1 小红维护领导*威
在上篇文章raft协议-看图说话-(一)中,小红成功当选了领导者。
小蓝和小黄虽然在之前的流程中承认了小红的领导者地位,但相互之间的通信是不可靠的,所以小黄和小蓝都有超时机制,如果超过一定时间没收到小红的消息,会重新发起选举流程。
针对这种情况,小红会定时向小蓝和小黄发送MsgHeartbeat信息,用来阻止小蓝和小黄启动选举流程。
小红和小蓝收到信息后,会更新自身超时设置归0,然后返回MsgHeartbeatResp消息
2 特殊场景-小红遇到比自身term大的MsgApp怎么办
case1 小红(id=1,term=1,state=follower,leader = 2)收到了来自小蓝(id=3)message(type=MsgApp,term=2)
case2 小红(id=1,term=1,state=candidate)收到了来自小蓝(id=3)message(type=MsgApp,term=2)
case3 小红(id=1,term=1,state=leader)收到了来自小蓝(id=3)message(type=MsgApp,term=2)
- 小红发现自己的term 1 小于 message中的term 2,会转变自己身份为follower身份,同时更新自己的term为2,leader为3(小蓝),最后回复MegAppResp消息
3 特殊场景-选举超时怎么办
case1 小红(id=1,term=1)当前是follower或者candidate角色,当前随机的选举超时时间(randomizedElectionTimeout)为19秒,当过了19秒,小红依然没收到任何消息,这时候的处理流程如下:
- 小红自身发起MsgHup消息,进行新一轮的选举流程,状态变为candidate
- 自身term由1变为2,给自己投票(votes_[1] = true)
- 向小黄(id=2)、小蓝(id=3)发送MsgVote消息,让他们给自己投票
4 特殊场景-请求投票被拒绝怎么办
有这样一种情形,当小红成功变为candidate后,会向小伙伴们(小黄、小蓝、小绿、小紫。。。)发送投票请求MsgApp,有的人会同意,同的人会拒绝,遇到这种情形,小红该如何处理
case1 当前集群里只有小红一人,id=1,term =1
- 前面说过,小红成为candidate时,会给自己投一票,然后小红发现自己的投票数已经等于当前集群的大多数(集群人数/2 + 1),成为leader
case2 当前集群有3人,小红为candidate,小黄和小蓝投了赞成票
- 假设小红先收到小黄(id=2)的投票,这时小红保存的投票状态为(votes_[1] = true,votes_[2] = true),已经满足了半数+1(即2)的要求,状态直接成为leader
- 后续小红再收到小蓝(id=3)的投票,这时小红已经是leader了,所以不再响应小蓝的请求
case3 当前集群有3人,小红为candidate,小黄投了赞成票,小蓝无响应
- case3与case2一样,由于小黄的投票已经让小红的状态变为了leader,小蓝投赞成或者反对,或者不投票都不再影响小红的状态
case4 当前集群有5人,小红为candidate,小黄和小蓝投了赞成票,其他人或者拒绝或者没有投票
- 假设小红(id=1)先收到小黄(id=2)的赞成票,投票状态为(votes_[1] = true,votes_[2] = true)(即2人),5个人的半数+1为3人,还不满足条件,继续维持现在的状态
- 然后小红收到了小蓝(id=3)的赞成票,状态为(votes_[1] = true,votes_[2] = true,votes_[3] = true),已经有3人,满足半数条件,小红成为leader
- 无论其他人投任何票,都不会再影响小红的状态。
case 5 当前集群有3人,小黄和小蓝都投了拒绝票
- 小红先收到小黄的拒绝请求,状态为(votes_[1] = true,votes_[2] = false),已投票人中拒绝的人有1个,集群半数+1为2,1 < 2,所以维持小红的candidate状态
- 小红继续收到小蓝的拒绝请求,状态为(votes_[1] = true,votes_[2] = false,votes_[3] = false),已投票中拒绝的人变为2个,等于集群的半数+1(2),小红状态直接变为follower
case5 当前集群有5人,其中小红是candidate,除了小红外,(1)有一个人投赞成,其他人没有投票。(2)有两人投反对票,其他人没有投票。(3)没有人投票
- 由于赞成票和反对票都没有满足半数+1要求(3人),所以小红维持candidate状态