Raft--Leader选举(Leader Election)

Raft通过心跳机制触发Leader Election。所有Server的初始状态(State)为Follower,只要一直能收到来自Leader或Candidate有效的RPC,就一直保持Follower的角色。其状态转换过程如图所示:
Raft各个状态的转换

正常情况

当Leader还健在时:
Leader会周期性给所有follower发送心跳(heartbeat)告诉大家自己还健在,大家听我的就好。

触发选举

当Leader挂掉时:

当Follower一段时间(Electtion Timeout)没收到Leader的心跳时,认为Leader已经挂了,那我要当新的Leader,所以发起选举(election)。

Follower发起选举时:

  1. 将自己当前的term加一,表示进入下一个term;
  2. 将自己的状态转换成candidate;
  3. 为自己投票(vote),并同时向集群中的所有服务器发起RequestVote的RPC。

选举结束条件

Candidate一直保持自己的状态,直到以下三种情况任意满足其一:

  1. 它赢得了选举
    若当前term中收到集群中超过半数(majority)的server投票给自己,则说明该Candidate获胜。该规则确保了每个term只有最多一个Candidate能赢得选举,成为Leader。
    当该Candidate赢得了选举,则将自己的状态转换成Leader,然后向所有其他的server发送心跳,告诉大家:“我已经是Leader啦,后面的Candidate没你们事儿了,乖乖当Follower吧!”(建立自己的权威),同时也能阻止掉新Leader Election的发起。
    关于投票的细节后面还会说明。
  2. 另一个server已经当上了Leader
    当等待其他server给自己投票时,Candidate可能会受到其他server的AppendEntries的RPC。此时Candidate会比较自己和其他server发过来的RPC中的term,若自己的term比较小,说明它比自己牛,那自己退出,把自己的状态从Candidate变回Follower。如果自己的term比它大,那就直接拒绝它发过来的请求(不如我还想当我老大?做梦!)。
  3. 选举超时(一段时间后没人赢得选举)
    当有多个Follower同时变成了Candidate,则大家非常有可能都不能获得过半的票数(first-come-first-serve的投票规则),那这个时候大家都不能成为Leader,于是大家就会超时(Election Timeout)并发起新的选举:term加一并发起新一轮的RequestVote RPC。
    但如果每次都是大家一起发出RequestVote,那是不是每次都选不出新Leader呢?很有可能。所以我们需要一个额外的机制保证大家不会同时发起选举。很容易想到,我们可以控制每次Election Timeout的时间。Raft的机制是,随机化每次Election的时间(往往在一个区间内取值),这样首先就保证每个server发现Leader挂掉的时间不一样,另外,就算发生了平票,重新发起选举的时间也不一样,那么大家都会投票给先发起选举且满足条件的那个Candidate。

投票规则

投票是一个first-come-first-serve的机制,即谁先找我我就给谁投票。
我们想确保新的Leader在赢得选举的时候有所有已经提交(commit)的entry,因为这样就不需要向新Leader同步它不知道的已经同步信息。这就意味着所有entry只会向一个方向传递:从Leader到Follower。并且Leader也不会重写log里面已经存在的entry。
因此,当Candidate的log包含了所有已经提交的entry时,它才能赢得选举。为实现这点,Candidate需要获得集群中的大多数(超过集群server个数的一半)server的确认,当Candidate的log至少是“最新的”(up-to-date)时,则说明它的log中有所有的已经提交的entry。
因此,当投票者发现自己的log比Candidate的都新时,就会拒绝给该Candidate投票。
“最新的”(up-to-date) 定义:当Candidate发起RequestVote的RPC时,会包括上个log entry的index和term信息。投票者比较自己和Candidate的index和term,当term不同时,term越高则为越新;当term相同时,index越高则为越新。(lastTerm_v > lastTerm_c) || (lastTerm_v > lastTerm_c) && (lastIndex_v > lastIndex_c)

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值