首页/数据/Redis 进阶速查/哈希标签设计实践

哈希标签设计实践

花括号内的内容决定槽位:{order}:1001 与 {order}:1002 的标签不同、可能跨槽;{user:1001}:a 与 {user:1001}:b 的标签相同、必然同槽。

Redis 进阶速查数据更新于 2026-10-13

把多个键绑定到同一个槽

哈希标签的作用是强制让多个键落到同一个槽。规则很简单:键名里第一对花括号内的内容参与槽位计算,花括号之外的部分不参与。因此 {user1001}:profile 与 {user1001}:orders 必然同槽,而 {u1}:a 与 {u2}:a 的标签不同,槽号也就不同。没有花括号时整个键名都参与计算,两个不同键几乎不可能自动同槽。标签的设计目标,就是圈定「必须能在一起做原子操作或批量操作」的那组键。

基本信息

规则仅第一对花括号内的内容参与槽位计算
同槽示例{user1001}:profile 与 {user1001}:orders
异槽示例{u1}:a 与 {u2}:a
槽总数固定 16384
验证命令CLUSTER KEYSLOT <key>

典型使用场景

  • 跨键原子操作:Lua 脚本或事务要同时改多个键时,用标签保证同槽
  • 批量读取同一实体的多个键(资料、明细、计数),避免跨槽多次往返
  • 热点控制:按维度设计标签,让访问压力更均匀地落到不同分片
  • 改造评估:检查现有键名是否需要加标签以支持多键命令
  • 多键命令评审:MGET、MSET 等操作前的键设计检查

验证与使用

验证与使用
redis-cli -p 7000 CLUSTER KEYSLOT '{user1001}:profile'   # 计算槽号
redis-cli -p 7000 CLUSTER KEYSLOT '{user1001}:orders'    # 与上一行相同即为同槽
redis-cli -p 7000 CLUSTER KEYSLOT '{u2}:a'               # 标签不同,槽号可能不同
# 脚本里同时访问的键必须同槽,否则报 CROSSSLOT
redis-cli -p 7000 EVAL "return redis.call('MGET', KEYS[1], KEYS[2])" 2 '{u1}:a' '{u1}:b'

标签粒度取舍

做法收益代价
标签为单个实体该实体的多个键可原子操作键多时压力集中在一个分片
标签过粗如统一 {app}跨键操作最方便全部数据挤进一个槽,分片失去意义
完全不带标签分布最均匀多键命令与事务无法使用
事后改造已有键可获得同槽能力需要全量数据重分布,成本高
键名里出现多对花括号时只有最先出现的那一对生效,后面的花括号不参与计算;如果花括号内为空则整段键名照常参与计算,等价于没有标签。这两种情况和直觉都不一致,写键名时最好只保留一处标签。

易错点

  • 给全部键加同一个标签,所有数据挤进一个槽,集群退化成单实例并出现明显热点
  • 需要原子操作的键落在不同槽,Lua 脚本或事务直接报 CROSSSLOT 错误,线上功能中断
  • 迁移已有系统时临时更改标签方案,等于触发全量数据重分布,风险与工时不符预期
  • 写成空花括号以为能生效,实际仍按整个键名计算,同槽假设落空导致批量操作失败

数据来源与参考

  • Redis 官方文档:哈希标签(Hash tags)说明
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌