Redis 底层数据结构学习笔记
(ziplist、quicklist、skiplist)
1. ziplist(压缩列表)
Redis 3.x~5.x 普遍使用的紧凑型线性存储结构,用于存储小数量对象。
用于:
- 小型 List(少量元素)
- 小型 Hash(field/value 都小)
- 小型 ZSet(score + member)
1.1 为什么使用 ziplist?
因为:
- dict、linkedlist 等结构的指针非常占内存
- 小数据使用 dict 不划算
ziplist 追求:
空间最节省(compact),连续内存,低开销
1.2 ziplist 的结构图(逻辑)
+----------+----------+----------+-----------+---------+
| zlbytes | zltail | zllen | entries | zlend |
+----------+----------+----------+-----------+---------+
| 字段 | 说明 |
|---|---|
| zlbytes | ziplist 占用总字节数 |
| zltail | 最后一个 entry 的偏移量 |
| zllen | entry 数量 |
| entries | 真正的数据 |
| zlend | 0xFF 标记结束 |
2.3 entry 的结构
每个 entry 分三部分:
prevlen | encoding | data
意义:
- prevlen:前一个节点长度(用于快速回退)
- encoding:整数 or 字符串
- data:实际内容
2.4 ziplist 的优缺点
优点:
- 内存占用非常小
- 结构紧凑
- 顺序访问速度快
缺点:
- 插入/删除需要移动内存(O(n))
- 容易产生连锁更新(prevlen 扩容会导致级联)
- 不适合大数据量
2. quicklist(快速列表)
Redis 3.2 后为优化 List 结构,引入了 quicklist。
quicklist = 双端链表 + ziplist
每个结点是一个 ziplist,而不是单个元素。
2.1 quicklist 的结构
quicklist
├── quicklistNode → ziplist
├── quicklistNode → ziplist
└── quicklistNode → ziplist
每个 quicklistNode 包含:
previous
next
ziplist 指针
ziplist 长度
ziplist 压缩深度
2.2 设计目的
解决:
- linkedlist 内存浪费
- ziplist 修改效率低 之间的矛盾
quicklist:
- 用链表解决扩容/插入效率问题
- 每个列表节点又用 ziplist 节省内存
2.3 quicklist 的优点
- 内存利用率高(ziplist)
- 插入删除快(linkedlist)
- 性能稳定,各场景兼顾
因此 List 的底层结构(原 linkedlist)被 quicklist 完全替代。
2.4 quicklist 的使用场景
List 类型的底层结构:
- RPUSH / LPUSH
- LPOP / RPOP
- LRANGE
适合大多数队列、栈、日志等业务。
3. skiplist(跳表)
skiplist 是 Redis Sorted Set(ZSet)的底层结构之一。
ZSet 底层 = dict + skiplist
- dict 负责根据 member 查 score
- skiplist 负责根据 score 排序和范围查询
3.1 为什么使用跳表而不是平衡树?
跳表特点:
- 实现简单
- 插入删除快速
- 区间查询高效
- 在 Redis 单线程中更友好(无需复杂旋转)
时间复杂度:
查找、插入、删除:O(logN)
区间查询:O(logN + m)
4.2 skiplist 结构
包含多个"层级":
L4: o-------------o
L3: o-----o---o---o---o
L2: o-o-o-o-o-o-o-o-o-o
L1: o-o-o-o-o-o-o-o-o-o
层级越高节点越少,作为"索引",类似高速公路。
3.3 skiplist 节点结构
score
member
level[] // 每层 forward 指针
backward // 后退指针
特点:
- 多层 forward 提高查找效率
- backward 用于反向查找
3.4 skiplist 使用场景(ZSet 核心)
- 排行榜
- TOP N
- 时间排序消息流
- 范围查询(ZRANGE/ZREVRANGE/BYRANK/BYSCORE)
Redis Sorted Set 的高性能就来自 skiplist。
总结表
| 数据结构 | 底层用途 | 复杂度 | 优点 | 缺点 |
|---|---|---|---|---|
| ziplist | 小型 List/Hash/ZSet | O(n) | 内存最省 | 插入删除慢 |
| quicklist | List | O(1)/O(n) | ziplist + 链表折中 | 复杂度高 |
| skiplist | ZSet 排序结构 | O(logN) | 区间查询效率高 | 内存比平衡树略大 |