哨兵领导者选举

哨兵领导者选举

为什么需要选举领导者

在 Redis 哨兵架构中,当主节点被判定为”客观下线”后,需要有一个哨兵来负责执行故障转移操作。但如果有多个哨兵同时进行操作,可能会导致混乱。因此,哨兵集群需要先选举出一个”领导者”,由它统一指挥故障转移。

基于 Raft 算法的选举机制

Redis 哨兵的领导者选举借鉴了 Raft 共识算法的核心思想,但做了简化适配。选举过程如下:

1. 发起竞选

当一个哨兵确认主节点进入 ODOWN 状态后,它会先给自己投一票,然后向其他哨兵发送 SENTINEL is-master-down-by-addr 命令,附带当前的纪元(epoch)和它的运行 ID,请求其他哨兵投票给它。

每个哨兵有一个纪元计数器(current_epoch),每次发生主节点状态变化或发起选举时,纪元都会递增。这类似于 Raft 中的 term(任期)。每个纪元内最多只能进行一次成功的选举。

2. 投票规则

其他哨兵收到投票请求后,根据以下规则决定是否投票:

  • 同一个纪元只能投一次票:每个哨兵在每个纪元中只能投出一张赞成票,遵循”先到先得”原则
  • 只投票给第一个请求者:如果哨兵在本纪元还没有投过票,它会投票给第一个向它请求投票的哨兵
  • 必须同意 ODOWN 判定:哨兵只有在自己也认为主节点处于 ODOWN 状态时,才会投票

3. 选举条件

要成为领导者,候选哨兵需要获得超过半数的选票:

所需票数 = (哨兵总数 / 2) + 1

例如,3 个哨兵需要 2 票,5 个哨兵需要 3 票。这个条件保证了在任意一次选举中,最多只能有一个哨兵获得足够的票数。

4. 超时重选

如果没有哨兵在故障转移超时时间内获得足够票数(例如由于网络分区导致投票分散),本次选举失败。哨兵会递增纪元号并重新发起选举。

为什么哨兵数量最好是奇数

由于需要”超过半数”的投票才能当选,哨兵集群的节点数最好是奇数:

总哨兵数 所需票数 容错数
3 2 1
4 3 1
5 3 2
6 4 2

可以看出,4 个哨兵和 3 个哨兵的容错能力一样(都只能容忍 1 个宕机),但奇数可以避免不必要的集群规模浪费。

与 Raft 算法的区别

Redis 哨兵的选举和标准 Raft 有几个关键差异:

  1. 没有日志复制:哨兵选举不需要复制日志,只负责选举执行人
  2. 简化的任期机制:纪元(epoch)只用于防止同一时段多次选举
  3. 无心跳维持:哨兵之间通过常规的 PING 通信,而不是专门的心跳机制
  4. 非强一致性:哨兵的共识目标是”就谁执行故障转移达成一致”,而不是维护一个状态机

面试要点

  • 哨兵选举使用Raft 思想不是完整 Raft 实现
  • 需要超过半数(N/2+1) 的选票才能当选
  • 每个纪元只能投一票,先到先得
  • 奇数个哨兵更合理(容错能力与偶数相同但成本更低)
  • 选举超时会递增纪元并重新选举

总结

哨兵领导者选举机制确保了在分布式环境下,故障转移操作由唯一一个哨兵协调执行,避免了多个哨兵同时操作导致的数据不一致问题。这是 Redis 高可用架构中关键的分布式共识环节。

© 版权声明
THE END
喜欢就支持一下吧
点赞9 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容