我对Redis线程模型的理解

我对Redis线程模型的理解

在网上翻了一下关于"Redis线程模型"搜索结果,都是在说IO多路复用。但是我个人觉得线程模型的定义更多的集中在线程,而请求处理模式,所以决定记录一下个人的想法。

先谈一下Redis中的线程,Redis的线程可以分为三种:

  • socker连接线程-套接字
  • Redis主线程
  • 后台线程(处理BGSAVE命令等操作)

因为Redis是类似单线程,所以线程模型很简单。在简单的线程下,Redis线程是如何工作的呢?

根据上面线程的划分,主要分成下面两个部分:

Redis处理请求方式

  1. socket线程连接用来连接客户端,并写入新事件到文件描述符中
  2. 主线程通过多路复用(multiplexing)抽象API读取请求
  3. 通过reactor的handler模式实现响应请求

Redis后台线程工作方式

  1. 从主进程中fork出子线程,利用linux的copy-on-write技术节省内存
  2. 在子线程处理完成后,通知主线程。

上面说完了Redis的线程模型,接下来我们来看一下,为什么Redis要设计成单线程的,以及Redis 6.0之后的"多线程"?

为什么Redis要设计成单线程的呢?

  • 首先,简单是第一考虑因素,在Redis的整体架构都体现了简单的思想。
  • CPU不是瓶颈。在多数的测试下,瓶颈更多的集中在带宽和内存上,如果CPU成为了瓶颈,那么可以使用更多的Redis实例或者集群进行解决。
  • 单线程不意味着不可以并发(Concurrent helps)

但是随着Redis后面使用的量越来越大,导致使用单核CPU已经不能满足需求,也需要使用多线程。那么Redis是如何设计多线程呢?

在设计Redis6.0时,原作者antirez先是思考了多线程的场景,他将多线程分为:

  • 并发隔离处理任务(parallelism)

  • 慢命令(可以理解为concurrent)两种模式。

在Redis的场景中,他选择使用第二种来作为Redis多线程模式,也与Reactor的线程模式类似。将Redis瓶颈的IO使用多线程实现(主线程仍然是单线程,接受命令,转化IO请求等,从而避免锁),从而增加对CPU的使用能力,提高Redis的处理能力。