[TOC] #### 1. 前言 --- 前面几讲你可能注意到一个词反复出现:单线程 很多人想不通:多线程不是更快吗 ?为什么 Redis 偏偏用单线程 ? 这个问题面试经常问,搞明白了比背八股有用得多 先说清楚一件事: ```plaintext Redis6.0之前,网络处理和命令执行都是单线程;6.0之后,网络IO用了多线程,但命令执行仍然是单线程 ``` 所以面试的时候你可以这么答:**命令执行是单线程,网络 IO 在 6.0 之后支持多线程**(一句话讲清楚,面试官会觉得你真懂) #### 2. 为什么命令执行坚持用单线程 --- 为什么命令执行坚持用单线程 ? 我打个比方你就明白了 你去一家小餐馆吃饭:如果厨房只有一个厨师,他炒完你的菜,马上炒下一个,流水线一样,很快 但如果厨房有 5 个厨师,他们得抢同一口锅、同一把铲子。谁先用 ?等一下,用完了喊下一个?又等一下 光 “排队等锅” 这件事就浪费了不少时间 Redis 的命令执行就是那个 “一个厨师一口锅” 的模式,来了就做,做完下一个,没有等待、没有切换、没有抢锁 而且 Redis 做的都是内存操作,一个命令只要纳秒级 ```plaintext 一个厨师每秒能炒 10 万道菜,瓶颈根本不在炒菜的速度,在顾客进门的速度 ``` #### 3. 网络 IO 为什么要改成多线程 --- 因为 “顾客进门” 确实太慢了 10 万个请求同时涌进来,一个线程收发网络数据忙不过来 6.0 的做法是:请几个助手帮忙 “接客”(收发网络数据),但 “炒菜”(执行命令)还是厨师一个人 这样网络不再是瓶颈,命令执行又保持了单线程的优势 配置: ```plaintext io-threads-do-reads yes io-threads 4 ``` 一般设 4~8 个线程就够了,不用太多 #### 4. 单线程有什么要注意的 --- 单线程有什么要注意的 ?答:大 key 会阻塞。 想象一下,一个顾客点了 1000 道菜,厨师炒了 10 分钟还没完,后面所有顾客都得等 Redis 也一样: + `keys *` 数据量大的时候遍历所有 key,卡住所有人 + `hgetall` 一个有 10 万字段的 Hash,传输半天 + `smembers` 一个有 100 万元素的 Set,遍历很久 这些 “慢命令” 会阻塞整个 Redis,生产环境要避免,后面会讲怎么用 scan、hscan、sscan 替代 #### 5. 本文小结 --- 小总结: + 命令执行单线程,网络 IO 多线程(6.0+) + 单线程的好处:没有切换开销、没有锁竞争、逻辑简单 + 瓶颈在网络 IO,不在 CPU + 注意大 key 和慢命令会阻塞整个 Redis 到这里,第一阶段 “Redis入门” 全部完成了 你已经知道了 Redis 是什么、为什么快、怎么装、有什么数据结构、常用命令、以及为什么用单线程 下一讲进入第二阶段,深入每一种数据结构,先从最常用的 String 开始