Redis 线程模型

  • Post author:
  • Post category:其他


Redis 内部使用文件事件处理器实现,这个文件事件处理器负责所有客户端请求的处理,由于文件处理器处理任务是单线程的,因此也说 redis 是单线程的。

其中文件事件处理器通过以下几个模块组成:

  • Socket:每个客户端对应一个 Socket 连接
  • IO 多路复用程序:监听多个 Socket,将产生事件的 Socket 放入队列
  • 文件事件分派器:每次取出一个 Socket,根据 Socket 的事件类型分派给不同处理器
  • 事件处理器:包括连接应答处理器,命令请求处理器,命令回复处理器

IO多路复用技术:多路指多个Socket连接,复用是指多个Socket连接复用一个或多个线程

Redis 一次请求全过程:

  1. Redis 服务端启动,将 Server Socket 的 AE_READABLE 事件与连接应答处理器关联
  2. 客户端 Socket1 向 Redis 服务端 Server Socket 请求建立,Server Socket 产生 AE_READABLE 事件,I/O 多路复用程序监听到事件后,将该 Socket 压入队列中
  3. 事件分派器从队列获取到 Socket,根据 Socket 事件类型将它交给连接应答处理器,连接应答处理器创建与该客户端通信的 socket01,并将该 Socket 的 AE_READABLE 事件与命令请求处理器关联
  4. 客户端发送 set key value 命令,此时 redis 中的 socket01 产生 AE_READABLE 事件,IO 多路复用技术将 socket01 压入队列
  5. 事件分派器从队列获取到 socket01 产生的 AE_READABLE 事件,并将该事件分派给命令请求处理器来处理。Redis 在内存中处理完毕后,会将 socket01 的 AE_WRITABLE 事件与命令回复处理器关联
  6. 如果此时客户端准备好接收结果了,Redis 中的 socket01 产生 AE_WRITABLE 事件,同样压入队列,事件分派器从队列中取出事件,分派给命令回复处理器,命令回复处理器对 socket01 输出本次操作的结果,之后解除 socket01 AE_WRITABLE 事件和命令回复处理器的关联

Redis 单线程是指从队列中拉取事件并分派处理是单线程的



Redis 为什么使用单线程

由于 Redis 基于内存实现,本身速度极快,CPU 不会成为性能的瓶颈,瓶颈只可能是内存大小或网络带宽,而且单线程实现简单,因此采用单线程实现。

虽然 Redis 采用单线程实现,但它的效率实际并不低:

  • 纯内存操作
  • 基于非阻塞的 IO 多路复用技术
  • C 语言实现,C语言相比其它语言执行本身较快
  • 单线程天然线程安全,不需要使用锁等同步机制
  • 单线程降低了进程内部上下文切换的消耗
  • Redis 全程使用 Hash 结构,再加上各种数据类型的支持,本身查询效率就很高

由于使用单线程,Redis 不能发挥多核 CPU 的性能,对此我们可以多启动几个实例,采用单线程多进程集群的方案充分利用 CPU 资源



Redis 版本更替

  • Redis 4.0 之前,完全单线程
  • Redis 4.0 引入多线程,但额外的线程只参与后台处理,不参与核心功能。例如:并发删除对象
  • Redis 6.0 再次引入多线程,额外的线程参与网络 I/O 阶段,也就是接受命令以及写回结果阶段,处理命令处理仍是单线程串行执行。

Reis 多线程不会同时参与读和写,多个线程只会同时读或者同时写。



版权声明:本文为m0_57015193原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。