DEBUG OBJECT 返回的 serializedlength 字段才是 Redis 实际存储长度,它反映 RDB/AOF 序列化及内存紧凑布局的真实字节数;需结合 MEMORY USAGE 评估含 key、过期、dictEntry 的总内存占用。

用 DEBUG OBJECT 看实际内存占用
Redis 不直接暴露序列化后的字节长度,DEBUG OBJECT 是最接近真相的手段——它返回 key 的内部编码、引用计数、逻辑长度,以及关键的 serializedlength(序列化后实际存储长度)。这个值才是真正写入 RDB/AOF 或在内存中紧凑布局时的大小。
实操建议:
- 先
SET一个测试 key,再执行DEBUG OBJECT keyname,关注输出里的serializedlength字段 - 对同一组数据分别用
JSON.stringify()、msgpack.encode()、Buffer.from(JSON.stringify(...))存入不同 key,逐个比对serializedlength - 注意:该命令在生产环境慎用,会阻塞主线程;仅用于离线评估或低峰期抽样
字符串 vs 哈希结构的序列化开销差异
把对象存成 STRING(如 JSON 字符串)还是拆成 HASH 字段,影响的不只是读写方式,更是底层序列化粒度。Redis 对 HASH 使用 ziplist 或 hashtable 编码,小字段多时 ziplist 更省空间,但字段值稍大就退化为 hashtable,额外引入指针和哈希表头开销。
常见错误现象:以为“拆成 HASH 总是更省”,结果存了 100 个短字段 + 长文本值,serializedlength 反而比单个 JSON 字符串大 2–3 倍。
实操建议:
- 字段数 ≤ 128 且所有值长度 ≤ 64 字节时,
HASH大概率走ziplist,可尝试 - 含任意一个 > 512 字节的字段,Redis 通常强制切换到
hashtable编码,此时STRING编码 JSON/MsgPack 往往更紧凑 - 用
OBJECT ENCODING keyname快速确认当前编码方式
自定义序列化时,MsgPack 比 JSON 少多少字节?
MsgPack 默认不带 schema,靠类型前缀压缩,对整数、布尔、空值、短字符串特别友好;JSON 则重复携带字段名和引号。但差距不是固定百分比,取决于数据结构稀疏度和值类型分布。
使用场景:高频写入、内存敏感、服务端与客户端都可控序列化协议时,MsgPack 优势明显;若需浏览器直接解析或调试友好,JSON 仍是现实选择。
实操建议:
- 对典型业务对象(如用户 profile),用 Node.js 的
msgpackr和JSON.stringify()分别序列化,取Buffer.byteLength()对比 - 避免嵌套过深的数组——MsgPack 对长数组的长度前缀开销和 JSON 差不多,但嵌套对象越多,优势越明显
- 注意:MsgPack 的
bin类型在 Redis 中存为STRING,无额外解析成本;但某些语言客户端默认不启用 bin 支持,可能误转成 base64 字符串,反而更大
评估时漏掉的两个隐藏成本
serializedlength 只反映值本身,但真实内存占用还包括 key 名长度、过期时间字段(如果设置了 EXPIRE)、以及 Redis 内部的 dictEntry 结构(每个 key 至少额外 32–64 字节,取决于架构)。
容易被忽略的地方:
- key 名每多 1 字节,全量 key 都多占 1 字节——别用
user:profile:123456789:settings这种长 prefix,缩成u:p:123456789:s可能省几百 MB - 哪怕只对 1% 的 key 设置过期,Redis 会为所有 key 分配一个
redisDb.expires字典槽位,高并发下该字典本身就有显著内存开销 - 使用
MEMORY USAGE keyname可看到总内存占用(含 key、value、元信息),比DEBUG OBJECT更贴近真实水位
真正压测前,得把 key 命名策略、是否统一过期、value 序列化格式这三件事定死,否则任何单点对比都没意义。










