ZipList 是 Redis 早期底层的连续内存双端链表,节省内存,用于 List、Hash、Zset 底层(新版 Redis 很多场景替换为 QuickList)
一、ZipList 整体结构
zlbytes | zltail | zllen | entry... | zlend
表格
| 字段 | 占用字节 | 作用 |
|---|---|---|
| zlbytes | 4B | 整个压缩列表总内存字节数 |
| zltail | 4B | 表尾节点相对起始地址偏移,快速拿到尾节点 |
| zllen | 2B | 节点数量;最大值 65534,超过后此字段固定写 65535,必须遍历才能统计真实个数 |
| entry | 不定长 | 列表存储的数据节点 |
| zlend | 1B | 固定0xFF,标记压缩列表结束 |
- 特性:连续内存,两端增删 O (1),不需要存储前后指针,通过记录前节点长度实现反向遍历,节约内存。
二、ZipListEntry 节点结构
previous_entry_length | encoding | content
- previous_entry_length:前一个节点的长度
- 前节点长度 <254B:占用1 字节,直接存长度
- 前节点长度 ≥254B:占用5 字节 ,首字节固定
0xFE,后面 4 字节存真实长度 - 作用:从后往前遍历的时候,用当前 entry 地址减去该值,直接拿到上一个节点起始地址。
- encoding:编码,标记 content 是字符串 / 整数、以及长度,占用 1/2/5 字节
- content:数据本体,存字符串或者整数
三、Encoding 编码规则
✅ 字符串类型(开头 bit:00 / 01 /10)
表格
| 编码 | 占用字节 | 字符串最大长度 |
|---|---|---|
| 00pppppp | 1B | ≤63 字节 |
| 01pppppp qqqqqqqq | 2B | ≤16383 字节 |
| 10000000 + 4 字节长度 | 5B | ≤4294967295 字节 |
✅ 整数类型(开头 bit:11,固定占 1 字节)
表格
| 编码 | 对应类型 |
|---|---|
| 11000000 | int16_t(2 字节) |
| 11010000 | int32_t(4 字节) |
| 11100000 | int64_t(8 字节) |
| 11110000 | 24 位有符号整数(3 字节) |
| 11111110 | 8 位有符号整数(1 字节) |
| 1111xxxx | 直接用低 4 位存数值,范围 1~10,值 = xxxx-1 |