redis压缩列表(ziplist)通过连续内存布局、变长编码和去除指针开销节省内存,非依赖压缩算法;满足字段数≤512且value≤64字节时自动启用,可省60%以上内存,退化为hashtable后不可逆。

Redis 压缩列表(ziplist)不是靠“压缩算法”节省内存,而是通过连续内存布局 + 变长编码 + 去除指针开销实现空间优化。它不适用于大数据,专为小规模、短内容设计——本质是用一点查找时间换显著内存下降。
为什么比常规结构更省空间?
以 Hash 类型为例:
- 普通 hashtable:每个 field/value 对需两个指针(prev/next 或 dictEntry 指针),64 位系统下仅指针就占 16 字节,再加 key/value 字符串头(SDS)、哈希桶等,单个 entry 实际开销常达 56–80 字节
- ziplist 编码:所有 entry 紧挨着存一块连续内存里,没有指针;每个 entry 只存“上一节点长度 + 当前编码类型 + 实际数据”,无冗余头信息;小整数(如 127)只用 1 字节存储
- 实测对比:10 个字段、value 均为 10 字节字符串的 Hash,在 ziplist 下约占用 220 字节;退化为 hashtable 后常升至 600+ 字节——内存可减少 60% 以上
ziplist 自动启用的条件与验证方法
它不会手动开启,完全由 Redis 根据数据特征和配置阈值动态决定:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- Hash:字段数 ≤ hash-max-ziplist-entries(默认 512)且每个 value 长度 ≤ hash-max-ziplist-value(默认 64 字节)
- List:元素数 ≤ list-max-ziplist-entries(默认 512)且每个元素 ≤ list-max-ziplist-value(默认 64 字节)
- ZSet:成员数 ≤ zset-max-ziplist-entries(默认 128)且每个 member/score ≤ zset-max-ziplist-value(默认 64 字节)
- 验证是否生效:
redis-cli object encoding your_key返回 "ziplist" 即命中;配合hlen和hstrlen key field查字段数与各 value 实际长度
调优建议:放宽阈值但避开陷阱
默认值偏保守,生产中常需调整,但必须结合业务数据分布:
- 若 Hash 字段多为 ID、状态码、短标签(如 "active"、"1"、"2026-08"),可安全设
hash-max-ziplist-value 128 - 字段数稳定在 10 个左右(如用户基本信息),
hash-max-ziplist-entries 1024合理;设到 2048 无意义,因 ziplist 查找是 O(n),字段越多 HGET 平均耗时越明显 -
切忌为塞长文本强行调大
hash-max-ziplist-value:value 超 200 字节(如 base64 图片片段)时,应直接设为 0,让 Redis 用 hashtable,避免因 realloc 引发延迟毛刺 - 注意:Redis 7.0 起已用 listpack 替代 ziplist,但编码退化逻辑一致,长 value 仍会导致结构升级
关键提醒:这不是通用压缩,别在应用层自己 gzip
Redis 明确不支持对 value 做 LZF/gzip 压缩,原因很实际:
- 每次 GET/SET 都要 CPU 解压/压缩,QPS 直接跌 30%+
- 原子命令(
HINCRBY、DECR、LPOP)全部失效,只能靠客户端模拟,丧失一致性保障 - 序列化后 value 变成二进制 blob,无法被 Redis 内部命令识别或操作
- 真正省空间的方式,是让 Redis 自己选对结构——而不是把压缩责任甩给应用层










