Redis学习(单线程vs多线程)(10.28)

Redis学习(单线程vs多线程)(10.28)

版本

  • 版本3.x,最早版本,单线程

  • 版本4.x,处理客户端请求单线程,异步删除多线程

  • 版本6.0.x,7.0,多线程

所谓“单线程”

网络io和键值对读写由一个线程完成

处理客户端请求(主线程:顺序串行):获取,解析,执行,内容返回

额外线程执行:持久化RDB,AOF,异步删除,集群数据共享

Redis命令工作线程单线程,整个Redis多线程

版本3.x单线程时代性能快

  • 基于内存操作:数据存在内存,所有运算内存级别

  • 数据结构简单:查找和操作时间大部分复杂度o(1)

  • 多路复用和非阻塞io:i/o多路复用功能来监听多个socket连接客户端,使用一个线程来处理多个请求,减少线程切换带来的开销,避免了i/o阻塞

  • 避免上下文切换:单线程模型,不会导致死锁

    扫描二维码关注公众号,回复: 17480894 查看本文章

版本4.0之前一直采用单线程

  1. 开发维护简单

  2. 单线程模型也可并发处理多客户端请求,采用io多路复用和非阻塞io

  3. 主要性能瓶颈为内存或网络带宽而非cpu

多线程特性出现

  • 大key问题

    • del bigkey一直阻塞,导致主线程卡顿

  • 引入惰性删除避免卡顿

    • 解决删除效率低

    • 删除操作从主线程剥离BIO子线程处理,提高性能稳定性

狭义单线程:引入多线程实现异步惰性删除,处理读写请求的任然只有一个线程

Redis6/7真正多线程

单线程处理网络请求的速度跟不上底层网络硬件的速度

采用多个io线程来处理网络请求,提高网络请求的并行度

Redis只是将i/o读写变成了多线程,而命令的执行依旧由主线程串行执行

主线程与io线程的四个阶段

  1. 服务端和客户端建立Socket连接,并分配处理线程

    1. 主线程负责接收建立连接请求

    2. 将Socket放入全局等待队列

    3. 主线程通过轮询分配给io线程

  2. io线程读取并解析请求

    1. 阻塞状态,等待io线程完成对客户端请求读取和解析(多io线程并行处理)

  3. 主线程执行请求操作

    1. io线程解析完毕,主程序执行

  4. io线程回写Socket和主线程清空全局队列

    1. 返回结果入缓冲区

    2. 等待io线程写回Socket(多io线程并行处理)

    3. 主线程清空全局队列

io读和写本身就是堵塞的,Socket中有数据时,Redis通过调用先将数据从内核态空间拷贝到用户态空间,再交给Redis调用,这个拷贝的过程就是堵塞的,数据量越大,拷贝需要的时间越多,这些操作基于单线程完成

版本6开始,新增多线程功能提高io的读写性能,将主进程的io读写任务(Socket读取,请求解析,写入)拆分给一组独立的线程去执行,使多个Socket的读写并行化,采用多路复用技术让单个线程高效处理多个连接请求(尽量减少网络io的时间消耗)。

Redis为什么这么快

直接原因:io多路复用+epoll函数使用

肤浅原因:单线程命令+redis安装在内存

在单机模式下,可以开启多线程,在其他模式下,最好不要开启

猜你喜欢

转载自blog.csdn.net/m0_62261710/article/details/143305203