Redis Cluster节点握手失败的根本原因是TCP连通性问题或cluster-enabled yes配置未生效;需确认cluster_enabled:1、放行port+10000端口、合理设置cluster-node-timeout。

Redis Cluster 节点握手失败:CLUSTER NODES 看不到其他节点
根本原因通常是 TCP 连通性或 cluster-enabled yes 配置没生效。不是“配置写了就完事”,Redis 启动时若发现 redis.conf 里有语法错误(比如多了一个空格在 cluster-enabled 行末),会静默忽略该配置,仍以单机模式运行。
- 用
redis-cli -p <port> info cluster | grep cluster_enabled</port>确认返回值是cluster_enabled:1,不是0 - 检查防火墙:6379 是客户端端口,但集群通信走的是
port + 10000(如 6379 → 16379),必须放行这个端口,且所有节点间双向可达 -
cluster-node-timeout建议设为 5000–15000,太小会导致网络抖动时频繁误判节点下线
手动触发分片迁移:如何安全地把槽(slot)从 A 节点移到 B 节点
别依赖 redis-trib.rb(已废弃),直接用原生命令。迁移本质是三步原子操作:设置目标节点为 importing、源节点为 migrating、逐个迁移 key。中间任何一步失败,槽状态就会卡住,导致写入失败。
- 先在目标节点执行:
CLUSTER SETSLOT <slot> IMPORTING <source-node-id></source-node-id></slot> - 再在源节点执行:
CLUSTER SETSLOT <slot> MIGRATING <target-node-id></target-node-id></slot> - 最后用
MIGRATE <target-host><target-port> "" 0 <timeout> KEYS <key1><key2> ...</key2></key1></timeout></target-port></target-host>迁移具体 key;注意""是空数据库名,不能省略 - 迁移完成后,两边都执行:
CLUSTER SETSLOT <slot> NODE <target-node-id></target-node-id></slot>,否则槽仍处于 migrating/importing 状态
客户端报错 MOVED 或 ASK:为什么连对了 IP 还跳转?
这不是故障,是 Cluster 的正常重定向机制。MOVED 表示槽已永久归属另一节点(比如完成迁移后),客户端必须更新本地 slot→node 映射表;ASK 是临时重定向,只针对当前命令,说明该槽正处于迁移中,key 可能还在源节点上。
- 用支持 Cluster 的客户端库(如 JedisCluster、redis-py-cluster),它们内置重试和映射刷新逻辑
- 自己写客户端时,遇到
MOVED必须解析响应里的IP:PORT并更新 slot 映射缓存;遇到ASK则临时连接目标节点执行一次,不更新映射 - 别用 pipeline 批量发跨槽命令——Cluster 不允许,会直接报
CROSSSLOT错误
主从切换后写入失败:新主节点还没被集群承认
当主节点宕机,从节点升主后,需要其他主节点投票确认(Gossip 协议),这个过程可能耗时数秒。在此期间,CLUSTER NODES 里能看到新主的 role 是 master,但 slot 分配仍是旧主的 ID,客户端写入会收到 CLUSTERDOWN 或持续 MOVED 到已下线节点。
- 监控
cluster_state:ok和cluster_slots_assigned:16384是否均为预期值,二者缺一不可 - 避免用
redis-cli --cluster check做实时健康判断——它只读取快照,不反映瞬时状态 - 业务侧要有降级逻辑:比如短暂拒绝写请求,或切到本地缓存,等
CLUSTER INFO返回cluster_state:ok再恢复
Slot 迁移的原子性、Gossip 的收敛延迟、客户端对重定向的处理粒度——这三者交织在一起,才是 Cluster 实际运维中最容易掉坑的地方。










