06.Redis线程模型 ✅常识原理
Redis 使用单线程 Reactor 模型处理命令,主要通过主线程完成客户端请求的接收、解析、数据操作和响应发送。
6.0 版本之前,Redis 仅使用单线程处理所有任务,而 6.0 后引入了多线程来处理 I/O 操作,提升了网络性能。
多线程仅用于网络 I/O,如数据的读取和写入,核心的命令执行仍由单线程完成,确保数据操作的安全性与一致性。
这种改进提高了 Redis 的吞吐能力,特别适合高并发场景。
# 01.Redis 线程模型
# 1、线程模型概述
Redis 底层是 Reactor模型,Reactor模型有三种
- 单线程Reactor模型
- 多线程Reactor模型
- 主从Reactor模型
Redis 单线程理解
Redis单线程主要指Redis-server主线程,不是说Redis生命周期只有一个线程
Redis单线程,指的是命令处理、逻辑处理在一个单线程中
接收客户端请求-->解析请求-->进行数据读写等操作-->发送数据给客户端是主线程完成而是其主线程(即下图的
任务队列以及事件分派器)为单线程

# 2、6.0前单线模式
1)建立连接(连接事件)1、建立连接- 客户端尝发送TCP连接请求,连接请求被
操作系统内核接收并放入等待队列 IO多路复用器监控等待队列,发现新连接请求,将其放入事件队列,等待被处理
- 客户端尝发送TCP连接请求,连接请求被
2、文件分派器文件分派器将会从事件队列中取出这个新的连接请求,将其分配给连接应答器(acceptor)处理
3、连接应答器连接应答器的任务是接受新的连接请求,建立新的socket连接- 连接应答器将新的socket放入IO多路复用器监控的文件描述符集合,并向IO多路复用器发送一个读就绪信号
2)处理客户端请求(读事件)- 客户端发送请求到Redis服务器时,请求被
IO多路复用器标记为读事件 - IO多路复用器接收到读事件后,会将其
放入事件队列中 Redis主线程会从事件队列中取出读事件,然后调用相应的事件处理器来处理- 读事件处理器将请求数据
解析成Redis命令和参数,根据命令类型调用相应的命令处理函数来处理 - 命令处理完毕后,
Redis会生成一条回复消息,并将其标记为一个写事件,等待被发送回客户端
- 客户端发送请求到Redis服务器时,请求被
3)数据发送给客户端(写事件)- 当有数据需要
发送回客户端时,这个发送操作会被标记为一个写事件 - IO多路复用器会将写事件放入事件队列中
主线程会从事件队列中取出写事件,调用相应的事件处理器来处理这个事件- 对于写事件,Redis会调用写事件处理器,
将回复消息写入到socket,然后发送给客户端
- 当有数据需要
注1:- 读事件和写事件都是异步处理的,不会因为一个读事件或写事件阻塞住
- 而是会将事件放入事件队列,然后继续处理其他的事件
注2:下图“写发送队列”指的是返回数据给客户端,这个过程需要写入到 socket

# 3、6.0为什么引入IO多线程
# 1、引入原因
在
Redis 6.0 版本之后,也采用了多个 I/O 线程来处理网络请求因为随着网络硬件的性能提升,Redis的性能瓶颈有时会出现在网络 I/O 的处理上
所以为了提高网络 I/O 的并行度,Redis 6.0
对于网络 I/O采用多线程来处理但是
对于命令的执行,Redis 仍然使用单线程来处理即
多线程处理网络IO(``read、decode和encode、send`阶段)主线程使用单线程,执行命令处理业务逻辑

# 2、引入后工作流程
主线程:执行命令,将结果写入队列
工作线程:读取请求数据、从队列中读取数据到 socket、关闭 socket 等
原因:Redis 的数据结构和操作都不是线程安全的,如果同时有多个线程对数据进行读写,可能会导致数据的不一致
- 6.0 后依然需要
一个主线程,可以有多个工作线程处理用户 I/O - 1)工作线程接收到客户端请求,从 socket 中读取请求数据
- 2)主线程解析出请求命令和参数,执行请求命令,获取或修改数据,然后生成响应数据
- 3)主线程将响应数据写入一个中间队列,然后唤醒工作线程
- 4)工作线程从中间队列中取出响应数据,然后将数据写入 socket,发送给客户端