大家好,我是 31 岁的小米,一个写代码十几年、踩坑踩成见坑就想讲故事的技术 UP 主。今天这篇文章的灵感来自上周一个社招 Java 面试候选人。他坐在我对面,手心微微冒汗,却盯着我一脸笃定地回答:“Redis 是单线程的,所以用不上多核 CPU,这就是 Redis 慢的原因。”
我愣了三秒。Redis 慢?Redis 觉得自己受到侮辱。
我当场把水杯放下,对他说:“兄弟,你这是侮辱 Redis 祖坟级别的优化哲学啊。”
于是,我决定把那天和候选人的对话写成故事,也顺便给所有准备面试的同学讲明白:
Redis 为什么是单线程?单线程怎么做到这么快?明明单线程,为什么也能吃满多核 CPU?我们 Java 程序员又该怎么在大厂面试里把这个题答到面试官心窝子里?
来,故事开始。
那天的面试:候选人说 Redis 利用不了多核,我的嘴角狂抖那天候选人说完那句话后,我问他:“那你知道 Redis 为啥单线程还这么快吗?”
候选人挠挠头,说:“因为它用的是 C 语言?”
我当场心里默默扣分 10 分。于是我把纸笔推给他,让他画画 Redis 的执行模型。
他画了几根横线,说:“单线程啊,能画什么?”
我又默默扣了 10 分。如果你也觉得“Redis 单线程 = 性能差 = 用不上多核”,那我必须给你补这一课。
Redis 为什么单线程还能这么快?因为它把单线程优化到了极致我跟候选人说:“Redis 单线程不代表 Redis 整个进程只有一个线程。”
候选人:???
我继续解释:“Redis 单线程只是指 网络 IO 和命令执行是单线程的。但 Redis 本身不是只有一个线程,比如持久化线程、集群通信线程、lazy-free 异步删除线程等等。”
但这不是重点。重点是:
Redis 单线程仍然可以打爆多线程数据库,是因为:
纯内存操作,速度极快
IO 多路复用,单线程也能处理海量并发
避免锁竞争,没有上下文切换的开销
命令执行路径短、纯 C 的极致优化
换句话说:
Redis 单线程并不是因为简单,而是因为极致。Redis 不是不想多线程,是觉得多线程会拖慢它。
我问候选人:“你知道上下文切换是什么吗?”
他:知道,会切来切去浪费 CPU。
我点点头:“对,所以 Redis 创始人 antirez 选择单线程,其实是选择性能。”
说到这里,候选人终于有点恍然大悟。
但重点来了:那 Redis 单线程,怎么吃掉多核 CPU?候选人接着问我:“那 Redis 既然是单线程,那我服务器 16 核岂不是浪费了?”
我笑了。
事实是:大多数互联网公司的 Redis 集群,可以干到全服 CPU 打满(当然是假设你 QPS 很高的情况下)。
怎么做到的?
方法一:一台机器部署多个 Redis 实例,每个实例绑定不同 CPU 核心我告诉候选人:“大厂都会这样搞。”
举个例子:
服务器:16 核 64G
部署:8 个 Redis 实例
每个实例绑定一个独立 CPU 核心
实例之间用不同端口运行,如:6379、6380、6381……6386
结果是:
单线程实例 × 多核 CPU = 多实例并行
这就像 8 个高速收费站,不会出现所有车都挤一条道。候选人听到这里已经开始疯狂点头。我继续补刀:
为什么企业喜欢这种方式?
提升多核利用率
一个实例爆掉不影响另外的实例,隔离性强
可以根据业务拆分成多个 Redis 实例(订单 Redis、用户缓存 Redis、商品缓存 Redis…)
便于扩容,可灵活迁移
说白了,就是:
Redis 单线程不等于 Redis 只能用一个核,而是你应该多开几个 Redis。
Redis 官方也认可这种方式。
方法二:使用 Redis Cluster,让不同分片分散在多个 Redis 实例上我跟候选人说:“如果你只开一个 Redis,那么你确实不能用满多核。但是你建一个 Redis Cluster 呢?”
Redis Cluster 有 16384 个 slot,每个 slot 可以分配给不同的 Redis 节点。比如你有:
redis-7001:master(slot:0~5460)
redis-7002:master(slot:5461~10922)
redis-7003:master(slot:10923~16383)
每个 Redis 节点自己单线程,但是三个节点跑在:
CPU 核 1
CPU 核 2
CPU 核 3
这是不是又利用上多核了?甚至你可以继续扩容:
一台机器跑多个 Redis 节点
多台机器分布更合理地使用 CPU
这样整个集群的 CPU 就能全部吃满。
方法三:Redis 7.0 多线程 IO 支持我问候选人:“你知道 Redis 7.0 开始支持多线程了吗?”
他:啊?不是一直单线程吗?
这是大部分 Java 面试者常犯的错误。Redis 6.0 起加入多线程,但不是执行命令用多线程,而是:多线程处理网络 IO:read/write/writev/sendfile
也就是说:
多线程处理网络读写
单线程执行命令
结果是:
IO 吞吐提升明显
网络瓶颈被解决
Redis 单核性能更上一层楼
这就叫:
“命令执行单线程,网络 IO 多线程”
很多人误解以为 Redis 完整变成多线程了,其实不是。但这个优化让 Redis 可以利用更多 CPU 核心。
方法四:使用 Pipeline + 批量命令降本增效然后我问候选人:“你知道为什么你 Redis CPU 只占 5% 吗?”
他:因为 Redis 太快?
我说:“不是,是因为你的应用太慢。”大部分 Java 系统访问 Redis 时:
一个请求只查一次 Redis
每次查 Redis 都走一次网络消耗
QPS 低到 Redis 根本不屑用 CPU
如果你用 Pipeline:
一次发 20 条命令
一次返回结果
你的 Redis 负载立刻提高,CPU 使用率上升。Redis 都等着你 Java 应用多来点请求。
方法五:用 Lua 脚本降低命令往返次数我继续补充:
如果你把 10 个操作组合成 1 个 Lua 脚本执行:
Redis 只处理一次命令
IO 往返都减少
CPU 也能利用得更高
例如做抢购、库存扣减时,Lua 让 Redis 执行路径更短、效率更高。
那天的面试后,候选人突然懂了:Redis 单线程不等于只能用一个核!我最后问他一个终极问题:
如果你是 Redis 作者,你会把执行命令做好多线程吗?
候选人陷入沉思。几秒后,他说了一句让我很欣慰的话:
“如果 Redis 执行命令多线程,锁竞争、上下文切换、数据一致性都会变复杂,也会变慢……”
我点头。Redis 作者早就说过:
“多线程不是 Redis 的问题解决方案,Redis 的核心是降低延迟。”
如果你真的想利用多核:
开多个 Redis 实例
用 Redis 集群
利用 Redis 6+ 多线程 IO
增加业务 QPS,让 Redis 忙起来
用 Pipeline、Lua 降低网络开销
只要你愿意,Redis 可以把你的 CPU 烧到冒烟。
我给所有准备社招 Java 面试的小伙伴的一些建议如果你在面试里遇到这个题,千万不要说 Redis 因为单线程所以慢。面试官喜欢听的答案是这样的:
标准满分回答(建议背熟):
Redis 虽然执行命令是单线程的,但并不是不能利用多核 CPU。
企业通常通过以下方式提升多核利用率:
一机多实例:在一台服务器上部署多个 Redis 实例,并绑定到不同 CPU 核心。
Redis Cluster 分片:不同分片运行在不同实例,从而横向扩展 CPU。
Redis 6/7 的多线程 IO 优化:虽然命令执行仍为单线程,但 IO 读写已多线程,可以提升 CPU 利用率。
通过 Pipeline、Lua 脚本减少网络往返,提高吞吐,从而让 Redis 更充分利用 CPU。
因此,Redis 单线程不等于性能差,它通过架构层面的方式实现了对多核 CPU 的高效利用。

我们经常误解“单线程”这个词。单线程不是落后,而是 Redis 对性能的一种极致选择。
Redis 用单线程避免了:
复杂锁
抢占
上下文切换
多线程共享内存问题
它专注做一件事:在内存里以最快速度处理网络请求。
至于多核利用?那是架构层面(多实例、多分片)的事情,不是 Redis 内核的活。
END希望读完这篇文章,你能在下一次面试里自信地讲:
“Redis 单线程,是为了更快;利用多核,是为了更强。”
如果你喜欢我这种讲故事式的技术文章,点个赞,下次继续给你讲更多面试底层知识,让你面试拿 offer 拿到手软。