Redis Cluster slot冲突必须手动修复:先用CLUSTER DELSLOTS从错误节点摘除重叠slot,再用CLUSTER ADDSLOTS在正确节点显式分配,严禁依赖--cluster fix;修复后需reloadPartitions或重启客户端连接以更新路由缓存。

直接用 redis-cli --cluster fix 会失败,因为这不是“缺槽”,而是“重叠”
Redis Cluster 不允许两个 master 同时 claim 同一个 slot,一旦发生,cluster_state:fail 是必然结果,redis-cli --cluster check 会明确报出类似 ERROR: Slot 1234 is assigned to both 2728a594... and 8e98e4b8... 的错误。此时运行 redis-cli --cluster fix 不会起作用——它只处理未分配(unassigned)slot,对冲突 slot 完全无视。
必须手动强制清理冲突 slot 的归属
核心动作是:选一个节点作为该 slot 的合法 owner,再用 redis-cli --cluster add-node 或 CLUSTER ADDSLOTS 显式赋权,同时用 CLUSTER DELSLOTS 从另一个节点上摘除。操作前务必确认哪边数据更新、是否可丢弃:
- 先连上疑似“错误拥有”slot 的节点(比如
redis-cli -c -h 127.0.0.1 -p 7002),执行CLUSTER DELSLOTS 1234—— 注意必须用-c模式或直连该节点,否则命令被重定向到 owner 节点而失败 - 再连上应保留数据的节点(如
127.0.0.1:7001),执行CLUSTER ADDSLOTS 1234 - 两步之间不要做任何写入;如果业务正在读写这个 slot,建议先切流或降级
- 执行完后,立刻跑
redis-cli --cluster check 127.0.0.1:7001验证 slot 归属是否唯一且无报错
为什么会出现两个 master claim 同一个 slot?
这不是配置失误,而是集群元数据状态撕裂的典型表现,常见于以下场景:
- 节点宕机后快速重启,但旧 gossip 信息尚未完全收敛,新老 view 对 slot owner 认知不一致
- 手动执行过
CLUSTER SETSLOT ... MIGRATING或IMPORTING但中途失败,残留了半截迁移状态 - 使用非官方脚本或工具直接修改
nodes.conf并强制重启,绕过了集群内部校验逻辑 - 跨机房部署时网络分区恢复后,两边各自认为自己是 owner,Gossip 未能及时归并
修复后客户端仍打错节点?重点检查 MOVED 响应和连接复用
即使 slot 归属已修正,客户端可能还在往旧节点发请求,原因不是命令没生效,而是缓存没刷新:
- 用
redis-cli -c测试能立刻走对,是因为每次命令都新建连接并触发一次 MOVED 重定向 - 业务代码中若复用长连接(如 Lettuce 的
StatefulRedisClusterConnection),需调用reloadPartitions()强制拉取最新 slot map - 某些老版本客户端(如 Jedis 3.3 以下)不自动处理 MOVED,会静默失败或反复重试,必须升级或加兜底重试逻辑
- 注意区分 ASK 和 MOVED:只有 MOVED 才表示 slot 已永久切换,ASK 只在迁移中临时存在,客户端不应据此更新本地路由表
实际中最容易被忽略的是:冲突 slot 往往不止一个,check 输出里可能列出一串,但人眼扫过去只修了前两三个。务必用 grep "is assigned to both" 抽出来逐条处理,漏掉任意一个,集群状态就永远卡在 fail。











