Redis的单线程


Redis是单线程还是多线程?

Redis的网络IO和键值对读写是由一个线程来完成的,Redis在处理客户端的请求时,包括获取(socket读)、解析、执行、内容返回(socket写)等都由一个顺序串行的主线程处理,这就是所谓的“单线程”。这也是Redis对外提供键值存储服务的主要流程。

但Redis的其他功能,比如持久化RDB、AOF、异步删除、集群数据同步等等,其实是由额外的线程执行的。

Redis命令工作线程是单线程的,但是,对整个Redis来说,是多线程的。


单线程为什么这么快?

在Redis3.x单线程时代但性能依旧很快的主要原因:

  • 基于内存操作:所有数据存在内存中,因此所有的计算都是内存级别的,所以性能较高

  • 数据结构简单:Redis的数据结构是专门设计的,这些简单的数据结构的查找和操作的大部分复杂度都是O(1),因此性能比较高

  • 多路复用和非阻塞IO:Redis使用IO多路复用功能来监听多个socket连接客户端,这样可以使用一个线程来处理多个请求,减少线程切换带来的开销,同时避免了IO阻塞

  • 避免上下文切换:因为是单线程模型,因此避免了不必要的上下文切换和多线程竞争,这就省去了多线程切换带来的时间和性能开销

但是在Redis4.0中开始支持多线程了


为什么引入多线程?

既然单线程有这些优势,那么为什么引入多线程?

Redis性能影响的因素有CPU、内存、网络IO,对于Redis主要的性能瓶颈在内存或者网络带宽而非CPU,特别是网络IO。

Redis在处理网络数据时,调用epoll的过程是阻塞的,也就是说这个过程会阻塞线程,如果并发量很高,达到几万的QPS,此处可能会成为瓶颈。开启多线程除了可以减少由于网络I/O等待造成的影响,还可以充分利用CPU的多核优势。

从Redis6开始,将网络数据读写、请求协议解析通过多个IO线程来处理,解决网络IO问题。这点可以是“Redis单线程为什么那么快?”问题的补充。

IO多路复用