Redis哨兵故障转移严格分两阶段:先由≥quorum哨兵投票选出Leader,再由Leader按健康检查、优先级、offset、run_id四层规则筛选新主;原主恢复后自动降为从节点。

哨兵故障转移不是“选一个从节点顶上”,而是两阶段选举
Redis 哨兵的 failover 不是随机挑、也不是按配置文件顺序选,它严格分两个串行阶段:先由哨兵集群选出一个 Leader Sentinel(领头哨兵),再由这个 Leader 单独执行新主节点筛选。跳过这个分工,比如直接改 sentinel.conf 或手动发 SENTINEL failover,容易触发脑裂或选错节点。
第一阶段(Leader 选举)靠类 Raft 投票:每个哨兵向其他哨兵发 is-master-down-by-addr 请求,带自己 run_id 和配置纪元(epoch)。投票规则很明确:
– 只投给配置纪元 ≥ 自己当前纪元的请求
– 同一纪元内只投第一次收到的请求
– 最终得票 ≥ quorum(且满足多数派条件)者胜出
第二阶段(新主筛选)由 Leader 执行,它不看配置文件顺序,而是一套四层流水线过滤:
- 健康检查:必须
INFO replication中master_link_status:up,且connected_slaves > 0 - 优先级排序:按
replica-priority升序(值越小越靠前),0表示放弃参选 - 复制偏移量比对:在优先级相近的节点中,选
replica-offset最大的那个(数据最全) - 最后决胜:offset 相同时,按
run_id字典序选最小的(稳定可预测)
replica-priority 配错或没生效,是选举失败最常见原因
replica-priority 是 Redis 5.0+ 的正式配置名,旧版叫 slave-priority;但写错成后者不会报错,哨兵直接忽略——它压根读不到这个字段。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
这个值必须设在 从节点自己的 redis.conf 里,不是哨兵的 sentinel.conf。常见错误包括:
- 路径写错:比如改了
/etc/redis/6379.conf,但实际运行的是/etc/redis/6380.conf - 语法错误:写成
replica-priority = 10或replica-priority "10",正确是replica-priority 10(无等号、无引号) - 没验证:改完没执行
redis-cli -p 6380 CONFIG GET replica-priority确认返回"10" - 漏密码:主节点有
requirepass,但从节点没配masterauth,导致复制中断,哨兵会直接过滤该节点
为什么设了高优先级还是没当选?检查这三点
即使 A 节点 replica-priority 设为 10,B 设为 100,A 仍可能落选——因为优先级只是第一关,后面还有硬性门槛:
-
健康状态不过关:用
redis-cli -p 26379 SENTINEL slaves mymaster查输出里的flags字段,含s_down或o_down就会被跳过 -
复制严重滞后:如果 A 的
replica-offset比 B 小几百 MB,哨兵会直接淘汰 A;优先级只在 offset 差距小于几 KB 时才起作用 - 主观下线未解除:哨兵自己认为该从节点不可用(比如网络抖动导致连续 ping 失败),哪怕你 telnet 得通,它也不会放进候选池
旧主恢复后自动降级,但前提是没脑裂
原主节点重启后,哨兵会自动让它执行 SLAVEOF <new-master-ip> <port>,变成新主的从节点。但这有个前提:旧主在宕机期间没有接受任何写请求。
如果旧主因网络分区被隔离,又继续收写(比如客户端直连没走哨兵),它和新主就会产生不一致数据。此时哨兵不会强制降级,而是保持双主状态——这就是脑裂。避免方式只有两个:
– 设置合理的 down-after-milliseconds(不能太短)
– 在客户端侧启用 sentinel.get_master_address_by_name() 动态获取主地址,别硬编码

















