第2章 基础类型的底层引擎


文档摘要

第2章 基础类型的底层引擎 章节摘要:本章跟着"一个键在内存里的真实长相"走。String、List、Set、Hash、Sorted Set 五种类型只是接口,底下是 SDS、quicklist、dict、跳表这几台发动机。读完本章,你能从结构复杂度直接推出命令的快慢与适用场景。 一条主线 一个面试常问的问题串起全章:"为什么 Redis 的 Sorted Set 做排行榜是毫秒级,而 MySQL 的 ORDER BY 做同样的事要几百毫秒?" 答案不在语法,在结构:Sorted Set 的底层是跳表,插入时就维护好了顺序;B+ 树按主键组织,排序要现场算。本章把这类"结构决定命运"的因果链逐个拆开。 沿途站点 2.

第2章 基础类型的底层引擎

章节摘要:本章跟着"一个键在内存里的真实长相"走。String、List、Set、Hash、Sorted Set 五种类型只是接口,底下是 SDS、quicklist、dict、跳表这几台发动机。读完本章,你能从结构复杂度直接推出命令的快慢与适用场景。

一条主线

一个面试常问的问题串起全章:"为什么 Redis 的 Sorted Set 做排行榜是毫秒级,而 MySQL 的 ORDER BY 做同样的事要几百毫秒?" 答案不在语法,在结构:Sorted Set 的底层是跳表,插入时就维护好了顺序;B+ 树按主键组织,排序要现场算。本章把这类"结构决定命运"的因果链逐个拆开。

沿途站点

  • 2.1 SDS:字符串为什么不直接用 C 的字符数组——多出来的那几个字节买来了 O(1) 长度和二进制安全。
  • 2.2 quicklist 与 listpack:List 的双端队列本质,以及小数据如何被压缩存储。
  • 2.3 dict 一鱼两吃:Set 与 Hash 共用同一张渐进式 rehash 的哈希表。
  • 2.4 跳表:Sorted Set 的排序引擎,层层跳跃的有序链表。

四种引擎与上层类型的对应关系:

拐点与结论

本章最重要的转折是 2.3 的"渐进式 rehash":Redis 的哈希表扩容不是一次搬完,而是把搬迁摊到每次操作里——用结构的聪明换主线程的不卡顿。理解这个设计哲学后,你会对"Redis 为什么不能存超大单键"有结构层面的解释。

本章知识点清单

以下知识点要求能脱稿回答,每一条都能用命令验证:

  • 写出 SDS 头部的关键字段,解释 alloc 与 len 的差值是什么
  • 说出 embstr 与 raw 的 44 字节分界从哪来(分配器的 64 字节块),并用 OBJECT ENCODING 复现
  • 解释 listpack 为什么从结构上根除了 ziplist 的级联更新
  • 默写渐进式 rehash 的触发条件(平时负载因子到 1、有后台保存任务时放宽到 5)与"双表并存、顺手搬迁"的执行方式
  • 手推跳表查找一个分数的完整路径,说明层数随机生成下复杂度为何是对数级
  • 面对一张字段表、一条时间线、一组带权成员,能立刻说出该用哪种类型与哪种编码

各类型在默认配置下的编码阈值,做本章实验前先混个眼熟:

类型 小数据编码 默认转换条件 大数据编码
String int(纯整数)或 embstr 超 44 字节,或被追加修改 raw
List listpack 单块体积或条数超限 quicklist
Hash listpack 元素超 128 或单值超 64 字节 dict
Set intset(纯整数)或 listpack 元素超 128 或单值超 64 字节 dict
Sorted Set listpack 元素超 128 或单值超 64 字节 跳表加 dict

阈值都能改,但改之前先问自己是不是在给错误的结构打补丁——超阈值的痛苦,多数时候说明该分键了,而不是调大阈值硬扛。

读完你应该

  1. 画出 SDS 的内存布局并解释三个字段各自的作用
  2. 说明 listpack 取代 ziplist 的原因(级联更新问题)
  3. 解释渐进式 rehash 的触发条件与执行方式
  4. 手推跳表查找一个元素的路径
  5. 面对"选哪种类型"的需求,能从结构复杂度表给出依据

下一章的接力

基础五类型讲完,主线推进到那些"为特定问题量身定做"的结构:位图、基数估算、地理编码与消息日志。它们是对本章引擎的极端化改造,理解了原版才看得懂改在哪。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U