Kaito
2021-09-27
1、Redis 为了实现故障自动切换,引入了一个外部「观察者」检测实例的状态,这个观察者就是「哨兵」 2、但一个哨兵检测实例,有可能因为网络原因导致「误判」,所以需要「多个」哨兵共同判定 3、多个哨兵共同判定出实例故障后(主观下线、客观下线),会进入故障切换流程,切换时需要「选举」出一个哨兵「领导者」进行操作 4、这个选举的过程,就是「分布式共识」,即多个哨兵通过「投票」选举出一个都认可的实例当领导者,由这个领导者发起切换,这个选举使用的算法是 Raft 算法 5、严格来说,Raft 算法的核心流程是这样的: 1) 集群正常情况下,Leader 会持续给 Follower 发心跳消息,维护 Leader 地位 2) 如果 Follower 一段时间内收不到 Leader 心跳消息,则变为 Candidate 发起选举 3) Candidate 先给自己投一票,然后向其它节点发送投票请求 4) Candidate 收到超过半数确认票,则提升为新的 Leader,新 Leader 给其它 Follower 发心跳消息,维护新的 Leader 地位 5) Candidate 投票期间,收到了 Leader 心跳消息,则自动变为 Follower 6) 投票结束后,没有超过半数确认票的实例,选举失败,会再次发起选举 6、但哨兵的选举没有按照严格按照 Raft 实现,因为多个哨兵之间是「对等」关系,没有 Leader 和 Follower 角色,只有当 Redis 实例发生故障时,哨兵才选举领导者进行切换,选举 Leader 的过程是按照 Raft 算法步骤 3-6 实现的 课后题:哨兵实例执行的周期性函数 sentinelTimer 的最后,修改 server.hz 的目的是什么? server.hz 表示执行定时任务函数 serverCron 的频率,哨兵在最后修改 server.hz 增加一个随机值,是为了避免多个哨兵以「相同频率」执行,引发每个哨兵同时发起选举,进而导致没有一个哨兵能拿到多数投票,领导者选举失败的问题。适当打散执行频率,可以有效降低选举失败的概率。
展开
共 3 条评论
30
曾轼麟
2021-09-26
首先回答老师的问题:调整 server.hz 的目的是什么? 答:为了使每个哨兵与其他哨兵不同步,通过这种方式避免由于几个哨兵同时启动,导致无法投出leader的情况,类似脑裂,因为每个独立的哨兵都在启动同一时刻开始发起投票,然后一轮一轮下去都没法投出leader。 总结: 本篇文章老师主要介绍了,redis在Raft协议上的实现,Redis本身不是完全按照Raft协议实现的,其中最主要的原因就是每个哨兵节点都是对等的,而Raft协议逻辑主要如下: 1、在稳定系统中只有 Leader 和 Follower 两种节点,并且 Leader 会向 Follower 发送心跳消息。 2、如果某个Follower 在一定时间没收到Leader的心跳,那么他会变成Candidate 并且可以发起选举。 3、Candidate 会先投自己一票,然后等待其他follower的投票。 4、如果投票结果能选出Leader则新的Leader上位,否则再进行一轮选举。 而Redis是哨兵是对等的,所以每个哨兵都会监听当前Redis的Leader的心跳,当前Redis的Leader如果发生异常,哨兵会开始发起选举直到第一个Leader被选举出来并通知每个哨兵。 TILT模式: 由于哨兵模式是对等的,那么必然会出现一情况导致哨兵节点不可信任,比如:当前系统时间被修改,当前哨兵节点硬件资源繁忙,当前网络稳定状态差等等。当这些情况发生的时候哨兵就有可能进入TILT模式,在这种模式下哨兵是正常运行工作,但是它的投票是不被信任的。 拓展: 其实本篇文章主要的核心就是分布式共识问题,针对分布式共识有一个很经典的问题就是【拜占庭将军问题】 ,而大多数分布式共识最终目的都是处理这个问题的场景,由此衍生出了各种共识算法如:Raft算法,Paxos算法,ZAB算法,PBFT算法等等。 而ZAB算法就是Zookeeper核心指导算法,ZAB与Raft不同的是,ZAB是通过竞争手里资源,比如leader底下有几个ack,最多ack的那个竞选成功,所以相比Raft可以改造为平等模型的互相投票再出leader,ZAB中leader的概念稍微重要一点(我个人理解ZAB应该比较容易脑裂,不知道理解是否到位)。
展开
3
可怜大灰狼
2021-09-26
回答问题:为了防止哨兵们总是按照一个频率来竞选leader,从而导致重复多轮选举