Redis:从“单线程神话“到“多线程真香“——一条走了十几年的演绎之路
引子:一个被误解了十年的"单线程"面试里有个经典问题:“Redis 是单线程的吗?”十年前,标准答案是"是的,而且正因为单线程才这么快"。今天再这么答,大概率会被追问一句:“那 6.0 的多线程 IO 你怎么看?4.0 的 lazy free 呢?后台的 BIO 线程呢?”这个转变不是 Redis 突然"变心"了,而是一条被业务规模、硬件演进和网络瓶颈一步步推着走出来的演绎之路。这篇文章想把这条路讲清楚:Redis 当初为什么选单线程,后来为什么在不同环节陆续引入多线程,以及这些设计对我们做架构和排障意味着什么。一、单线程神话的由来:为什么当初这么设计先纠正一个长期存在的误解。"Redis 是单线程"这句话从来都不完整。准确的说法是:Redis 处理命令的核心逻辑是单线程的。从最早的版本开始,Redis 就有其它线程在跑(比如后面会讲的持久化 fork、BIO 线程)。那么核心的命令处理为什么坚持单线程?原因很务实:1. 避免锁竞争Redis 的数据结构(dict、ziplist、skiplist 等)如果要支持多线程并发读写,就必须加锁。锁本身有开销,更麻烦的是锁竞争带来的上下文切换和缓存失效。对于一个内存操作动辄纳秒级、命令执行以微秒计的系统,加锁的代价可能比操作本身还大。2. 内存操作本身就快,瓶颈不在 CPU在 Redis 诞生的年代,单核处理一个GET/SET