同样的数据不同的内存
键名长度、值的编码方式、单键规模与值尺寸是否统一,都会直接影响 Redis 的内存占用与碎片水平:短键名减少每键固定开销,小 Hash 走 listpack 紧凑编码,把分散的小对象聚合进一个 Hash 能显著减少键数量。优化前必须用工具量化,改完再量化对比,避免凭感觉调整。
基本信息
| 适用 | Redis 4.0 及以上,编码阈值随版本略有差异 |
|---|---|
| 量化手段 | MEMORY USAGE、OBJECT ENCODING、redis-cli --memkeys |
| 编码阈值 | hash-max-listpack-entries(默认 128)与 hash-max-listpack-value(默认 64 字节) |
| 命名约定 | 短前缀要在内部文档登记,否则排障全靠猜 |
编码与占用验证
编码与占用验证
HSET cfg a 1 b 2 c 3
OBJECT ENCODING cfg # listpack:小 Hash 的紧凑编码
MEMORY USAGE cfg # 精确到该键的字节占用
OBJECT ENCODING cfg # 字段数超阈值后会变成 hashtable
CONFIG GET hash-max-listpack-entries # 查看列表压缩的字段数阈值
CONFIG GET hash-max-listpack-value # 查看值长度阈值
redis-cli --memkeys -i 0.1 # 采样统计各键占用,定位大 key省内存手段与代价
| 手段 | 收益 | 代价 |
|---|---|---|
| 短键名加命名空间前缀 | 减少每键固定开销 | 可读性下降,必须在文档登记 |
| 整数编码与 listpack | 小对象内存显著压缩 | 超出阈值即退化为通用编码 |
| 小对象聚合进 Hash | 键数量大幅减少,开销下降 | 单键过大后无法按字段设置过期 |
| value 压缩后存储 | 体积明显下降 | 增加 CPU 与解压时延 |
| 统一 value 尺寸 | 减少分配器尺寸类碎片 | 需要业务侧配合改造 |
典型使用场景
- 缓存节点内存吃紧,评估在不加机器的前提下压缩占用
- 大 key 治理:定位单键占用过高的键并拆分
- 计数器类业务:用 Hash 聚合多字段减少键数量
- 碎片率偏高时从键设计入手排查成因
- 容量规划:用 MEMORY USAGE 估算扩容后的内存需求
优化前先用 MEMORY USAGE 与采样工具量化,改完再量化对比;盲目压缩键名会拖累排障效率,收益与可维护性要一起权衡。
用采样工具统计大 key 会给实例带来额外开销,生产环境建议低峰执行,或改用从库采样。