Raft实现报告(八)
Raft使用投票操作,防止不包含全部日志条目的候选人成为leader。candidate必须跟集群中大多数的服务器沟通过,为了成功变成leader,日志条目必须出现在这些集群服务器之一中,如果candidate的日志,至少至少跟其中任何server的日志一样为最新(up to date)那证明该candidate至少包含了所有的已提交条目。RequestVote RPC实现了这则限制,RPC包含了candidate的日志信息,还包含投票者的拒绝响应,可能其他投票者投给了自己因为自己的log比起candidate更加的新。
(这里留下一个疑问,如果一个followerA出发了leader选举,他开始发送RequestVoteRPC,然后其他的followerB发现了自己的log更加的新,那么该followerB会变成candidate吗?)
如何确定谁的log更加新
Raft通过对比日志中term的索引和term中最后一条日志条目的索引,日志中最后一条如果term不相同,那么term靠后的为最新,如果日志中最后一条有相同的term,那么谁的日志长,该日志为最新。
难得有个好例子
上图会解释为什么leader不能通过旧term中的日志条目来确定提交行为。
- (a):S1是一个leader,已经将新的日志条目2,复制给了少部分server,S2
- (b):S1宕机,S5从term3开始被选举为leader,S5的票来自S3,S4和他自己,然后收到了一条不一样的日志条目在日志索引的2号位置。
- (c):如果S5宕机;S1重启,又被选为了leader,继续复制日志。这时,S1先前保存的在term2时产生的日志条目就会给大家同步,但是没有确认提交。
- (d):因为在d这种时候,如果S1宕机了,先前S5在选举为leader的时候开始同步自己在term3的日志条目,且因为要保持一致性,需要一致性检查,leader会强行复制自己的最新日志条目。
- (e):如果S1能在自己宕机之前完成日志复制,那么该条目(所有在term4产生的log)就会提交(S5无法完成选举),那么先前term2时刻的所有条目也会成功提交。
问题一:S5为什么会收到S3和S4的投票?
因为在follower在投票的时候会检查自己log中条目的term,S1,S2发现S5带来的日志信息,与自己的不一致,就会否决投票。
所有的RPC请求都带有term信息,所以即便是S1宕机了,也能感知到下一term是什么。