Raft一致性算法( 三 )


因此,实际的系统中很少有和 Paxos 相似的实践 。每一种实现都是从 Paxos 开始研究,然后发现很多实现上的难题,再然后开发了一种和 Paxos 明显不一样的结构 。这样是非常费时和容易出错的,并且理解 Paxos 的难度使得这个问题更加糟糕 。Paxos 算法在理论上被证明是正确可行的,但是现实的系统和 Paxos 差别是如此的大,以至于这些证明没有什么太大的价值 。下面来自 Chubby 实现非常典型:
 

在Paxos算法描述和实现现实系统中间有着巨大的鸿沟 。最终的系统建立在一种没有经过证明的算法之上 。
 
由于以上问题,我们认为 Paxos 算法既没有提供一个良好的基础给实践的系统,也没有给教学很好的帮助 。基于一致性问题在大规模软件系统中的重要性,我们决定看看我们是否可以设计一个拥有更好特性的替代 Paxos 的一致性算法 。Raft 算法就是这次实验的结果 。
4 为了可理解性的设计
设计 Raft 算法我们有几个初衷:它必须提供一个完整的实际的系统实现基础,这样才能大大减少开发者的工作;它必须在任何情况下都是安全的并且在大多数的情况下都是可用的;并且它的大部分操作必须是高效的 。但是我们最重要也是最大的挑战是可理解性 。它必须保证对于普遍的人群都可以十分容易的去理解 。另外,它必须能够让人形成直观的认识,这样系统的构建者才能够在现实中进行必然的扩展 。
在设计 Raft 算法的时候,有很多的点需要我们在各种备选方案中进行选择 。在这种情况下,我们评估备选方案基于可理解性原则:解释各个备选方案有多大的难度(例如,Raft 的状态空间有多复杂,是否有微妙的暗示)?对于一个读者而言,完全理解这个方案和暗示是否容易?
我们意识到对这种可理解性分析上具有高度的主观性;尽管如此,我们使用了两种通常适用的技术来解决这个问题 。第一个技术就是众所周知的问题分解:我们尽可能地将问题分解成几个相对独立的,可被解决的、可解释的和可理解的子问题 。例如,Raft 算法被我们分成领导人选举,日志复制,安全性和成员变更几个部分 。
我们使用的第二个方法是通过减少状态的数量来简化需要考虑的状态空间,使得系统更加连贯并且在可能的时候消除不确定性 。特别的,所有的日志是不允许有空洞的,并且 Raft 限制了日志之间变成不一致状态的可能 。尽管在大多数情况下我们都试图消除不确定性,但是也有一些情况下不确定性可以提升可理解性 。尤其是,随机化方法增加了不确定性,但是他们有利于减少状态空间数量,通过处理所有可能选择时使用相似的方法 。我们使用随机化来简化 Raft 中领导人选举算法 。
5 Raft 一致性算法
Raft 是一种用来管理章节 2 中描述的复制日志的算法 。图 2 为了参考之用,总结这个算法的简略版本,图 3 列举了这个算法的一些关键特性 。图中的这些元素会在剩下的章节逐一介绍 。
Raft 通过选举一个杰出的领导人,然后给予他全部的管理复制日志的责任来实现一致性 。领导人从客户端接收日志条目(log entries),把日志条目复制到其他服务器上,并告诉其他的服务器什么时候可以安全地将日志条目应用到他们的状态机中 。拥有一个领导人大大简化了对复制日志的管理 。例如,领导人可以决定新的日志条目需要放在日志中的什么位置而不需要和其他服务器商议,并且数据都从领导人流向其他服务器 。一个领导人可能会发生故障,或者和其他服务器失去连接,在这种情况下一个新的领导人会被选举出来 。
通过领导人的方式,Raft 将一致性问题分解成了三个相对独立的子问题,这些问题会在接下来的子章节中进行讨论:
 
  • 领导选举:当现存的领导人发生故障的时候, 一个新的领导人需要被选举出来(章节 5.2)
  • 日志复制:领导人必须从客户端接收日志条目(log entries)然后复制到集群中的其他节点,并强制要求其他节点的日志和自己保持一致 。
  • 安全性:在 Raft 中安全性的关键是在图 3 中展示的状态机安全:如果有任何的服务器节点已经应用了一个确定的日志条目到它的状态机中,那么其他服务器节点不能在同一个日志索引位置应用一个不同的指令 。章节 5.4 阐述了 Raft 算法是如何保证这个特性的;这个解决方案涉及到选举机制(5.2 节)上的一个额外限制 。
 


推荐阅读