Redis集群中DEL/MGET/MSET等命令失败的根本原因是协议强制要求多key操作必须同槽,否则报CROSSSLOT错误;因集群不支持跨节点原子操作,需通过HashTag或客户端按slot分组+Pipeline解决。

因为 Redis 集群要求多 key 命令的所有 key 必须落在同一个哈希槽(slot),否则直接拒绝执行,报 CROSSSLOT Keys in request don't hash to the same slot。
为什么 DEL/MGET/MSET 等命令在集群里会失败
Redis 集群把 16384 个 slot 分配给不同节点,每个 key 通过 CRC16(key) % 16384 算出所属 slot。批量命令如 DEL key1 key2 要求所有 key 的 slot 一致——否则就等于要跨节点原子操作,而集群不支持跨节点事务或原子批量。
-
MGET key1 key2失败:key1 槽 9189(在 7010 节点),key2 槽 4998(在 7000 节点) -
MSET a 1 b 2同理,只要 a 和 b 的 slot 不同,就立刻报错 - 连
EXEC事务也会失败,只要 MULTI 里命令涉及多个 slot 的 key
怎么查一个 key 落在哪 slot
用 cluster keyslot 命令直接算,不用猜:
127.0.0.1:7000> cluster keyslot user:1001
(integer) 9189
127.0.0.1:7000> cluster keyslot order:{1001}:202401
(integer) 12706
注意:{} 是哈希标签分隔符,Redis 只对 {} 内的内容计算 slot。所以 user:{1001}:name 和 user:{1001}:age 一定同槽,但 user:1001:name 和 user:1002:age 几乎必然不同槽。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
批量删除通配符 key(如 log:*)该怎么写
不能用 KEYS log:*(集群禁用),也不能直接 DEL log:*(不支持 glob)。必须手动遍历所有主节点,分别 SCAN + DEL:
- 先获取全部主节点地址:
redis-cli -h 127.0.0.1 -p 7000 cluster nodes | grep master | awk '{print $2}' - 对每个节点执行:
redis-cli -h node_ip -p node_port --scan --pattern "log:*" | xargs -n 100 redis-cli -h node_ip -p node_port DEL - 注意:xargs -n 100 控制每批删 100 个,避免单次命令过长或阻塞
JedisCluster 怎么安全地批量 get
官方 JedisCluster.mget() 会直接抛 CROSSSLOT 异常。正确做法是客户端自己按 slot 分组,再对每组用 pipeline 发到对应节点:
- 调用
JedisClusterCRC16.getSlot(key)算出每个 key 的 slot - 查
JedisClusterInfoCache.getSlotPool(slot)得到目标节点连接池 - 把同 slot 的 key 归为一组,用
Pipeline批量发过去 - 别漏掉异常处理:某个节点临时不可达时,这组 key 就得降级为逐条重试
真正麻烦的不是“能不能做”,而是 slot 分组逻辑一旦写错(比如没处理哈希标签、忽略大写小写),就会在流量高峰突然触发大量跨槽错误——这种问题往往压测覆盖不到,上线后才暴露。

















