把多个键绑定到同一个槽
哈希标签的作用是强制让多个键落到同一个槽。规则很简单:键名里第一对花括号内的内容参与槽位计算,花括号之外的部分不参与。因此 {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} | 跨键操作最方便 | 全部数据挤进一个槽,分片失去意义 |
| 完全不带标签 | 分布最均匀 | 多键命令与事务无法使用 |
| 事后改造已有键 | 可获得同槽能力 | 需要全量数据重分布,成本高 |
键名里出现多对花括号时只有最先出现的那一对生效,后面的花括号不参与计算;如果花括号内为空则整段键名照常参与计算,等价于没有标签。这两种情况和直觉都不一致,写键名时最好只保留一处标签。