登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  科技周边 >  业界新闻

Redis 8.10 Compact Hash新哈希布局会影响哪些内存场景

来源:17golang原创

时间:2026-11-04 14:18:21 271浏览 收藏

Redis 8.10 的 Compact Hash 主要解决一种很具体的内存重复:大量 Hash key 拥有相同或基本稳定的 field 集合,却为每个 key 重复保存字段名。对用户资料、订单快照、会话对象这类“同一结构、很多实例”的数据,它可能明显减少字段名开销;对字段集合经常变化、使用字段过期或只有少量 key 的数据,收益就不能想当然。

官方地址:https://redis.io/docs/latest/develop/whats-new/8-10/

判断是否值得迁移的关键,不是看到“Compact”就改命令,而是先确认:有多少个 Hash 共享同一套字段、字段是否稳定、是否能接受先在影子环境观察模板指标。

Compact Hash 真正省的是哪一部分内存

传统 Hash 可以理解为每个 key 都带着自己的 field-name 集合。假设有数百万个用户对象,每个对象都包含 name、email、country 和 last_login,字段名本身会被反复保存。Compact Hash 把共享字段集合抽成模板,多个 key 只保留各自的值和对模板的引用。

Redis 8.10 Compact Hash 共享字段模板与独立值的结构说明图
图1:Compact Hash 布局说明图,展示共享字段集合与独立值之间的关系,不是运行截图。

这带来三个判断点:

  • 重复结构越多,字段名被共享的空间越大,节省越有意义。
  • 已有的 HGET、HGETALL、HSET 等命令语义不需要改写,变化主要在内部编码。
  • “最多降低 50%”是官方针对特定宽度和数据形状给出的上限信号,不是每个线上实例的固定比例。

什么时候用 HIMPORT,什么时候保持现有 HSET

如果应用正在批量创建同构 Hash,可以使用 Redis 8.10 新增的 HIMPORT。它先在当前连接准备一个有序 fieldset,之后每个 key 只发送对应顺序的值。示意命令如下:

# 只在当前连接声明一次稳定的字段顺序
redis-cli HIMPORT PREPARE profile name email country last_login

# 按上面字段顺序写入值,避免每个 key 重复发送字段名
redis-cli HIMPORT SET user:1001 profile Alice alice@example.test CN 2026-09-14T08:00:00Z
redis-cli HIMPORT SET user:1002 profile Bob bob@example.test US 2026-09-14T08:02:00Z

# 会话结束或不再使用时,清理当前连接的 fieldset
redis-cli HIMPORT DISCARD profile

HIMPORT 的 fieldset 是连接级的,会话断开或执行 RESET 后不再可用。因此它适合由批处理客户端长期控制连接和字段顺序的场景,不适合把 fieldset 名称当成跨连接的全局配置。

如果暂时不能改客户端,也可以考虑让普通写入路径自动转换。Redis 8.10 提供了 hash-min-template-entries 和 hash-max-template-entries 等配置,转换是惰性的:运行 CONFIG SET 后,已有 Hash 不会瞬间全部重写,而是在后续写入时判断。可以先在非生产环境用较窄的范围观察:

# 只让字段数在 4 到 16 之间的 Hash 参与后续写入转换
redis-cli CONFIG SET hash-min-template-entries 4
redis-cli CONFIG SET hash-max-template-entries 16

# 记录配置,便于回滚或在变更单中保留当前值
redis-cli CONFIG GET hash-min-template-entries hash-max-template-entries

这里的数字不是通用推荐值。若业务 Hash 经常追加临时字段、字段过宽,或者使用字段级过期,应该先保留普通布局,再根据观测结果调整。

用哪些指标判断内存收益

我会把“迁移成功”拆成三个可观察的问题:模板有没有形成、多少 key 在引用、单个 key 的统计是否包含模板分摊。Redis 8.10 增加了相应指标:

观察入口重点字段它回答的问题
INFO STATShash_templates、hash_template_keys有多少模板、多少 key 使用了 Compact Hash
INFO MEMORYused_memory_hash_templates共享模板整体占用了多少内存
MEMORY USAGE key单 key 使用量该 key 的数值包含它分摊到的模板成本
Redis 8.10 Compact Hash 内存指标之间的关系说明图
图2:内存指标关系说明图,展示模板数量、引用键数量和单键统计口径,不是监控截图。

这些数字要和业务对象数量一起看。只有一个或几个 key 的小数据集,即使被转换,也未必能抵消模板本身的成本;大量同构 key 才更容易体现共享字段名的价值。比较前后时还要保持样本规模、字段集合和采样时间一致,避免把业务增长误判为布局收益。

# 查看 Compact Hash 的模板数量与引用键数量
redis-cli INFO STATS | grep -E 'hash_templates|hash_template_keys'

# 查看共享模板占用的整体内存
redis-cli INFO MEMORY | grep used_memory_hash_templates

# 查看某个 Hash 的统计口径;结果含该 key 分摊的模板成本
redis-cli MEMORY USAGE user:1001

升级时最容易忽略的四个边界

  1. 字段集合不稳定:如果每个 Hash 都在追加不同字段,模板复用率会下降,后续维护也更难判断。
  2. 字段过期:官方文档明确指出,使用 field expiration 的 Hash 不会因为字段数满足条件就转换。
  3. 超宽 Hash:hash-max-template-entries 可以把过宽对象排除在自动转换之外,避免把不适合共享的结构塞进注册表。
  4. 旧 RDB 升级:RDB 加载转换是有条件的升级路径,不等于对所有现存数据立即重写;要把加载时间和内存峰值单独纳入评估。

最后可以用一张小清单收口:同构 Hash 是否足够多?字段名是否稳定?是否使用字段过期?客户端能否维持 HIMPORT 连接会话?模板指标是否连续增长?只有前四项大多为“是”,并且观测到模板引用数量稳定增加,才值得继续扩大范围。

常见问题

Compact Hash 会改变现有 Hash 命令的返回结果吗?不会。它是内部编码,重点变化是字段名存储方式;已有 Hash 命令仍按原语义读写。

开启自动转换后,内存会立刻下降吗?不一定。写入路径的自动转换按后续写入惰性触发,旧数据还要结合 RDB 加载配置或业务迁移窗口评估。

HIMPORT 是否适合所有批量写入?不适合。只有字段集合稳定、客户端能维持连接级 fieldset、并且数据量足够大时,才有机会同时获得网络与内存收益。

参考资料:https://redis.io/docs/latest/develop/data-types/hashes/、https://redis.io/docs/latest/commands/himport/、https://redis.io/docs/latest/commands/memory-usage/

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>