raft论文(二)

Leader election

选举触发

当一个Follower一段时间内没有收到来自于Leader或者Candidate的消息时,该Follower会转化成Candidate进行一次选举:
election timeout
触发选举时,该Candidate做的事情:

  1. currentTerm++(自身任期号+1);
  2. votedFor = me(给自己投票);
  3. resetElectTimer (重置定时器);
  4. 给除自己的所有server发送RequestVote请求;

这里会涉及到的超时时间有:

  1. base_election_timeout + rand_time
    加上一个随机偏移,是为了防止多个Follower同时Candidate导致瓜分选票的概率。因此选举超时间可能是在一个区间(例如150 ~ 300ms)
  2. 发送RPC会有一个RPCTimeout;

论文在后续章节讨论了对时间性的要求:

消息广播时间 << 选举超时时间 << 系统平均故障时间

RPCs需要对方将信息持久化到存储中,广播时间大约是0.5ms ~ 20ms(取决于存储的技术),因此选举超时时间可能在10ms ~ 500ms之间。

等待选举结果

在并行发送完RequestVote RPC后,会有三种结果

赢得选举

Candidate发送的RequestVote包含了自身的term,集群中每个server针对这个term最多只会投出一张选票,按照先来先得的原则;
额外的限制: RequestVote RPC中包含了Candidate的日志信息,投票人会拒绝那些日志没有自己新的RequestVote

接受者如果发现RequestVote的term比自己小的话(term < currentTerm),会投反对票;

接受者在这个term还没有投过票的话(votedFor = nil),就会赞成票;

Candidate如果赢得了大多数的选票的话(Election Safety),就会当选Leader,同时向其他的server发送心跳来阻止其他节点的选举触发。

收到其他节点的AppendEntry

等待期间,Candidate可能会收到其他节点发送过来的AppendEntry,该AppendEntry声明了该节点为Leader。
此时如果:
AppendEntry.term >= currentTerm的话,承认这个Leader的地位,自己转化为Follower
AppendEntry.term < currentTerm的话,返回false,拒绝这次RPC;

无人当选

这种情况可能发生在选票瓜分的情况下,此时每个Candidate都会再次election timeout,触发新一次的选举。(如上所说,增加了随机时间偏移)

simple example

example1

三节点初始状态:
server1
election timeout = 150ms
server2
election timeout = 150ms
server3
election timeout = 200ms
三者都是Follower;
150ms后:

server1超时,server1.currentTerm = 1, server1.votedFor = server1, 
server1.elect_timeout rand update to 100s;

server2超时,server2.currentTerm = 1, server2.votedFor = server2, 
server2.elect_timeout rand update to 200s

假设server3先收到server1的RequestVote, 此时server3.currentTerm = 0, 投票给server1;
紧接着收到了server2的RequestVote,此时因为Term=1任期已经投过票,因此拒绝投票。

最终server1当选Leader。

example2

五节点初始状态:
server1
election timeout = 150ms
server2
election timeout = 150ms
server3
election timeout = 150ms
server4
election timeout = 200ms
server5
election timeout = 300ms

150ms后:

server1超时,server1.currentTerm = 1, server1.votedFor = server1, 
server1.elect_timeout rand update to 100s;

server2超时,server2.currentTerm = 1, server2.votedFor = server2, 
server2.elect_timeout rand update to 200s

server3超时,server3.currentTerm = 1, server3.votedFor = server3, 
server3.elect_timeout rand update to 300s

假设server4投票给server1;server5投票给server2

此时选票被瓜分,无Leader当选。

再经历100s后:

server1超时,server1.currentTerm = 2, server1.votedFor = server1, 
此时其他的server都没有超时,因此都会投票server1发送的term=2的RequestVote。
最终,经过两轮election timeout,server1当选。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值