Redis的线程问题 redis线程模型详解_数据库

在网上翻了一下关于"Redis线程模型"搜索结果,都是在说IO多路复用。但是完整的线程模型应该更整体的,而不仅仅是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要设计成单线程的呢?

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

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

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

  • 并行处理任务(parallelism)
  • 慢命令(一个命令慢,导致其他的命令也慢,可以理解为concurrent)

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