首页/数据/Redis 进阶速查/listpack 紧凑列表结构
数据结构与选型42 条

listpack 紧凑列表结构

listpack 是 7.0 起取代 ziplist 的顺序紧凑结构:整块内存连续存放、头部记录总长,作为小 Hash、小 ZSet 与 quicklist 节点的底层容器。

Redis 进阶速查数据更新于 2026-10-13

紧凑编码与它的演进

listpack 是 7.0 起取代 ziplist 的顺序紧凑结构:所有元素放在一整块连续内存里,头部记录元素数量与总长度。它出现在小 Hash、小 ZSet 以及 quicklist 的每个链表节点内部。相比 ziplist,listpack 的关键改进是取消了尾部指针记录,修改某个元素不会引发后续元素连锁重写(级联更新),因此在小对象频繁小幅更新的场景下表现更稳定。查看某个键当前使用的编码,用 OBJECT ENCODING。

基本信息

出现位置小 Hash、小 ZSet、quicklist 的节点内部
7.0 变化全面替代 ziplist 作为紧凑编码
查看方式OBJECT ENCODING 返回 listpack
相关阈值hash-max-listpack-entries / hash-max-listpack-value
旧命名6.x 及以前对应的是 ziplist

典型使用场景

  • 确认小 Hash 是否仍处于紧凑编码,判断内存优化是否生效
  • 排查键占用比预期大:编码已经转成了 hashtable
  • 调阈值之前先看现状,避免凭感觉改参数
  • 升级到 7.0 后复核编码名称变化,修正监控里的字符串匹配
  • 容量估算:紧凑编码与常规编码的内存差距相当明显

查看与对照

查看与对照
redis-cli HSET cfg:app theme dark lang zh
redis-cli OBJECT ENCODING cfg:app          # 小对象:listpack
redis-cli ZADD rank 1 a 2 b
redis-cli OBJECT ENCODING rank             # 小 ZSet:listpack
redis-cli CONFIG GET hash-max-listpack-entries   # 当前字段数阈值
redis-cli MEMORY USAGE cfg:app             # 量化单键占用,调优前后对比
redis-cli CONFIG REWRITE                   # 调整阈值后落盘

编码与触发条件

编码触发条件内存特征
listpack(Hash)字段数与值长度均在阈值内连续内存,单键额外开销小
hashtable(Hash)字段数或单值长度超出阈值每个字段都有指针开销
listpack(ZSet)成员数与成员长度在阈值内连续内存,适合小排行榜
skiplist(ZSet)突破阈值后转换支持范围查询,内存开销更大
listpack 同样要求整块连续内存,把阈值调得过于激进会让单个对象变大,一次修改需要搬动的字节随之增加,O(N) 操作的阻塞时间也被拉长。调优要结合访问模式,而不是只看内存数字。
从 6.x 升级到 7.0 时,配置项从 ziplist 系列改名为 listpack 系列,部分版本仍保留旧名作为兼容别名。脚本或监控里按字符串匹配编码名称的地方要一并调整,否则判断会静默失效。

易错点

  • 把阈值调得很大,单个紧凑对象随之变大,一次修改要复制大块内存,阻塞时间明显上升
  • 监控按 ziplist 字符串匹配编码,升级后判断全部失效却不报错,问题长期潜伏
  • 以为改阈值能立即省内存,实际存量键需要重建才会重新判断编码
  • 对紧凑编码对象执行全量遍历,忽略它同样受单线程阻塞约束

数据来源与参考

  • Redis 7.0 Release Notes:listpack 全面替代 ziplist
  • Redis 官方文档:内存优化相关说明
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌