Redis 紧凑存储结构(ziplist /listpack)详细优势
一、核心优势:极致节省内存(最核心价值)
普通哈希表(dict)、双向链表,每个节点除了业务数据,还要附带大量指针、元数据。
- 64 位系统,一个指针就要占用 8 字节;
- 哪怕你只存很短字符串,节点本身的指针开销甚至大于业务数据本身,内存碎片化严重。
紧凑存储是一整块连续内存,没有分散的节点指针:
- 整块内存一次性申请,不需要为每个 K/V 单独分配内存;
- 元数据极少,只保存少量长度标记,去掉所有对象指针;
- 内存连续,减少内存碎片。
举例:存储用户简单 hash(name、age、city),用 listpack 占用内存远小于 hashtable。 只有当元素数量变多、value 变长,才会自动切换到 hashtable。
✅ listpack 在内存上比 ziplist 更进一步:去掉了「前一个 entry 长度」冗余字段,同等数据下内存占用比 ziplist 更小。
二、CPU 缓存友好,访问速度更快
CPU 读取内存有高速缓存 Cache机制:连续内存块更容易被加载进 CPU 缓存。
- 普通哈希表:节点分散在堆内存各处,访问时频繁发生缓存失效(cache miss),CPU 要多次访问内存,速度慢;
- ziplist/listpack:连续内存,一次性加载一大段内存到 CPU 缓存,遍历读取时命中率很高。
适用场景:批量遍历小 hash、短列表,读取性能会明显优于普通哈希表 / 链表。
三、元数据简单,轻量,适合小数据场景
紧凑结构的头部元数据非常精简:
- ziplist:zlbytes、zltail、zllen、zlend;
- listpack:header + 结束标记,每个 entry 仅存当前 entry 长度 + 数据。
不需要维护哈希桶、链表指针、next/prev 引用等复杂元信息。 在元素数量少,value 很短场景下,元数据开销几乎可以忽略。
四、天然支持顺序遍历(正向、反向)
ziplist
每个 entry 记录前一项长度,支持从尾部向前反向遍历。
缺点:这个特性带来连锁更新缺陷。
listpack
取消了前一项长度字段:
- 正向遍历:读取当前 entry 自身长度,直接跳到下一条;
- 反向遍历:依靠总长度,从末尾向前计算偏移;
既保留正反遍历能力,又消除了连锁更新的致命缺陷。
五、自动降级,对业务无感知(Redis 自动切换编码)
Redis 会自动判断:
- 满足阈值(元素数量、value 长度)→ 使用 listpack/ziplist 紧凑存储;
- 一旦超出阈值 → 自动转换成 hashtable。
业务代码完全不用改动,HSET/HGET 等命令写法不变,底层存储自动切换,对上层应用透明。 配置项可自定义阈值:hash-max-listpack-entries、hash-max-listpack-value,可以根据业务调优。
六、listpack 相比 ziplist 新增的关键优势(重点)
ziplist 有致命缺陷:连锁更新,listpack 全部解决,同时保留上面所有优点。
- 彻底消除连锁更新(多米诺骨牌阻塞风险) ziplist 修改 entry 长度会导致后续所有 entry 全部重分配,极端场景阻塞 Redis 单线程。 listpack 每个 entry 只记录自身长度,修改某一条数据,只会影响当前 entry,不会连锁改动后面所有数据,不存在大面积内存移位,不会出现长时间阻塞。
- 元素数量读取 O (1) ziplist 的 zllen 只有 16bit,最多记录 65535,超过之后必须遍历全部 entry 统计总数,O (n); listpack 直接存储完整元素个数,随时直接读取总数,O (1)。
- 内存布局更简洁,编码逻辑更简单,减少 bug。
七、适用边界(优势不是无限的,配套理解)
紧凑存储的优势只在少量、短 value场景生效; 当元素很多、value 很长时:
- 插入、修改的内存移位成本会变高(连续内存中间插入需要挪动后面所有数据);
- 此时 Redis 自动切换 hashtable,放弃紧凑存储,利用哈希表 O (1) 随机读写优势。
一句话总结边界:小数据省内存,大数据交给哈希表,Redis 自动切换。
八、优势汇总(面试可直接背诵精简版)
- 内存占用极低:连续内存,消除大量指针开销,减少内存碎片;listpack 比 ziplist 更省内存。
- CPU 缓存友好:连续内存,提升 cache 命中率,顺序遍历速度快。
- 元数据精简,结构轻量,适合短值少量数据。
- 支持正反双向遍历。
- 上层业务透明,Redis 自动判断编码,无需业务改造。
- listpack 独有:根除 ziplist 连锁更新阻塞风险;元素数量查询 O (1)。
所属版权:JSON工具 JSON工具
原文路径:
转载声明:转载时必须以链接形式注明原始出处及本声明。