首页/数据/Redis 进阶速查/CROSSSLOT 错误与多 key 限制

CROSSSLOT 错误与多 key 限制

集群模式下多 key 命令(MGET、MSET、SINTERSTORE、事务、Lua)要求所有键在同一槽,否则报 CROSSSLOT Keys in request do not hash to the same slot。

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

CROSSSLOT 是什么

集群把键空间分片后,一条命令涉及的所有键必须落在同一个槽里,否则无法在单个节点上完成,服务端直接返回 CROSSSLOT 错误,提示这些键没有哈希到同一个槽。受影响的包括 MGET、MSET、SINTERSTORE、SUNION、重命名、事务 MULTI、以及 Lua 脚本中的所有键。解决办法只有两个:要么让相关键通过哈希标签落在同一槽,要么把多键操作拆成多次单键调用。

基本信息

报错文本CROSSSLOT Keys in request do not hash to the same slot
触发条件多键命令或事务、脚本中涉及跨槽的键
哈希标签用 {} 包住参与计算的部分,如 {user1001}:profile
标签规则只取第一对花括号内的内容参与 CRC16 计算
验证工具CLUSTER KEYSLOT 逐个确认键的槽号

典型使用场景

  • 按业务主体聚合键:把同一用户的多个键套上相同标签,使相关多键操作在集群下可用
  • 重构既有单机应用:上线集群前先梳理所有多键命令,逐一决定改标签还是改为多次单键调用
  • Lua 脚本迁移:脚本中涉及的键必须同槽,否则需要拆脚本或调整键命名
  • 客户端批量优化:确认哪些批量操作能合并、哪些必须按槽拆分后并发发送
  • 故障排查:业务报错里出现 CROSSSLOT 时,用 KEYSLOT 快速定位是命名问题还是设计问题

复现与验证

复现与验证
redis-cli -c -p 7000 MGET k1 k2
# (error) CROSSSLOT Keys in request do not hash to the same slot
redis-cli -p 7000 CLUSTER KEYSLOT user:1001        # 看键落在哪个槽
redis-cli -p 7000 CLUSTER KEYSLOT '{user1001}:profile'
redis-cli -p 7000 CLUSTER KEYSLOT '{user1001}:orders'   # 与上一行槽号相同
redis-cli -c -p 7000 MGET '{user1001}:profile' '{user1001}:orders'   # 同槽后可用

两类解法对照

解法适用情况代价
哈希标签同槽键之间确有业务关联,如一个用户的多类数据标签粒度决定分片均匀度,粗标签会造成热点
拆成多次单键调用键之间没有强关联,如批量取多个无关对象往返次数增加,需要并发发送或管道化
业务层聚合集合运算跨主体,如求两个大集合的交集需把数据拉到应用侧计算,注意内存与耗时
改用单键结构把多个小对象合并进一个 Hash 或 ZSet单键规模上升,注意编码阈值与阻塞时间
标签的取用规则:只有第一对花括号内的内容参与 CRC16 计算,{a}{b} 只按 a 计算,{} 空标签则按整键计算。团队必须约定唯一且语义明确的前缀,否则同一业务主体被写成不同标签,多键操作仍然失败。
把所有键都套上同一个标签,等于把集群退化成单槽单机:所有写入集中在一个节点,其他节点空转,扩容与故障转移都失去意义。标签的粒度应落在「需要一起操作的键集合」这一层级。

易错点

  • 在单机环境开发完成后直接部署到集群,多键命令全部失败,测试环节必须覆盖集群模式下的批量与事务操作
  • 用客户端循环单键替代多键命令却不做并发,往返次数成倍增加,性能反而比同槽方案差很多
  • 标签粒度设计过粗,大量键挤进同一个槽,形成单节点热点,容量规划需要与键设计一起做
  • 把哈希标签用在热点键上而不评估均匀度,某个槽的负载远高于其他槽,监控上表现为单节点 CPU 与内存明显偏高

数据来源与参考

  • Redis 官方文档:集群多 key 限制说明
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌