首页/数据/数据库速查/String 编码(int / embstr / raw)
Redis 命令96 条

String 编码(int / embstr / raw)

String 有三种内部编码:整数用 int(共享对象)、短字符串用 embstr(≤44 字节,一次分配)、长字符串用 raw;用 OBJECT ENCODING 查看。

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

String 的三种编码是什么

Redis 的 String 在内部有三种编码:纯整数字符串用 int(还能共享小整数对象,最省内存)、长度不超过 44 字节的短字符串用 embstr(对象头与数据一次分配)、更长的字符串用 raw(两次分配)。编码由 Redis 自动选择,用 OBJECT ENCODING 可以查看。关键点是切换通常单向:embstr 一旦被 APPEND 修改就会变成 raw 且不会再变回去。

基本信息

适用版本Redis 2.6+ 已有 embstr,Redis 7.x 阈值与实现细节略有差异
int长整数字符串,可复用共享对象
embstr长度 ≤ 44 字节,只读小字符串,一次内存分配
raw长度 > 44 字节或已被修改过的字符串
查看命令OBJECT ENCODING key、MEMORY USAGE key
权限普通客户端即可执行

典型使用场景

  • 内存优化排查:确认大量短字符串是否仍是 embstr 而不是被改成 raw
  • 缓存设计评审:评估键值长度是否跨越编码阈值导致内存上升
  • 对比不同集群的内存占用差异:编码差异常常是主因之一
  • 排查热点键:结合 OBJECT 命令与采样分析单键开销
  • 验证序列化方案:评估 JSON 与紧凑格式在内存上的差异

观察编码变化

观察编码变化
SET n 12345
OBJECT ENCODING n      # int

SET s "hello"
OBJECT ENCODING s      # embstr

APPEND s "-world-0123456789012345678901234567890123456789"
OBJECT ENCODING s      # raw(追加后变长,且不会再变回 embstr)

SET big "$(python3 -c 'print("a"*100)')"
OBJECT ENCODING big    # raw

MEMORY USAGE s         # 对比不同编码下的实际占用

编码对照

编码产生条件内存特点
int值可解析为 64 位长整数最省,且可复用共享对象
embstr字符串长度 ≤ 44 字节一次分配,读写紧凑
raw长度 > 44 字节,或经 APPEND / SETRANGE 修改两次分配,额外内存开销
阈值边界44 字节是历史实现值,随版本略有差异跨版本迁移后编码可能不同
编码是自动选择的,业务无法直接指定;能做的优化是控制值的长度与修改方式:短字符串尽量整体 SET 而不是 APPEND,需要频繁拼接的数据考虑 Hash 或分段存储。
大量键的内存占用差异往往来自编码而非键数量:同样的业务数据,用 JSON 存与用紧凑格式存可能相差一倍以上,容量评审时以 MEMORY USAGE 实测为准,不要只按字符数估算。

易错点

  • embstr 被 APPEND 后不会变回:反复修改的短字符串长期承担 raw 的额外内存
  • 把 OBJECT ENCODING 当只读诊断而忽略操作时机:GET 不影响编码,但一次 APPEND 就会改变结论
  • 按字符数而非字节数判断阈值:中文按 3 或 4 字节算,跨过 44 字节就变 raw
  • 用 MEMORY USAGE 估总量而不看键数量相关性:单键实测值乘以键数会高估或低估
  • 跨版本迁移后不复查编码:不同版本实现差异导致内存占用变化,容量规划失准

数据来源与参考

  • Redis 官方文档: OBJECT ENCODING
  • Redis 官方文档: Redis 数据类型(String)

相关工具

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