Raft算法总结

来源:互联网 发布:好看的仙侠言情文 知乎 编辑:程序博客网 时间:2024/06/05 19:30

关于论文《In Search of an Understandable Consensus Algorithm (Extended Version)》的个人总结。

主要是Raft算法基础。

Raft包含5个服务器节点,可以容忍2个失效。

通常情况下client--leader--follower,如果client--follower,那么follower重定向给leader。

图 4

关于任期

任期相当于逻辑时钟。

每个节点储存一个当前任期号,在整个时期内单调增长,在服务器通讯时会交换任期号,如果服务器发现自己的比别人的小,则更新任期号。

如果leader或candidate发现自己的term过期,那么他会变成follower。如果节点收到带有过期term的请求,则会拒绝。

Raft算法中服务器通讯视同远程过程调用(RPCs),基本一致性算法只需要两种类型的RPCs,RequestVote和AppendEntries。

关于选举


一开始都是follower,直到它从leader或者candidate接到RPCs。

leader周期性的给所有follower发送心跳包(不包含日志项内容)来维持自己的权威。

如果follower一段时间没收到任何消息,也就是选举超时,就会重新进行选举。

开始选举

follower增加当前任期号并转换成candidate,并行向其他节点发送RequestVote。保持状态直到1.自己赢得选举;2.其他人赢得选举;3.超时。

每个服务器最多对一个任期号投票,先来先服务。要求大多数选票的规则保证了最多一个leader。一旦candidate赢得选举,则立即成为leader,并想其他服务器发送心跳包建立自己的权威并阻止新leader产生。

当选票被瓜分时,每一个candidate都超时,通过增加当前任期号开始新一轮选举。

Raft通过使用随机选举超时时间来确保很少发生瓜分选票的情况。150ms-300ms随机选择,使服务器分散开,在其他超时之前发送心跳包。在选票被瓜分时,会重置随机时间,防止被无限瓜分。

日志复制

客户端每个请求都包含一条被复制状态机执行的指令。

leader把这条指令作为一条新的日志条目附加到日志中,然后并行发给其他服务器,让他们复制这条日志条目,

当这个被安全的复制后,leader会应用这条日志到状态机中,再把执行结果返回给客户端。如果follower出问题,leader会不断发RPCS,直到所有follower储存所有日志条目。

日志由有序序号标记的条目组成。每个条目都包含创建时的任期号(图中框中的数字),和一个状态机需要执行的指令。一个条目当可以安全的被应用到状态机中去的时候,就认为是可以提交了。

leader决定什么时候把日志条目应用到状态机中是安全的,这种日志条目被称为已提交(committed)。在leader将创建的日志条目复制到大多数服务器上时候,日志条目会被提交,同时leader日志中的所有日志条目也都会被提交,包括其他leader创建的条目。

leader跟踪了最大将会被提交的日志项的所以,并且所以只会包含在未来所有附加日志RPCs(包括心跳包),这样服务器会知道leader提交到哪个位置了。一旦follower知道一条日志条目已经被提交,那么他会将这个日志条目应用到本地状态机中,按照日志的顺序。

Raft日志机制维护不同服务器之间的日志一致性,并组成以下特性:

  • 如果在不同的日志中的两个条目拥有相同的索引和任期号,那么他们存储了相同的指令。
  • 如果在不同的日志中的两个条目拥有相同的索引和任期号,那么他们之前的所有日志条目也全部相同。
1.leader最多在一个term内指定的一个日志索引位置创建一条日志条目,同时日志条目在日志中位置不会改变。

2.在leader发送附加日志RPC时候,leader会把新的日志条目紧接着之前的条目索引位置和任期号包含在里面,如果follower在他的日志找不到相同的索引位置和任期号的条目,则拒绝接受新的日志条目。当附加日志RPC返回成功时,leader就知道follower的日志跟自己相同。



当一个领导人成功当选时,跟随者可能是任何情况(a-f)。每一个盒子表示是一个日志条目;里面的数字表示任期号。跟随者可能会缺少一些日志条目(a-b),可能会有一些未被提交的日志条目(c-d),或者两种情况都存在(e-f)。例如,场景 f 可能这样发生,那个服务器在任期 2 的时候是领导人,附加了一些日志条目到自己的日志中,在提交之前就崩溃了;很快这个机器就重启了,在任期 3 重新被选为领导人,并且又增加了一些日志条目到自己的日志中;在这些任期 2 和任期 3 重点日志被提交之前,这个服务器又宕机了,然后的几个任期里一直处于宕机状态。

这种问题通过leader强制follower复制自己日志来解决,follower中冲突的日志会被领导人的日志覆盖。

要使follower的日志和自己一致,leader必须找到最后两者达成一致的地方,然后覆盖那个点之后的所有日志条目。所有这些操作都要在进行附加日志RPCs的一致性检查时完成。leader针对每一个follower维护了一个nextIndex,这表示下一个需要发送给follower的日志条目的索引地址。当一个leader刚获得权力时,它初始化所有nextIndex值为自己的最后一条日志的Index加1,如上图的11,如果follower日志不一致,在下一次附加日志RPC时就会失败,在被拒绝之后,leader会减少nextIndex值重试。最终达成一致,并覆盖之后的日志条目。

安全性限制

通过增加一些限制来完善Raft算法,保证任何leader对于给定的任期号,都拥有了之前任期的所有被提交的日志条目。


选举限制


领导人必须存储已提交的日志条目。Raft使用投票的方式来保证候选人已经包含所有已提交的日志条目,候选人为了得到投票必须联系集群中的大部分节点,这就表示,每一个已提交的日志条目肯定在这些服务器节点中至少一个上,如果候选人日志和大部分节点一样新,那么他一定就包含所有已提交的日志条目。

请求投票RPC中限制:RPC中包含候选人日志信息,投票人会拒绝掉那些日志没有自己新的投票请求。

Raft 通过比较两份日志中最后一条日志条目的索引值和任期号定义谁的日志比较新。如果两份日志最后的条目的任期号不同,那么任期号大的日志更加新。如果两份日志最后的条目任期号相同,那么日志比较长的那个就更加新。

图 8

如图的时间序列展示了为什么领导人无法通过老的日志的任期号来判断其提交状态。在 (a) 中,S1 是领导者,部分的复制了索引位置 2 的日志条目。在 (b) 中,S1 崩溃了,然后 S5 在任期 3 里通过 S3、S4 和自己的选票赢得选举,然后从客户端接收了一条不一样的日志条目放在了索引 2 处。然后到 (c),S5 又崩溃了;S1 重新启动,选举成功,开始复制日志。在这时,来自任期 2 的那条日志已经被复制到了集群中的大多数机器上,但是还没有被提交。如果 S1 在 (d) 中又崩溃了,S5 可以重新被选举成功(通过来自 S2,S3 和 S4 的选票),然后覆盖了他们在索引 2 处的日志。但是,在崩溃之前,如果 S1 在自己的任期里复制了日志条目到大多数机器上,如 (e) 中,然后这个条目就会被提交(S5 就不可能选举成功)。 在这个时候,之前的所有日志就会被正常提交处理。


Raft 通过计算副本数目的方式,使得永远不会提交一个之前任期内的日志条目。通过计算副本数目,只有领导人当前任期里的日志条目可以被提交;一旦当前任期的日志条目以这种方式被提交,那么由于日志匹配特性,之前的日志条目也都会被间接的提交。




0 0
原创粉丝点击