哨兵leader选举在主节点被客观下线(odown)时触发,需至少quorum个哨兵先主观下线(sdown)并互相确认;首个判定odown的哨兵自荐为candidate,通过raft协议三阶段拉票,获≥quorum且过半票数即当选。

哨兵怎么选出“总指挥”:Leader选举触发条件
只有当主节点被判定为 客观下线(ODOWN) 时,哨兵集群才会启动 Leader 选举。这不是一发现主节点连不上就立刻开选,而是必须满足两个硬性条件:
- 至少有
quorum个哨兵(配置项sentinel monitor mymaster 127.0.0.1 6379 <quorum></quorum>中的数值)各自独立判定主节点为主观下线(SDOWN); - 这些哨兵通过
SENTINEL is-master-down-by-addr命令互相确认后,达成共识,将主节点状态升级为ODOWN。
一旦进入 ODOWN 状态,**第一个完成该判定的哨兵**会立即把自己设为 Candidate,并尝试拉票——它不会等别人先动。
选举过程严格遵循 Raft 协议三阶段
Redis 哨兵的 Leader 选举不是投票制,而是基于 Raft 的“任期(epoch)+ 多数派确认”机制。整个流程分三步走,每步都带超时控制:
-
自荐与拉票:Candidate 向所有其他哨兵发送
SENTINEL is-master-down-by-addr请求,附带自己的runid和当前epoch(由sentinel.current_epoch维护),并给自己投一票; -
投票响应:其他哨兵收到请求后,只会在满足以下全部条件时投赞成票:
epoch是最新、自己没给同轮其他 Candidate 投过票、且主节点确实处于 ODOWN 状态; -
胜出判定:Candidate 收到的赞成票数 ≥
quorum且 > 总哨兵数一半(即多数派),才算当选 Leader;否则本轮失败,重置状态,等待下一轮选举超时后重试。
注意:quorum 是故障判定阈值,而 Leader 当选所需的票数是“max(quorum, N/2 + 1)”——这意味着哪怕你配了 quorum 2,但部署了 5 个哨兵,Leader 仍需至少 3 票才能上位。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
为什么选举失败常见?几个典型卡点
实际运维中,Leader 选举卡住或反复失败,往往不是算法问题,而是配置或网络细节没对齐:
-
down-after-milliseconds值设得太小(比如 1000ms),导致网络抖动就触发 SDOWN,频繁进入选举流程,反而加剧不一致; - 哨兵之间时间不同步(
clock skew > 5s),造成epoch比较失效或心跳超时误判; - 防火墙或安全组未放开哨兵间通信端口(默认
26379),is-master-down-by-addr请求发不出或收不到响应; - 哨兵配置里
sentinel monitor的主节点地址写的是localhost或内网不可达 IP,导致彼此发现失败,无法组成有效集群。
选举本身不涉及 Redis 数据节点,只在哨兵进程间进行;但一旦失败,整个故障转移就会停滞——此时查 redis-cli -p 26379 sentinel master mymaster 会看到 failover-state 停在 wait_start,而不是推进到 select_slave 阶段。
选举成功后,Leader 并不直接改配置
当选 Leader 只是拿到了“发号施令权”,它接下来要做的第一件事,是调用 sentinelFailoverStateMachine 进入状态机流程。真正执行新主选举(即从 Slave 中挑接班人)是后续步骤,和 Leader 选举完全解耦——前者靠 Raft 达成哨兵间共识,后者靠 slave-priority、replica_offset、runid 三级排序,两者逻辑隔离、互不影响。
最容易被忽略的一点是:current_epoch 是全局递增的,每次选举失败都会自增;如果某哨兵长期掉线再上线,它的 epoch 落后太多,会被其他哨兵直接拒绝投票——这不是 bug,而是 Raft 保证日志连续性和防止旧 Leader “幽灵复活” 的关键设计。










