首页/数据/数据库速查/缓存序列化选型(JSON / MsgPack / Protobuf)
Redis 运维与场景124 条

缓存序列化选型(JSON / MsgPack / Protobuf)

序列化决定体积与兼容性:JSON 可读通用、MsgPack 紧凑、Protobuf 最小最快但需 schema;带版本前缀便于演进。

数据库速查数据更新于 2026-10-13

缓存序列化选型是什么

缓存里存什么格式决定了三件事:占用内存、可读性、演进难度。JSON 通用可读但体积最大,MsgPack 更紧凑,Protobuf 体积最小最快但需要 schema 与生成代码;大 value 还可以选择先压缩再存,用 CPU 换内存与带宽。无论选哪种,都要给键值加版本前缀,并把「反序列化失败」当作缓存未命中处理,而不是抛错给用户。

基本信息

适用版本与 Redis 版本无关,取决于客户端序列化库
JSON通用、可读、调试友好,体积最大
MsgPack二进制紧凑,需工具才能阅读
Protobuf / Thrift体积最小、跨语言,需要 schema 与代码生成
压缩JSON + gzip/zstd 省内存,但消耗 CPU
演进策略键值加版本前缀(如 :v2),新增字段可空,删除字段先过渡

典型使用场景

  • 多语言服务共享缓存:Protobuf 保证各语言解析一致
  • 调试频繁的业务:JSON 便于直接查看内容
  • 内存紧张的大缓存:紧凑格式或压缩能显著降低占用
  • 结构演进:用版本化键名实现新旧格式并行过渡
  • 大对象缓存:先压缩再存,评估 CPU 与网络收益

格式对比

格式体积可读性与兼容
JSON大可读性好,字段增减较宽容
MsgPack中需工具查看,字段增减同样宽容
Protobuf小需 schema,跨语言一致性最好
JSON + gzip小(CPU 换)可读性好,解压有 CPU 开销
Java 原生序列化较大跨语言与升级易碎,不建议在缓存中使用

版本前缀与容错实践

版本前缀与容错实践
# 键值带版本前缀,结构升级时并行存在 v2 与 v3
SET user:1001:v2 '{"name":"张三"}' EX 300
GET user:1001:v2
TTL user:1001:v2

# 结构升级时的双写过渡
SET user:1001:v3 '{"name":"张三","level":3}' EX 300

# 反序列化失败的处理原则:视为未命中,回源重建而不是报错

大小与编码核对

大小与编码核对
# 对比不同序列化后的实际占用
MEMORY USAGE user:1001:v2
OBJECT ENCODING user:1001:v2   # 超过 44 字节即为 raw

# 大 value 加压缩后体积变化需实测,别凭感觉判断
STRLEN user:1001:v2
跨语言服务用 Protobuf 或 Thrift 更稳,单语言且调试频繁用 JSON 更省事;关键是别在缓存里存不可演进的结构,并把格式与版本写进接口文档,避免不同服务各自解读同一份数据。
缓存中的序列化异常必须降级为「未命中」:把解析错误抛给用户会让一次格式变更直接变成线上故障,而正常做法是回源重建并记录日志统计比例。

易错点

  • 缓存里存语言原生序列化对象(如 Java 序列化):跨语言或类结构变更即无法解析
  • 反序列化异常直接抛给用户:格式升级变成大面积报错,应降级为未命中回源
  • 不做版本前缀:新旧结构混在同一键名上,灰度期无法区分,回滚困难
  • 压缩所有 value:CPU 开销大于收益,小对象压缩反而增加延迟与体积
  • 只按字符数估算内存:结构化格式加键名与括号后实际占用远高于预期,容量评审要用实测值

数据来源与参考

  • Redis 官方文档: 数据类型
  • 缓存序列化实践

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌