寻找一种易于理解的一致性算法(扩展版)下

本文首发于深刻浅出区块链社区 原文连接:寻找一种易于理解的一致性算法(扩展版)原文已更新,请读者前往原文阅读算法

6 集群成员变化

到目前为止,咱们都假设集群的配置(加入到一致性算法的服务器集合)是固定不变的。可是在实践中,偶尔是会改变集群的配置的,例如替换那些宕机的机器或者改变复制级别。尽管能够经过暂停整个集群,更新全部配置,而后重启整个集群的方式来实现,可是在更改的时候集群会不可用。另外,若是存在手工操做步骤,那么就会有操做失误的风险。为了不这样的问题,咱们决定自动化配置改变而且将其归入到 Raft 一致性算法中来。安全

为了让配置修改机制可以安全,那么在转换的过程当中不可以存在任什么时候间点使得两个领导人同时被选举成功在同一个任期里。不幸的是,任何服务器直接从旧的配置直接转换到新的配置的方案都是不安全的。一次性自动的转换全部服务器是不可能的,因此在转换期间整个集群存在划分红两个独立的大多数群体的可能性(见图 10)。性能优化

图 10

图 10:直接从一种配置转到新的配置是十分不安全的,由于各个机器可能在任何的时候进行转换。在这个例子中,集群配额从 3 台机器变成了 5 台。不幸的是,存在这样的一个时间点,两个不一样的领导人在同一个任期里均可以被选举成功。一个是经过旧的配置,一个经过新的配置。服务器

为了保证安全性,配置更改必须使用两阶段方法。目前有不少种两阶段的实现。例如,有些系统在第一阶段停掉旧的配置因此集群就不能处理客户端请求;而后在第二阶段在启用新的配置。在 Raft 中,集群先切换到一个过渡的配置,咱们称之为共同一致;一旦共同一致已经被提交了,那么系统就切换到新的配置上。共同一致是老配置和新配置的结合:网络

  • 日志条目被复制给集群中新、老配置的全部服务器。
  • 新、旧配置的服务器均可以成为领导人。
  • 达成一致(针对选举和提交)须要分别在两种配置上得到大多数的支持。

共同一致容许独立的服务器在不影响安全性的前提下,在不一样的时间进行配置转换过程。此外,共同一致可让集群在配置转换的过程人依然响应客户端的请求。数据结构

集群配置在复制日志中以特殊的日志条目来存储和通讯;图 11 展现了配置转换的过程。当一个领导人接收到一个改变配置从 C-old 到 C-new 的请求,他会为了共同一致存储配置(图中的 C-old,new),之前面描述的日志条目和副本的形式。一旦一个服务器将新的配置日志条目增长到它的日志中,他就会用这个配置来作出将来全部的决定(服务器老是使用最新的配置,不管他是否已经被提交)。这意味着领导人要使用 C-old,new 的规则来决定日志条目 C-old,new 何时须要被提交。若是领导人崩溃了,被选出来的新领导人多是使用 C-old 配置也多是 C-old,new 配置,这取决于赢得选举的候选人是否已经接收到了 C-old,new 配置。在任何状况下, C-new 配置在这一时期都不会单方面的作出决定。并发

一旦 C-old,new 被提交,那么不管是 C-old 仍是 C-new,在没有通过他人批准的状况下都不可能作出决定,而且领导人彻底特性保证了只有拥有 C-old,new 日志条目的服务器才有可能被选举为领导人。这个时候,领导人建立一条关于 C-new 配置的日志条目并复制给集群就是安全的了。再者,每一个服务器在见到新的配置的时候就会当即生效。当新的配置在 C-new 的规则下被提交,旧的配置就变得可有可无,同时不使用新的配置的服务器就能够被关闭了。如图 11,C-old 和 C-new 没有任何机会同时作出单方面的决定;这保证了安全性。负载均衡

图 11

图 11:一个配置切换的时间线。虚线表示已经被建立可是尚未被提交的条目,实线表示最后被提交的日志条目。领导人首先建立了 C-old,new 的配置条目在本身的日志中,并提交到 C-old,new 中(C-old 的大多数和 C-new 的大多数)。而后他建立 C-new 条目并提交到 C-new 中的大多数。这样就不存在 C-new 和 C-old 能够同时作出决定的时间点。分布式

在关于从新配置还有三个问题须要提出。第一个问题是,新的服务器可能初始化没有存储任何的日志条目。当这些服务器以这种状态加入到集群中,那么他们须要一段时间来更新追赶,这时还不能提交新的日志条目。为了不这种可用性的间隔时间,Raft 在配置更新的时候使用了一种额外的阶段,在这个阶段,新的服务器以没有投票权身份加入到集群中来(领导人复制日志给他们,可是不考虑他们是大多数)。一旦新的服务器追遇上了集群中的其余机器,从新配置能够像上面描述的同样处理。函数

第二个问题是,集群的领导人可能不是新配置的一员。在这种状况下,领导人就会在提交了 C-new 日志以后退位(回到跟随者状态)。这意味着有这样的一段时间,领导人管理着集群,可是不包括他本身;他复制日志可是不把他本身算做是大多数之一。当 C-new 被提交时,会发生领导人过渡,由于这时是最先新的配置能够独立工做的时间点(将老是可以在 C-new 配置下选出新的领导人)。在此以前,可能只能从 C-old 中选出领导人。

第三个问题是,移除不在 C-new 中的服务器可能会扰乱集群。这些服务器将不会再接收到心跳,因此当选举超时,他们就会进行新的选举过程。他们会发送拥有新的任期号的请求投票 RPCs,这样会致使当前的领导人回退成跟随者状态。新的领导人最终会被选出来,可是被移除的服务器将会再次超时,而后这个过程会再次重复,致使总体可用性大幅下降。

为了不这个问题,当服务器确认当前领导人存在时,服务器会忽略请求投票 RPCs。特别的,当服务器在当前最小选举超时时间内收到一个请求投票 RPC,他不会更新当前的任期号或者投出选票。这不会影响正常的选举,每一个服务器在开始一次选举以前,至少等待一个最小选举超时时间。然而,这有利于避免被移除的服务器扰乱:若是领导人可以发送心跳给集群,那么他就不会被更大的任期号废黜。

7 日志压缩

Raft 的日志在正常操做中不断的增加,可是在实际的系统中,日志不能无限制的增加。随着日志不断增加,他会占用愈来愈多的空间,花费愈来愈多的时间来重置。若是没有必定的机制去清除日志里积累的陈旧的信息,那么会带来可用性问题。

快照是最简单的压缩方法。在快照系统中,整个系统的状态都以快照的形式写入到稳定的持久化存储中,而后到那个时间点以前的日志所有丢弃。快照技术被使用在 Chubby 和 ZooKeeper 中,接下来的章节会介绍 Raft 中的快照技术。

增量压缩的方法,例如日志清理或者日志结构合并树,都是可行的。这些方法每次只对一小部分数据进行操做,这样就分散了压缩的负载压力。首先,他们先选择一个已经积累的大量已经被删除或者被覆盖对象的区域,而后重写那个区域还活跃的对象,以后释放那个区域。和简单操做整个数据集合的快照相比,须要增长复杂的机制来实现。状态机能够实现 LSM tree 使用和快照相同的接口,可是日志清除方法就须要修改 Raft 了。

图 12

图 12:一个服务器用新的快照替换了从 1 到 5 的条目,快照值存储了当前的状态。快照中包含了最后的索引位置和任期号。

图 12 展现了 Raft 中快照的基础思想。每一个服务器独立的建立快照,只包括已经被提交的日志。主要的工做包括将状态机的状态写入到快照中。Raft 也包含一些少许的元数据到快照中:最后被包含索引指的是被快照取代的最后的条目在日志中的索引值(状态机最后应用的日志),最后被包含的任期指的是该条目的任期号。保留这些数据是为了支持快照后紧接着的第一个条目的附加日志请求时的一致性检查,由于这个条目须要前一日志条目的索引值和任期号。为了支持集群成员更新(第 6 节),快照中也将最后的一次配置做为最后一个条目存下来。一旦服务器完成一次快照,他就能够删除最后索引位置以前的全部日志和快照了。

尽管一般服务器都是独立的建立快照,可是领导人必须偶尔的发送快照给一些落后的跟随者。这一般发生在当领导人已经丢弃了下一条须要发送给跟随者的日志条目的时候。幸运的是这种状况不是常规操做:一个与领导人保持同步的跟随者一般都会有这个条目。然而一个运行很是缓慢的跟随者或者新加入集群的服务器(第 6 节)将不会有这个条目。这时让这个跟随者更新到最新的状态的方式就是经过网络把快照发送给他们。

安装快照 RPC

由领导人调用以将快照的分块发送给跟随者。领导者老是按顺序发送分块。

参数 解释
term 领导人的任期号
leaderId 领导人的 Id,以便于跟随者重定向请求
lastIncludedIndex 快照中包含的最后日志条目的索引值
lastIncludedTerm 快照中包含的最后日志条目的任期号
offset 分块在快照中的字节偏移量
data[] 原始数据
done 若是这是最后一个分块则为 true
结果 解释
term 当前任期号(currentTerm),便于领导人更新本身

接收者实现

  1. 若是term < currentTerm就当即回复
  2. 若是是第一个分块(offset 为 0)就建立一个新的快照
  3. 在指定偏移量写入数据
  4. 若是 done 是 false,则继续等待更多的数据
  5. 保存快照文件,丢弃具备较小索引的任何现有或部分快照
  6. 若是现存的日志条目与快照中最后包含的日志条目具备相同的索引值和任期号,则保留其后的日志条目并进行回复
  7. 丢弃整个日志
  8. 使用快照重置状态机(并加载快照的集群配置)

图 13

图 13:一个关于安装快照的简要概述。为了便于传输,快照都是被分红分块的;每一个分块都给了跟随者生命的迹象,因此跟随者能够重置选举超时计时器。

在这种状况下领导人使用一种叫作安装快照的新的 RPC 来发送快照给太落后的跟随者;见图 13。当跟随者经过这种 RPC 接收到快照时,他必须本身决定对于已经存在的日志该如何处理。一般快照会包含没有在接收者日志中存在的信息。在这种状况下,跟随者丢弃其整个日志;它所有被快照取代,而且可能包含与快照冲突的未提交条目。若是接收到的快照是本身日志的前面部分(因为网络重传或者错误),那么被快照包含的条目将会被所有删除,可是快照后面的条目仍然有效,必须保留。

这种快照的方式背离了 Raft 的强领导人原则,由于跟随者能够在不知道领导人状况下建立快照。可是咱们认为这种背离是值得的。领导人的存在,是为了解决在达成一致性的时候的冲突,可是在建立快照的时候,一致性已经达成,这时不存在冲突了,因此没有领导人也是能够的。数据依然是从领导人传给跟随者,只是跟随者能够从新组织他们的数据了。

咱们考虑过一种替代的基于领导人的快照方案,即只有领导人建立快照,而后发送给全部的跟随者。可是这样作有两个缺点。第一,发送快照会浪费网络带宽而且延缓了快照处理的时间。每一个跟随者都已经拥有了全部产生快照须要的信息,并且很显然,本身从本地的状态中建立快照比经过网络接收别人发来的要经济。第二,领导人的实现会更加复杂。例如,领导人须要发送快照的同时并行的将新的日志条目发送给跟随者,这样才不会阻塞新的客户端请求。

还有两个问题影响了快照的性能。首先,服务器必须决定何时应该建立快照。若是快照建立的过于频繁,那么就会浪费大量的磁盘带宽和其余资源;若是建立快照频率过低,他就要承受耗尽存储容量的风险,同时也增长了从日志重建的时间。一个简单的策略就是当日志大小达到一个固定大小的时候就建立一次快照。若是这个阈值设置的显著大于指望的快照的大小,那么快照对磁盘压力的影响就会很小了。

第二个影响性能的问题就是写入快照须要花费显著的一段时间,而且咱们还不但愿影响到正常操做。解决方案是经过写时复制的技术,这样新的更新就能够被接收而不影响到快照。例如,具备函数式数据结构的状态机自然支持这样的功能。另外,操做系统的写时复制技术的支持(如 Linux 上的 fork)能够被用来建立完整的状态机的内存快照(咱们的实现就是这样的)。

8 客户端交互

这一节将介绍客户端是如何和 Raft 进行交互的,包括客户端如何发现领导人和 Raft 是如何支持线性化语义的。这些问题对于全部基于一致性的系统都存在,而且 Raft 的解决方案和其余的也差很少。

Raft 中的客户端发送全部请求给领导人。当客户端启动的时候,他会随机挑选一个服务器进行通讯。若是客户端第一次挑选的服务器不是领导人,那么那个服务器会拒绝客户端的请求而且提供他最近接收到的领导人的信息(附加条目请求包含了领导人的网络地址)。若是领导人已经崩溃了,那么客户端的请求就会超时;客户端以后会再次重试随机挑选服务器的过程。

咱们 Raft 的目标是要实现线性化语义(每一次操做当即执行,只执行一次,在他调用和收到回复之间)。可是,如上述,Raft 是能够执行同一条命令屡次的:例如,若是领导人在提交了这条日志以后,可是在响应客户端以前崩溃了,那么客户端会和新的领导人重试这条指令,致使这条命令就被再次执行了。解决方案就是客户端对于每一条指令都赋予一个惟一的序列号。而后,状态机跟踪每条指令最新的序列号和相应的响应。若是接收到一条指令,它的序列号已经被执行了,那么就当即返回结果,而不从新执行指令。

只读的操做能够直接处理而不须要记录日志。可是,在不增长任何限制的状况下,这么作可能会冒着返回脏数据的风险,由于领导人响应客户端请求时可能已经被新的领导人做废了,可是他还不知道。线性化的读操做必须不能返回脏数据,Raft 须要使用两个额外的措施在不使用日志的状况下保证这一点。首先,领导人必须有关于被提交日志的最新信息。领导人彻底特性保证了领导人必定拥有全部已经被提交的日志条目,可是在他任期开始的时候,他可能不知道那些是已经被提交的。为了知道这些信息,他须要在他的任期里提交一条日志条目。Raft 中经过领导人在任期开始的时候提交一个空白的没有任何操做的日志条目到日志中去来实现。第二,领导人在处理只读的请求以前必须检查本身是否已经被废黜了(他本身的信息已经变脏了若是一个更新的领导人被选举出来)。Raft 中经过让领导人在响应只读请求以前,先和集群中的大多数节点交换一次心跳信息来处理这个问题。可选的,领导人能够依赖心跳机制来实现一种租约的机制,可是这种方法依赖时间来保证安全性(假设时间偏差是有界的)。

9 算法实现和评估

咱们已经为 RAMCloud 实现了 Raft 算法做为存储配置信息的复制状态机的一部分,而且帮助 RAMCloud 协调故障转移。这个 Raft 实现包含大约 2000 行 C++ 代码,其中不包括测试、注释和空行。这些代码是开源的。同时也有大约 25 个其余独立的第三方的基于这篇论文草稿的开源实现,针对不一样的开发场景。同时,不少公司已经部署了基于 Raft 的系统。

这一节会从三个方面来评估 Raft 算法:可理解性、正确性和性能。

9.1 可理解性

为了和 Paxos 比较 Raft 算法的可理解能力,咱们针对高层次的本科生和研究生,在斯坦福大学的高级操做系统课程和加州大学伯克利分校的分布式计算课程上,进行了一次学习的实验。咱们分别拍了针对 Raft 和 Paxos 的视频课程,并准备了相应的小测验。Raft 的视频讲课覆盖了这篇论文的全部内容除了日志压缩;Paxos 讲课包含了足够的资料来建立一个等价的复制状态机,包括单决策 Paxos,多决策 Paxos,从新配置和一些实际系统须要的性能优化(例如领导人选举)。小测验测试一些对算法的基本理解和解释一些边角的示例。每一个学生都是看完第一个视频,回答相应的测试,再看第二个视频,回答相应的测试。大约有一半的学生先进行 Paxos 部分,而后另外一半先进行 Raft 部分,这是为了说明二者从第一部分的算法学习中得到的表现和经验的差别。咱们计算参加人员的每个小测验的得分来看参与者是否在 Raft 算法上更加容易理解。

咱们尽量的使得 Paxos 和 Raft 的比较更加公平。这个实验偏心 Paxos 表如今两个方面:43 个参加者中有 15 我的在以前有一些 Paxos 的经验,而且 Paxos 的视频要长 14%。如表格 1 总结的那样,咱们采起了一些措施来减轻这种潜在的偏见。咱们全部的材料均可供审查。

关心 缓和偏见采起的手段 可供查看的材料
相同的讲课质量 二者使用同一个讲师。Paxos 使用的是如今不少大学里常用的。Paxos 会长 14%。 视频
相同的测验难度 问题以难度分组,在两个测验里成对出现。 小测验
公平评分 使用评价量规。随机顺序打分,两个测验交替进行。 评价量规(rubric)

表 1:考虑到可能会存在的偏见,对于每种状况的解决方法,和相应的材料。

参加者平均在 Raft 的测验中比 Paxos 高 4.9 分(总分 60,那么 Raft 的平均得分是 25.7,而 Paxos 是 20.8);图 14 展现了每一个参与者的得分。配置t-检验(又称student‘s t-test)代表,在 95% 的可信度下,真实的 Raft 分数分布至少比 Paxos 高 2.5 分。

图 14

图 14:一个散点图表示了 43 个学生在 Paxos 和 Raft 的小测验中的成绩。在对角线之上的点表示在 Raft 得到了更高分数的学生。

咱们也创建了一个线性回归模型来预测一个新的学生的测验成绩,基于如下三个因素:他们使用的是哪一个小测验,以前对 Paxos 的经验,和学习算法的顺序。模型预测,对小测验的选择会产生 12.5 分的差异。这显著的高于以前的 4.9 分,由于不少学生在以前都已经有了对于 Paxos 的经验,这至关明显的帮助 Paxos,对 Raft 就没什么太大影响了。可是奇怪的是,模型预测对于先进行 Paxos 小测验的人而言,Raft的得分低了6.3分; 虽然咱们不知道为何,这彷佛在统计上是有意义的。

咱们同时也在测验以后调查了参与者,他们认为哪一个算法更加容易实现和解释;这个的结果在图 15 上。压倒性的结果代表 Raft 算法更加容易实现和解释(41 人中的 33个)。可是,这种本身报告的结果不如参与者的成绩更加可信,而且参与者可能由于咱们的 Raft 更加易于理解的假说而产生偏见。

图 15

图 15:经过一个 5 分制的问题,参与者(左边)被问哪一个算法他们以为在一个高效正确的系统里更容易实现,右边被问哪一个更容易向学生解释。

关于 Raft 用户学习有一个更加详细的讨论。

9.2 正确性

在第 5 节,咱们已经制定了正式的规范,和对一致性机制的安全性证实。这个正式规范使用 TLA+ 规范语言使图 2 中总结的信息很是清晰。它长约400行,并做为证实的主题。同时对于任何想实现 Raft 的人也是十分有用的。咱们经过 TLA 证实系统很是机械的证实了日志彻底特性。然而,这个证实依赖的约束前提尚未被机械证实(例如,咱们尚未证实规范的类型安全)。并且,咱们已经写了一个非正式的证实关于状态机安全性是完备的,而且是至关清晰的(大约 3500 个词)。

9.3 性能

Raft 和其余一致性算法例如 Paxos 有着差很少的性能。在性能方面,最重要的关注点是,当领导人被选举成功时,何时复制新的日志条目。Raft 经过不多数量的消息包(一轮从领导人到集群大多数机器的消息)就达成了这个目的。同时,进一步提高 Raft 的性能也是可行的。例如,很容易经过支持批量操做和管道操做来提升吞吐量和下降延迟。对于其余一致性算法已经提出过不少性能优化方案;其中有不少也能够应用到 Raft 中来,可是咱们暂时把这个问题放到将来的工做中去。

咱们使用咱们本身的 Raft 实现来衡量 Raft 领导人选举的性能而且回答两个问题。首先,领导人选举的过程收敛是否快速?第二,在领导人宕机以后,最小的系统宕机时间是多久?

图 16

图 16:发现并替换一个已经崩溃的领导人的时间。上面的图考察了在选举超时时间上的随机化程度,下面的图考察了最小选举超时时间。每条线表明了 1000 次实验(除了 150-150 毫秒只试了 100 次),和相应的肯定的选举超时时间。例如,150-155 毫秒意思是,选举超时时间从这个区间范围内随机选择并肯定下来。这个实验在一个拥有 5 个节点的集群上进行,其广播时延大约是 15 毫秒。对于 9 个节点的集群,结果也差很少。

为了衡量领导人选举,咱们反复的使一个拥有五个节点的服务器集群的领导人宕机,并计算须要多久才能发现领导人已经宕机并选出一个新的领导人(见图 16)。为了构建一个最坏的场景,在每一的尝试里,服务器都有不一样长度的日志,意味着有些候选人是没有成为领导人的资格的。另外,为了促成选票瓜分的状况,咱们的测试脚本在终止领导人以前同步的发送了一次心跳广播(这大约和领导人在崩溃前复制一个新的日志给其余机器很像)。领导人均匀的随机的在心跳间隔里宕机,也就是最小选举超时时间的一半。所以,最小宕机时间大约就是最小选举超时时间的一半。

图 16 中上面的图代表,只须要在选举超时时间上使用不多的随机化就能够大大避免选票被瓜分的状况。在没有随机化的状况下,在咱们的测试里,选举过程每每都须要花费超过 10 秒钟因为太多的选票瓜分的状况。仅仅增长 5 毫秒的随机化时间,就大大的改善了选举过程,如今平均的宕机时间只有 287 毫秒。增长更多的随机化时间能够大大改善最坏状况:经过增长 50 毫秒的随机化时间,最坏的完成状况(1000 次尝试)只要 513 毫秒。

图 16 中下面的图显示,经过减小选举超时时间能够减小系统的宕机时间。在选举超时时间为 12-24 毫秒的状况下,只须要平均 35 毫秒就能够选举出新的领导人(最长的一次花费了 152 毫秒)。然而,进一步下降选举超时时间的话就会违反 Raft 的时间不等式需求:在选举新领导人以前,领导人就很难发送完心跳包。这会致使没有意义的领导人改变并下降了系统总体的可用性。咱们建议使用更为保守的选举超时时间,好比 150-300 毫秒;这样的时间不大可能致使没有意义的领导人改变,并且依然提供不错的可用性。

10 相关工做

已经有不少关于一致性算法的工做被发表出来,其中不少均可以归到下面的类别中:

  • Lamport 关于 Paxos 的原始描述,和尝试描述的更清晰。
  • 关于 Paxos 的更详尽的描述,补充遗漏的细节并修改算法,使得能够提供更加容易的实现基础。
  • 实现一致性算法的系统,例如 Chubby,ZooKeeper 和 Spanner。对于 Chubby 和 Spanner 的算法并无公开发表其技术细节,尽管他们都声称是基于 Paxos 的。ZooKeeper 的算法细节已经发表,可是和 Paxos 着实有着很大的差异。
  • Paxos 能够应用的性能优化。
  • Oki 和 Liskov 的 Viewstamped Replication(VR),一种和 Paxos 差很少的替代算法。原始的算法描述和分布式传输协议耦合在了一块儿,可是核心的一致性算法在最近的更新里被分离了出来。VR 使用了一种基于领导人的方法,和 Raft 有不少类似之处。

Raft 和 Paxos 最大的不一样之处就在于 Raft 的强领导特性:Raft 使用领导人选举做为一致性协议里必不可少的部分,而且将尽量多的功能集中到了领导人身上。这样就可使得算法更加容易理解。例如,在 Paxos 中,领导人选举和基本的一致性协议是正交的:领导人选举仅仅是性能优化的手段,并且不是一致性所必需要求的。可是,这样就增长了多余的机制:Paxos 同时包含了针对基本一致性要求的两阶段提交协议和针对领导人选举的独立的机制。相比较而言,Raft 就直接将领导人选举归入到一致性算法中,并做为两阶段一致性的第一步。这样就减小了不少机制。

像 Raft 同样,VR 和 ZooKeeper 也是基于领导人的,所以他们也拥有一些 Raft 的优势。可是,Raft 比 VR 和 ZooKeeper 拥有更少的机制由于 Raft 尽量的减小了非领导人的功能。例如,Raft 中日志条目都遵循着从领导人发送给其余人这一个方向:附加条目 RPC 是向外发送的。在 VR 中,日志条目的流动是双向的(领导人能够在选举过程当中接收日志);这就致使了额外的机制和复杂性。根据 ZooKeeper 公开的资料看,它的日志条目也是双向传输的,可是它的实现更像 Raft。

和上述咱们说起的其余基于一致性的日志复制算法中,Raft 的消息类型更少。例如,咱们数了一下 VR 和 ZooKeeper 使用的用来基本一致性须要和成员改变的消息数(排除了日志压缩和客户端交互,由于这些都比较独立且和算法关系不大)。VR 和 ZooKeeper 都分别定义了 10 中不一样的消息类型,相对的,Raft 只有 4 中消息类型(两种 RPC 请求和对应的响应)。Raft 的消息都稍微比其余算法的要信息量大,可是都很简单。另外,VR 和 ZooKeeper 都在领导人改变时传输了整个日志;因此为了可以实践中使用,额外的消息类型就很必要了。

Raft 的强领导人模型简化了整个算法,可是同时也排斥了一些性能优化的方法。例如,平等主义 Paxos (EPaxos)在某些没有领导人的状况下能够达到很高的性能。平等主义 Paxos 充分发挥了在状态机指令中的交换性。任何服务器均可以在一轮通讯下就提交指令,除非其余指令同时被提出了。然而,若是指令都是并发的被提出,而且互相之间不通讯沟通,那么 EPaxos 就须要额外的一轮通讯。由于任何服务器均可以提交指令,因此 EPaxos 在服务器之间的负载均衡作的很好,而且很容易在 WAN 网络环境下得到很低的延迟。可是,他在 Paxos 上增长了很是明显的复杂性。

一些集群成员变换的方法已经被提出或者在其余的工做中被实现,包括 Lamport 的原始的讨论,VR 和 SMART。咱们选择使用共同一致的方法由于他对一致性协议的其余部分影响很小,这样咱们只须要不多的一些机制就能够实现成员变换。Lamport 的基于 α 的方法之因此没有被 Raft 选择是由于它假设在没有领导人的状况下也能够达到一致性。和 VR 和 SMART 相比较,Raft 的从新配置算法能够在不限制正常请求处理的状况下进行;相比较的,VR 须要中止全部的处理过程,SMART 引入了一个和 α 相似的方法,限制了请求处理的数量。Raft 的方法同时也须要更少的额外机制来实现,和 VR、SMART 比较而言。

11 结论

算法的设计一般会把正确性,效率或者简洁做为主要的目标。尽管这些都是颇有意义的目标,可是咱们相信,可理解性也是同样的重要。在开发者把算法应用到实际的系统中以前,这些目标没有一个会被实现,这些都会必然的偏离发表时的形式。除非开发人员对这个算法有着很深的理解而且有着直观的感受,不然将会对他们而言很难在实现的时候保持原有指望的特性。

在这篇论文中,咱们尝试解决分布式一致性问题,可是一个广为接受可是十分使人费解的算法 Paxos 已经困扰了无数学生和开发者不少年了。咱们创造了一种新的算法 Raft,显而易见的比 Paxos 要容易理解。咱们同时也相信,Raft 也能够为实际的实现提供坚实的基础。把可理解性做为设计的目标改变了咱们设计 Raft 的方式;随着设计的进展,咱们发现本身重复使用了一些技术,好比分解问题和简化状态空间。这些技术不只提高了 Raft 的可理解性,同时也使咱们坚信其正确性。

12 感谢

这项研究必须感谢如下人员的支持:Ali Ghodsi,David Mazie`res,和伯克利 CS 294-91 课程、斯坦福 CS 240 课程的学生。Scott Klemmer 帮咱们设计了用户调查,Nelson Ray 建议咱们进行统计学的分析。在用户调查时使用的关于 Paxos 的幻灯片很大一部分是从 Lorenzo Alvisi 的幻灯片上借鉴过来的。特别的,很是感谢 DavidMazieres 和 Ezra Hoch,他们找到了 Raft 中一些难以发现的漏洞。许多人提供了关于这篇论文十分有用的反馈和用户调查材料,包括 Ed Bugnion,Michael Chan,Hugues Evrard,Daniel Giffin,Arjun Gopalan,Jon Howell,Vimalkumar Jeyakumar,Ankita Kejriwal,Aleksandar Kracun,Amit Levy,Joel Martin,Satoshi Matsushita,Oleg Pesok,David Ramos,Robbert van Renesse,Mendel Rosenblum,Nicolas Schiper,Deian Stefan,Andrew Stone,Ryan Stutsman,David Terei,Stephen Yang,Matei Zaharia 以及 24 位匿名的会议审查人员(可能有重复),而且特别感谢咱们的领导人 Eddie Kohler。Werner Vogels 发了一条早期草稿连接的推特,给 Raft 带来了极大的关注。咱们的工做由 Gigascale 系统研究中心和 Multiscale 系统研究中心给予支持,这两个研究中心由关注中心研究程序资金支持,一个是半导体研究公司的程序,由 STARnet 支持,一个半导体研究公司的程序由 MARCO 和 DARPA 支持,在国家科学基金会的 0963859 号批准,而且得到了来自 Facebook,Google,Mellanox,NEC,NetApp,SAP 和 Samsung 的支持。Diego Ongaro 由 Junglee 公司,斯坦福的毕业团体支持。

本文经TopJohn受权转自TopJohn's Blog

深刻浅出区块链 - 系统学习区块链,打造最好的区块链技术博客。

相关文章
相关标签/搜索