看完这篇博客之后,别再说你不会 Redis 的线程模型

前言

我们常说 Redis 是单线程的,那为什么 Redis 是单线程的呢?
在这里插入图片描述

Redis 的线程模型

Redis 有一个网络事件处理器,这个处理器基于 Reactor 模式开发,又称文件事件处理器,它包含以下四个部分:

  1. 套接字:与客户端建立连接,接收客户端的指令,并给客户端返回数据
  2. IO 多路复用程序:监听多个套接字的消息,根据套接字目前执行的任务来为套接字关联不同的事件处理器,会将产生事件的套接字都推到同一个队列上
  3. 文件事件分派器:从队列中获取套接字,并将套接字分配给不同的事件处理器
  4. 事件处理器:根据套接字目前执行的任务,对事件进行处理

之所以 Redis 是单线程的,是因为 Redis 是基于文件事件分派器工作的,且文件事件分派器队列的消费是单线程的。

消息处理流程

文件事件处理器会使用 I/O 多路复用来同时监听多个套接字,并根据套接字目前执行的任务来为套接字关联不同的事件处理器。当被监听的套接字准备执行连接应答,读取,写入,关闭等操作时,与操作相对应的文件事件就会产生,这时文件事件处理器就会调用套接字之前关联好的事件处理器来处理这些事件。

文件事件是可能并发的,但 I/O 多路复用程序会将所有产生事件的套接字推送到一个队列上,根据队列可以实现以有序,同步,每次一个套接字的方式向文件事件分派器传送套接字。只有当上一个套接字产生的事件被处理完毕之后(该套接字为事件所关联的事件处理器执行完毕),I/O 多路复用程序才会继续向文件事件分派器传送下一个套接字。

IO 多路复用程序

Redis 所谓的 I/O 多路复用程序实际上是包装了 select,epoll,evport,kqueue 这些 I/O 多路复用函数库来实现的,在底层,Redis 为每个 I/O 多路复用函数库都实现了相同的 API,故实际上 I/O 多路复用程序的底层实现是可以进行互换的。在编译时,程序会选择系统中性能最好的 I/O 多路复用函数库来作为 Redis 的 I/O 多路复用程序的底层实现。

事件处理器

Redis 提供的事件处理器有很多种,各种不同的事件处理器用于实现不同的网络通讯需求。几种常见的事件处理器如下:

  1. 连接应答处理器:对连接服务器的各个客户端进行应答。当 Redis 服务器初始化时,程序会把这个连接应答处理器与服务器监听套接字的 AE_READABLE 事件进行关联。当客户端连接服务器监听套接字时,套接字会产生 AE_READABLE 事件,使连接应答处理器执行
  2. 命令请求处理器:接收客户端传来的命令请求,该处理器可以从套接字读入客户端发送的命令请求内容。每当客户端通过连接应答处理器连接上服务器之后,服务器会将客户端套接字的 AE_READABLE 事件与命令请求处理器相关联。当客户端向服务器发送命令请求的时候,套接字会产生 AE_READABLE 事件,使命令请求处理器执行
  3. 命令回复处理器:向客户端返回命令的执行结果,将服务器执行命令后得到的命令回复通过套接字返回给客户端。在服务器需要给客户端传送命令回复时,服务器会将客户端套接字的 AE_WRITABLE 事件与命令回复处理器相关联。当客户端准备接收服务器传回的命令回复时,就会产生 AE_WRITABLE 事件,使命令回复处理器执行

一次客户端与服务器相连接的流程

  1. 如果 Redis 服务器正在工作,那么服务器的监听套接字的 AE_READABLE 事件应该处于监听状态下,该事件处理器为连接应答处理器
  2. Redis 客户端向 Redis 服务器发起连接,监听套接字产生 AE_READABLE 事件,触发连接应答处理器执行
  3. 处理器对客户端的连接请求进行应答, 然后创建客户端套接字
  4. 处理器将客户端套接字的 AE_READABLE 事件与命令请求处理器进行关联,使客户端可以向主服务器发送命令请求
  5. 当客户端向 Redis 服务器发送一个命令请求时,客户端套接字会产生 AE_READABLE事件,触发命令请求处理器执行,处理器会去读取客户端的命令内容, 然后传给相关程序执行
  6. Redis服务器执行命令,产生相应的命令回复
  7. 服务器将客户端套接字的 AE_WRITABLE 事件与命令回复处理器相关联,用以将命令回复传送回客户端
  8. 当客户端尝试读取命令回复时,客户端套接字产生 AE_WRITABLE 事件, 触发命令回复处理器执行
  9. 命令回复处理器将命令回复全部写入到套接字后, 服务器会解除客户端套接字的 AE_WRITABLE 事件与命令回复处理器之间的关联

参考: 彻底搞懂Redis的线程模型

发布了146 篇原创文章 · 获赞 300 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/Geffin/article/details/105348967