第3部分:Raft论文的翻译-共识:理论与实践的桥梁(基础Raft算法)

本章介绍Raft算法。我们试图让Raft算法更容易理解。第一部分描述了我们的理解性设计方法。下一部分描述Raft算法本身,并包括我们的设计选择,以便于理解。

我们在设计Raft算法时有几个目标:必须为系统构建提供完整实用的算法基础,从而显著减少开发者所需的设计工作;它必须在所有条件下都是安全的,并且在典型操作条件下可用;对于常规操作,它必须是高效的。但是我们最重要的目标和最困难的挑战是Raft算法的可理解性。该算法必须易于被大量读者理解。此外,开发者必须能够直观地指导算法的工程化开发,让系统构建者在面临问题时能够意识到不可避免的算法扩展。

在筏形基础的设计中,我们不得不面对各种可行方法的选择。在这些情况下,我们基于可理解性评估备选方案:评估解释每个备选方案的难度(例如,其状态空间有多复杂,是否有复杂的隐藏内容/信息?)并尝试评估读者完全理解Raft算法及其隐含信息的难易程度。

我们意识到这种分析非常主观。尽管如此,我们仍然使用两种可行的技术来评估它。首先是问题解构(把一个大问题分解成几个小问题)。例如,我们将Raft算法分为三个部分:领导者选举、日志复制和安全性。第二种方法是通过减少要考虑的状态来减少状态机的状态空间,使* * *识别算法尽可能有序,消除不确定性。具体来说,Raft算法不允许日志有空洞(空洞是指一个条目中没有对应的内容,但是后面的条目有内容,这是Paxos算法的一个缺点),Raft算法限制了日志不一致的可能性(通过对领导者选举的限制和只有领导者是主要数据源的限制,保证了跟随者之间不会相互传输日志内容,只要和领导者一致,减少了各个服务器上日志的不一致)。虽然我们尽量避免算法中的不确定性,但有时也通过这种不确定性来增强算法的可理解性(这是以可理解性为首要目标的表现)。比如随机法引入了不确定性,但是可以缩减状态空间(通过随机法,我们可以避免处理系统中可能出现的各种问题,比如当领袖当选时,不同的候选人通过加时发起下一轮选举,从而避免。

Raft算法是一种以2.1节中描述的形式管理日志副本的算法。图3.1总结了算法供参考,图3.2列出了算法的关键属性。本章的其余部分将在几节中讨论。

Raft首先选择一个服务器作为领导者,然后让领导者完全负责管理系统中的日志副本。Leader接受来自客户机的日志条目,将它们复制到其他服务器上,并告诉服务器何时将日志条目应用到其状态机是安全的。通过Leader management简化日志副本的管理。例如,领导者可以在不咨询其他服务器的情况下决定在日志中放置新条目,数据以简单的方式从领导者流向其他服务器(追随者或候选人)。领导者可能会失败或与其他服务器断开连接,在这种情况下,将选择新的领导者。

Raft算法通过基于Leader的方法,将* * *认知问题分解为三个相对独立的子问题:

在介绍了Raft***识别算法之后,本章讨论了可用性问题和定时在系统中的作用(3.9节),以及服务器之间的Leader转换的可选扩展(3.10节)。

图3-1显示了Raft算法中的关键元素、操作和原理。因为整个画面太大,下面就把这个大图分成四个小图来说明。

图3-1状态(状态)

1 .所有服务器上的持久状态(所有服务器上的持久状态)

(在回复RPC请求之前更新本地永久存储)

& ltcenter style = " box-sizing:border-box;边距-顶部:0px边距-底部:0px颜色:rgb(192,192,192);文本装饰:下划线;"& gt图3.2-2请求投票RPC < /center >

(候选人将此请求称为收集选票)

3.AppendEntries RPC是一个RPC请求,用于领导者与跟随者同步日志条目。通过这个RPC请求,领导者请求追随者追加日志条目,实现日志的同步。

(由领导调用,用于日志条目的备份,该请求还将肩负心跳检查的功能)

为了说明prevLogIndex和prevLogTerm之间的比较方案,请参见下图。

图中领导者和跟随者的任期是3,领导者中的logentries比跟随者中的要新,所以领导者需要发送一个AppendEntries请求,让跟随者同步这些logentries。即RPC请求中的previewindex和previewterm分别为i-1和3。当跟随者收到这个RPC请求时,其当前日志条目的索引是I-1,任期是3,与RPC消息中的previewindex和previewterm相匹配,因此跟随者可以使用entries[]中的日志条目来填充其I到N..如果跟随者最新日志条目的索引(这里暂称为FollowerIndex)不等于i-1,有两种情况。第一种是跟随者index < PrevLogIndex,表示跟随者的日志仍然缺失,那么跟随者将回复false,领导者将再次更新PrevLogIndex、prevLogTerm和entries[]并发起AppendEntries请求(将在下一章详细描述);第二章,遵循索引& gtprevLogIndex,这意味着Follower在PrevLogIndex和prevLogTerm之后同步了日志条目。但是,后一个日志条目的内容与RPC请求中的内容相同吗?以及prevLogIndex和prevLogTerm的日志条目中的内容是否与Leader相同?“这里的问题看完后面的内容会更新的。”

& lt& lt前一章:Raft算法的目的

下一章:Raft算法基础。