首页/数据/Redis 进阶速查/Hash 编码:listpack 与 hashtable 切换
数据结构与选型42 条

Hash 编码:listpack 与 hashtable 切换

少量字段的 Hash 用 listpack 紧凑保存,超过 hash-max-listpack-entries(默认 128)或单字段超过 64 字节即转 hashtable,内存与查询特性随之变化。

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

Hash 的编码是什么

Hash 类型的底层实现有两种:字段少、字段值小时用 listpack 把全部字段值连续存放在一块紧凑内存里,省去指针与哈希表的额外开销;字段数或单个字段长度超过阈值后转为 hashtable,每个字段用字典条目表示,查询与更新稳定高效但内存开销明显上升。阈值由 hash-max-listpack-entries 与 hash-max-listpack-value 两个配置决定,7.0 之前的命名是 ziplist 系列。

基本信息

两种编码listpack(紧凑)与 hashtable(字典)
条目阈值hash-max-listpack-entries 默认 128
值长度阈值hash-max-listpack-value 默认 64 字节
查看方式OBJECT ENCODING key
命名变化7.0 起配置项由 ziplist 改为 listpack,旧名作为别名保留

典型使用场景

  • 对象缓存:用户资料、商品属性这类字段数不多的对象,listpack 编码下内存占用接近理论上限的紧凑程度
  • 按维度聚合计数:把一个实体的多种计数放进一个 Hash,字段级 HINCRBY 原子递增
  • 配置与开关集合:字段数量可控、读多写少的键值对集合
  • 内存优化核查:用 OBJECT ENCODING 确认线上键是否真的处在紧凑编码,而不是已经悄悄升级
  • 容量评估:按编码阈值估算每个键的平均开销,判断是否需要调整阈值或改变数据组织方式

观察编码变化

观察编码变化
redis-cli HSET user:1 name alice age 30
redis-cli OBJECT ENCODING user:1              # listpack
redis-cli CONFIG GET hash-max-listpack-entries   # 默认 128
redis-cli CONFIG GET hash-max-listpack-value     # 默认 64
redis-cli HSET user:1 bio <一段超过 64 字节的文本>
redis-cli OBJECT ENCODING user:1              # raw 或 hashtable,已升级
redis-cli MEMORY USAGE user:1                 # 对比升级前后的实际占用

编码对照

编码适用条件特点
listpack字段数与字段长度都在阈值内连续内存、无指针开销、内存最省
hashtable字段数或字段长度超阈值查询稳定 O(1),内存开销明显更高
不可逆一旦升级不会自动退回删除元素后仍保持 hashtable
阈值可调通过 CONFIG SET 调整调大能让更多键保持紧凑,但单命令阻塞时间随之上升
编码升级是单向的:Hash 从 listpack 转为 hashtable 后,即使把字段删到只剩一个也不会退回紧凑编码,只有键被删除后重新写入才会重新开始。因此阈值调整对存量数据无效,只影响此后新建的键。
把阈值调大能让更多键保持紧凑,但单个键包含的元素越多,对该键执行 HGETALL 或删除整个键时的单次阻塞时间越长。批量操作大 Hash 会长时间占用主线程,需要评估元素规模后再决定阈值。

易错点

  • 以为调整阈值能立刻让存量键变紧凑,实际编码升级不可逆,优化只对新建键有效,存量数据需要重建才能受益
  • 把超大 Hash 当成万能容器,字段数上千万后 HGETALL 与整键删除会长时间阻塞,应按时间或业务维度拆分
  • 只看内存总量不看单键编码,优化方向缺乏依据,应先用 OBJECT ENCODING 与 MEMORY USAGE 抽样定位
  • 把 7.0 之后的新配置名与旧名混用在同一份配置里,排查时容易误以为配置未生效,需确认当前版本支持的写法

数据来源与参考

  • Redis 官方文档:Hashes 数据类型
  • Redis 7.0 配置文件 redis.conf 注释
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌