分布式数据一致性算法之Raft算法

Posted IT路人乙

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分布式数据一致性算法之Raft算法相关的知识,希望对你有一定的参考价值。

1 Raft基础

Raft云包含多台服务器,5是经典的数字,它允许系统默认两台服务器宕机。在任何给定的时间段内,每台服务器均处于三个状态中的一种: leaderfollowercandidate。正常运行的情况下,Raft云有一个leader,其他的服务器都是follower。Follower是不会主动的给leader发请求的,它只会响应leader的请求。Leader处理所有客户端请求(假如一个客户端联系follower,这个follower会重定向它到leader)。第三种状态,candidate,被用来选举一个新的leader。

Raft把时间划分为人任意长度的任期。任期有一个连续的整型任期号。每次任期由一次选举开始,每次选举会从一个或多个candidate中选举出一个leader。假如一个candidate赢得了选举,这个任期它会是leader。若任期内候所有candidate得到的选票相同,则这个任期没有leader;然后一个伴随着新选举的任期又重新开始。Raft确保一个制定的任期内至多有一个leader。三种状态转换如下图

Followers仅仅响应来自其他服务器的请求。假如一个follower没有接收到信息,它会变成candidate,并初始化选举。一个接受到到多数投票的candidate变成一个新leader。Leader一直运行知道宕机。

时间划分如下图所示

时间被划分为多个任期,每个任期伴随着选举开始。一次选举成功之后,一个唯一的leader管理云知道任期结束。加入选举失败,这个任期以没有leader结束。

每个服务器都会保存当前任期号。在服务器进行通讯的时候,任期号会被互相交换。加入一个服务器的任期号比其他服务器的小,然后它会更新自己维护的任期号为更大的值。假如一个candidate或leader发现自己的任期到期了,它会立即恢复到follower状态。

Raft服务之间通讯采用远程过程调用(RPCs),一致性算法仅仅要求两种类型的RPCs。RequestVote RPCs选举期间被candicate初始化,AppendEntries RPCs被leader初始化来复制日志实体和提供一种心跳形式。假如服务器没有及时的接收到响应,他们会重试RPCs。

2 Leader选举

Raft使用心跳机制来出发选举。当服务器启动,它被初始化为Followers。服务器会一直维护为follower状态直到它接收到了Leader或者candidate的RPCs。Leaders为了维护自己的权限,会周期性地发送心跳到所有的followers。

选举开始之前,一个follower增加它自己的当前任期号,同时转台状态为candidate状态。然后,它会投票给自己,同时发送RequestVote RPCs给所有云成员中的其他服务器。一个candidate会一直保存当前状态,直到下面的三件事情发生,

  • a) 它赢得选举

  • b) 另一台服务器确立为leader

  • c) 选举期间,没有选举出leader

假如一个candidate在同一个任期内,接收到了整个云中的大多数服务器的投票,它就赢得这轮选举。每台服务器在一个制定的任期内基于 先到先服务 原则至多能投票给一个candidate。多数规则确保一轮常规的任期内至多有一个candidate能赢得选举。一旦一个candidate赢得了选举,它就变成了leader。然后,它会发送心跳给其他的服务器来确立自己的权限,且阻止新一轮的选举。

在等待投票的时候,一个candidate可能接收到来自其他服务器申明自己成为leader的AppendEntries RPCs。假如这个leader的任期号至少和这个candidate的当前任期号一样大,这个candidate识别这个leader为合法的,同时转换自己为follower状态。假如这次RPC的任期号比candidate的当前任期号小,这个candidate拒绝这次RPC,并保持candidate状态不变。

第三种可能是一个candidate要么赢得选举要么失去选举。假如一些follows同时变为candidate,投票可能被均分导致没有candidate获得大多数投票。当这种情况发生,所有的candidate会超时,同时开始新一轮选举通过增加自己的任期和初始化下一轮RequestVote RPCs。

Raft使用随机选举超时来保证所有candidate同时获取相同选票的可能性极低,并且当这种情况发生时能迅速的被解决。为了阻止这种情况发生,选举超时时间应该选择一个固定的时间间隔(如 150-300ms)。每个candidate在选举开始重新开始它自己的随机选举超时,同时在开始下一轮选举之前它等待超时来过期。

3 日志复制

一旦leader被选举,它就开始服务客户端请求。每个客户端请求包含一个被复制状态机执行的命令。leader把这条命令当做一个新的条目追加到自己的日志中,然后并行发起一个AppendEntries RPCs到每台服务器来复制这个条目。当这个条目已经被安全的复制,leader把这个条目应用于自己的状态机,同时返回给客户端执行结果。假如followers宕机、运行缓慢或者网络丢包,leader会发起重试知道成功为止。

在Raft中,leader通过强制follower复制自己的日志来处理数据不一致。这就意味着follower的冲突日志条目会被覆盖。为了让follower保持日志数据一致,leader必须在两个日志约定的地方找到最新的日志条目,删除follower那个点之后的所有的条目,然后给follower发送那个点之后的所有的leader的日志。假如follower的日志和leader的不一致,下一次AppendEntries RPC AppendEntries一致性检查会失败。拒绝之后,leader减少nextIndex和重试AppendEntries RPC。nextIndex最终会达到leader和follower日志互相匹配的一个点。当这发生,AppendEntries会成功,移除follower中冲突的条目,追加leader的条目到自己本地日志。一旦AppendEntries成功,follower的日志和leader的日志就会保持一致。

这种协议能够通过减少被拒绝的AppendEntries RPCs的数量来优化。

4 安全性

上面的章节描述了Raft怎样选举leader和复制日志条目。然后,这种机制到目前为止还不能够完全地保证每个状态机相同的顺序精确地执行相同的命令。例如,当leader提交几条日志条目的时候,follower可能不可用,然后它可能被选举为leader和使用新的日志覆盖这些日志条目;结果,不同的状态机可能执行不同的命令序列。

这部分通过在可能被选举为leader的服务器上增加一个约束来完成Raft算法。这个约束确保在任何指定任期内,leader包含所有的之前任期内被提交的所有日志条目。

4.1 选举约束

在任何基于leader的一致性算法中,leader事实上必须存储所有的已提交的日志条目。RequestVote RPC实现这种约束:这个RPC包含candidate的日志的信息;假如投票者自己的日志的up-to-data比candidate的多,投票者拒绝它自己的投票。

Raft通过比较下标和日志中最近条目的任期来决定两个日志中哪一个的up-to-date更多。假如日志的最近条目的任期不同,有最近条目的日志有更多的up-to-date。假如日志以相同的任期结尾,无论日志的长短up-to-date是更多的。

5 Follower和Candidate宕机

直到这之前,我们一直聚焦在leader失败。Follower和candidate宕机比leader宕机处理更简单。两种情况使用相同的方法处理。假如follower或candidate宕机,发送给它的RequestVote和AppendEntries RPC会失败。Raft通过无限期地重试来处理这种失败。假如宕机的服务器重启了,RPC会成功完成。假如服务器在完成RPC之后响应之前宕机,重启之后,它会接受到相同的RPC。Raft RPC是冥等的,因此这不会造成影响。例如,假如一个follower接收到包含它自己日志中已经存在的日志条目的AppendEntries请求,在新的请求中它忽略这些日志条目。

6 定时和可用性

对于Raft,我们的需求之一就是安全性不依赖与时间:系统不应该仅仅因为某些事件比预期发生的早或者晚而产生错误的结果。然后,可用性应该不可避免的依赖于时间。例如,介于服务器宕机之间,假如消息交换比物理时间花费更长,candidate不会保持做够长的时间来赢得选举;没有稳定的leader,Raft不能往前推进。

Leader选举是Raft时间最关键的地方的一方面。系统满足下面的时间范围之内,Raft会选举和维护一个稳定的leader,

broadcastTime << electionTimeout << MTBF

在这个不平均的broadcastTime是平均时间之内,一台服务器并行发送RPCs到云中的启发服务器和接收他们的响应;electionTimeout是选举超时时间;MTBF是单台服务器失败之间的平均时间。广播时间比选举超时时间小一个量级以至于leader能够向followers可靠地发送心跳; 选举超时时间会随机的方式获取,这种不平均会使均摊投票变得不可能。选举超时时间应该比MTBF量级小一点以至于系统能够稳定的运行。

当我们选择选举超时时间,广播时间和MTBF是系统的属性。Raft的RPCs需要接受者持久化信息到稳定的存储,因此广播时间可能是0.5毫秒到20毫秒之间,这依赖于存储技术。选举超时时间可能是10毫秒到500毫秒之间。服务的MTBFs可能是容易满足时间要求的几个月或者更多。

以上是关于分布式数据一致性算法之Raft算法的主要内容,如果未能解决你的问题,请参考以下文章

分布式一致性之raft算法

分布式一致性之raft算法

一致性协议Raft算法

编程实践Raft 算法的原理 & go代码实例

分布式一致性算法——Paxos 和 Raft 算法

Raft协议之领导者选举