如果你做过后端,十有八九用过 Redis。但真要回答一句"它为什么这么快",大多数人只能挤出两个字:内存。这其实是个偷懒的答案——内存只是入场券,真正让 Redis 能跑出每秒数十万乃至上百万次操作、并且延迟稳定在亚毫秒级的,是一整套被精心雕琢的工程取舍。这期《Why Is Redis Extremely Fast? | Redis Internals Explained》之所以值得反复看,就在于它把"快"这件事拆成了三个层次:架构层的单线程事件循环、数据结构层的六大底层编码、协议层的 RESP 与 pipelining。看完你会明白一个反直觉的结论:Redis 之所以快,恰恰是因为它"不做"了很多别人都在做的事——不加锁、不切线程、不维护复杂的并发结构。 这套思路,比 Redis 本身更值得你带走。
| 项目 | 内容 |
|---|---|
| 视频标题 | Why Is Redis Extremely Fast? | Redis Internals Explained |
| 频道 | DevMonk(后端 / 系统设计深度讲解类频道) |
| 时长 | 深度长视频(具体以 YouTube 页面为准) |
| 热度 | Redis 内部机制是 YouTube 后端方向持续热门的硬核选题之一 |
| 核心主题 | 单线程事件循环 × 六大底层数据结构 × RESP 协议 = 极致速度 |
说明:受检索工具限流影响,频道订阅数、播放量等指标请以 YouTube 页面实时数据为准;本文的技术解读以该视频主题为纲,并交叉比对了多篇公开的 Redis 工程资料,确保事实准确。
视频一上来就纠正了最常见的误解:内存不是 Redis 快的全部。内存只是把"磁盘毫秒级"压到了"内存纳秒级",这是所有 in-memory 数据库都能做到的。Redis 真正的护城河,在于它在内存这个量级上做出的取舍——当单次操作已经是纳秒级,传统多线程带来的锁竞争(lock contention)、上下文切换(context switch)、CPU 缓存失效(cache invalidation)这些开销,往往比并行省下的那点收益还大。
我的延伸:这其实是分布式/系统设计里一个被反复验证的规律——瓶颈在哪,就在哪花力气,别在不是瓶颈的地方徒增复杂度。对内存数据库而言,瓶颈是内存带宽和网络 I/O,而不是 CPU 算力。所以 Redis 选择了"在瓶颈处并行、在数据处串行"这条路线,这才是它"单线程却最快"的根本逻辑。
Redis 的心脏是一个事件循环(event loop)。它借助操作系统的 I/O 多路复用机制——Linux 上是 epoll、macOS/BSD 上是 kqueue、Solaris 上是 evport、退化时用 select——让一个线程同时监听几万个 socket。哪个连接的数据就绪,就处理哪个,把"接受连接 → 读命令 → 执行 → 写回复"串成一条流水线。
关键在于:命令执行是单线程的,因此整个数据处理路径上不需要任何锁。没有锁,就没有锁竞争、没有死锁、没有内存屏障带来的性能损耗,代码也简单到可以推理。
我的延伸:Redis 6 之后引入了 threaded I/O——把"读 socket、写 socket"这种慢 I/O 扔给几个 worker 线程并行处理,但命令执行依旧单线程。这是非常精准的一刀:网络 I/O 是瓶颈,就并行它;数据是共享状态,就串行它。既榨干了多核,又保住了"免锁"的核心优势。
普通用户眼里,Redis 只有 String、List、Hash、Set、Sorted Set 五种类型。但视频强调,这只是糖衣。糖衣之下,是 SDS、dict(hash table)、ziplist/listpack、quicklist、skiplist、intset 六种用 C 手写的底层结构。Redis 会根据数据的类型和大小动态切换编码(encoding):集合还小的时候,用紧凑的连续内存结构省内存;元素一多,自动切换成 O(1) 或 O(log n) 的高效结构保性能。
这种"自适应编码"是 Redis 的核心哲学,也是它和"带过期时间的 MySQL"最大的区别。别人提供的是数据类型,Redis 提供的是针对每种使用场景量体裁衣的数据结构。
C 语言自带的字符串以 \0 结尾,有三个致命缺陷:求长度要 O(n)、不能存二进制(中间遇到 \0 就截断)、修改要频繁 realloc。视频专门讲了 Redis 自己造的 SDS(Simple Dynamic String):
strlen 从 O(n) 降到 O(1);我的延伸:这是"把通用工具换成场景定制"的教科书案例。C 标准库追求通用性,Redis 追求的是"在我的场景下最快最省"。这种为热点路径定制数据结构的思路,可以直接迁移到你自己的系统设计里。
Sorted Set(ZSet,有序集合)是 Redis 最经典的结构,排行榜、延迟队列、带权重的去重都靠它。视频详细讲了它的双结构设计:dict(哈希表)负责 O(1) 查成员的分值,skiplist(跳表)负责 O(log n) 的范围查询,两者共用同一份元素数据,空间换时间。
为什么不用平衡树(红黑树 / AVL)或 B+ 树?跳表有几个压倒性优势:
我的延伸:这是一个典型的"工程优于理论最优"的选择。教科书告诉你红黑树保证最坏情况 O(log n),但跳表在期望意义上同样是 O(log n),而且简单得多。Redis 选跳表,说明在真实系统里"可维护性 + 实现成本"常常比纸面复杂度更重要。
视频后半段讲了 Redis 内存优化的演进,特别值得记的是 ziplist → listpack 的迁移。ziplist 是一段连续内存,省到极致,但它每个 entry 都记录了前一个 entry 的长度(prevlen)。问题在于:如果某个 entry 从小于 254 字节膨胀到大于等于 254 字节,prevlen 要从 1 字节变成 5 字节,这会导致后面所有 entry 的 prevlen 全部级联更新(cascade update),最坏复杂度退化到 O(n²)。
Redis 7.0 用 listpack 替换了 ziplist:每个 entry 只存自己的长度,彻底去掉了 prevlen,根治了这个级联隐患。
我的延伸:这是"为内存极致优化而踩坑、再反思"的完美范本。它告诉你:一个看似聪明的紧凑编码,如果引入了隐含的全局依赖(一个 entry 影响所有后续 entry),迟早会在大数据量下反咬你一口。 设计数据结构时,"局部性"是比"极致压缩"更该优先保证的性质。
很多人盯着数据结构看,却忽略了 Redis 快的另一个功臣:协议。Redis 用的是自己设计的 RESP(REdis Serialization Protocol),文本协议,简单到肉眼可读、解析极快,还支持 inline 命令。在此基础上,pipelining(流水线) 让客户端把一堆命令一次性打包发出去、不必等每条回复,把 N 次网络往返(RTT)压缩成 1 次。
我的延伸:在跨机房、跨地域的场景里,RTT 往往才是长尾延迟的元凶,而不是 Redis 本身的处理速度。视频点出这一点非常有价值——很多团队抱怨"Redis 慢了",去调数据结构、加机器,最后发现是客户端没用 pipeline、每次一个来回。先优化协议层,往往收益最大。
graph TD
A["Redis 为什么极致快"] --> B["架构层:单线程事件循环"]
A --> C["数据结构层:六大底层编码"]
A --> D["协议层:RESP + Pipelining"]
A --> E["持久化层:后台异步不阻塞"]
B --> B1["epoll/kqueue I/O 多路复用"]
B --> B2["命令执行单线程 → 免锁"]
B --> B3["Redis6 threaded I/O:分离慢I/O"]
C --> C1["SDS:O(1)长度 + 预分配 + 多头部"]
C --> C2["dict:渐进式 rehash"]
C --> C3["ziplist → listpack:消灭级联更新"]
C --> C4["quicklist:链表 + 紧凑块"]
C --> C5["skiplist:ZSet 范围查询"]
C --> C6["intset:紧凑整数集合"]
D --> D1["RESP2/3 文本协议:解析快"]
D --> D2["pipelining:N 个 RTT → 1 个"]
E --> E1["RDB 快照:fork 后台进程"]
E --> E2["AOF 追加日志:异步刷盘"]
B2 --> F(("免锁 + 内存 + 紧凑 = 极致速度"))
C3 --> F
D2 --> F
选型层面:当你需要亚毫秒级读写、排行榜(ZSet)、计数器/限流(INCR + 过期)、会话缓存、最新列表时,Redis 几乎是默认答案。但要清醒:它是内存数据库,成本和数据量线性挂钩,绝不适合当主库存全量冷数据。正确的姿势是"Redis 当热数据/计算层,关系库/对象存储当持久层"。
建模层面:善用 Redis 的"数据结构即能力"——别只会 SET/GET。排行榜用 ZSet、独立访客用 HyperLogLog、签到/活跃用 Bitmap、消息流用 Stream、广播用 pub/sub。把 Redis 当"带过期时间的 MySQL",是对它最大的浪费。
避坑层面(这些是面试和线上事故的高频点):
KEYS *、大集合的 SMEMBERS/HGETALL 会卡住整个实例,线上禁用,用 SCAN 替代;方法论迁移:Redis 的三条工程哲学适用于任何系统设计——① 在瓶颈处并行,在共享数据处串行;② 自适应编码,为场景量体裁衣;③ 把通用工具换成场景定制的专用结构。 这才是这期视频能给你带到下个项目里的真正资产。
src/networking.c(事件循环)、src/t_zset.c(ZSet/跳表)、src/listpack.c、src/sds.c,这是最好的老师。Redis 快的密码不是内存,而是"单线程免锁 + 六大自适应数据结构 + RESP/pipelining 协议"三位一体的极致工程取舍——它教会我们的,是"少做"比"多做"更高级的系统设计智慧。
本文由「51学通信」技术团队出品。51学通信由通信行业18年老兵爱卫生(微信ID: gprshome201101)维护,聚焦5G/6G核心网、3GPP标准解读、通信前沿技术深度分析。 出版作品有《5G核心网原理与实践》《IMS原理与实践》等4本通信专业书籍。知识星球「51学通信」提供深度技术答疑和行业洞察。
产出:3000+ 字完整解读,含 7 大要点拆解、1 张 Mermaid 知识结构图、实战避坑指南、5 条延伸学习路径、5 条参考来源、品牌信息,全程未碰敏感话题
[!tip] 51学通信知识星球 星主:爱卫生(微信:gprshome201101)——公众号「51学通信」创办者,19 年通信行业运维与讲师经验,著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书(各大电商平台有售)。 星球定位:深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域,主打运维岗位与信令分析。 当前规模:5200 篇主题 / 990 个回答,198 元/年。 加入福利:加入星球后请加爱卫生微信,拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题,另有群内分享。 AI 加持:51学通信知识星球已作为 skill 接入 WorkBuddy,使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例,做总结、找文档和 PPT 等场景全覆盖。
