Redis 线程模型

2021/5/8 19:25:18

本文主要是介绍Redis 线程模型,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

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 只是核心处理功能采用单线程,一些 网络、IO 模块仍是多线程,总得来说线程数少,降低了上下文切换的消耗,并不能完全避免
Redis 6.0 版本开始支持多线程,多线程只是用来处理网络数据的读写和数据解析,执行命令仍使用单线程。

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

总得来说 CPU 效率的瓶颈不在 CPU,使用单线程也简单,避免了很多并发处理问题。



这篇关于Redis 线程模型的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程