“Redis是单线程的。”
这句话你可能听过无数遍。面试官问你Redis为什么快,你脱口而出:"因为它是单线程的,避免了线程切换开销。"面试官满意地点点头,你也觉得自己答对了。
但这个答案,只对了一半。
从Redis 6.0开始,Redis就不再是纯粹的单线程了。它引入了多线程IO,用多个线程来处理网络读写。到了Redis 8.0,又进一步优化了多线程实现,换成了异步IO线程模型。
那为什么大家还在说Redis是单线程?因为命令执行仍然是单线程的。这是Redis的核心设计,从未改变。
所以准确的说法应该是:Redis的命令执行是单线程的,但IO处理可以是多线程的。这两句话听起来差不多,但背后的设计思想完全不同。
今天这篇文章,我们就来彻底搞清楚Redis的线程模型:单线程为什么快?瓶颈在哪里?多线程IO是怎么设计的?源码层面是怎么实现的?什么时候该开启多线程?
一、单线程Redis为什么快?
在聊多线程之前,先搞清楚一个问题:单线程的Redis,凭什么能达到每秒10万+的QPS?
很多人的第一反应是"因为单线程没有锁竞争"。这话没错,但只是表象。真正的原因有四个。
1.1 纯内存操作
Redis的数据全部存在内存里。内存读写的速度,比磁盘快了好几个数量级。
一次主内存访问大约需要50-100纳秒(如果命中CPU缓存会更快,L1缓存只需1纳秒左右)。而磁盘呢?机械硬盘寻址需要10毫秒左右,即使是SSD,随机读也要0.1毫秒(100微秒)。算下来,内存