Consual 一致性协议

  Consul使用一致性协议来提供一致性(如CAP定义的)。一致性协议基于“Raft: In search of an Understandable Consensus Algorithm”。Raft的直观展现,见The Secret Lives of Datahtml

  提示:本页覆盖了Consul内部的全部技术细节。有效的操做和使用Consul并不须要这些细节。这些细节是为了那些不想查阅源代码但又但愿学习的人准备的。算法

Raft协议概述

  Raft是一个基于Paxos的一致性算法。与Paxos相比,Raft被设计得有更少的状态,更简单和更好理解。bootstrap

  当讨论Raft时,有一些关键的术语须要知道:安全

  • Log——Raft系统的基本工做单元是日志记录。一致性的问题能够被分解到复制日志中。日志是一个有序的记录序列。若是全部成员赞成记录和他们的顺序,咱们认为日志是一致的。
  • FSM——有限状态机。有限状态机是互相转移的有限的状态的集合。当有新的日志,FSM容许在状态之间转换。相同日志序列的应用必须产生相同的状态,这意味着行为必须是肯定性的。
  • Peer set——全部参与日志复制的成员组成了Peer set。对于Consul而言,全部的server节点都在本地数据中心的Peer set中。
  • Quorum(法定人数)——法定人数是Peer set中的大多数成员。对于一个大小为n的集合,法定人数必须至少是(n/2)+1个成员。例如,若是在Peer set中有5个成员,咱们须要3个节点来组成一个法定人数。若是因为任何缘由致使法定人数的节点不可用,则集群是不可用的,而且不会有新的日志提交。
  • Committed Entry——当一条记录被持久化的存储在法定人数的节点中,该记录被认为是已提交的。一旦一条记录被提交他就能够被应用。
  • Leader——在任何给定时间,Peer set选举一个节点成为leader。leader负责处理新提交的记录,复制到follow上和管理它们。

  Raft是一个复杂的协议,不会在这里详细介绍(对于那些但愿更全面的了解的,完整的规范在这篇文章中)。然而,咱们试图提供一个更高层次的描述,这有助于创建一个心理模型。服务器

  Raft节点老是处于三个状态中的一个:follower,candidate和leader。全部的节点最初都是处于follower。在这个状态节点能够接受来自leader的日志和进行投票。若是一段时间没有收到任何记录,节点会自我升级为candidate。在candidate状态,节点从其它节点处获取选票,若是candidate获取法定的选票数,则它晋升为leader。leader必须接收新的记录而且复制到其它全部的follower上。另外,若是过期的查询时不可接受的,全部的查询也必须在leader上执行。网络

  一旦一个集群有一个leader,它能够接受新的日志记录。client能够请求leader追加新的日志(从Raft的角度看,日志是一个不透明的二进制blob)。而后leader将记录写入持久化的介质中而且试图复制到法定人数的follower。一旦日志记录被认为是提交的,它能被应用到有限状态机上。有限状态机是应用指定的。在Consul中,咱们使用BoltDB来维护集群状态。app

  显然,容许复制的日志以无限的方式增加这显然是不可取的。Raft提供一种快照当前状态和压缩日志的机制。由于FSM是抽象的,重播旧的日志来恢复FSM的状态必然致使相同的状态。这使得Raft能够在某个时间点计算FSM的状态,而后删除全部达到该状态的日志。这是自动执行的,无需用户干预而且防止无限制的使用磁盘,同时也减小了重放日志的时间。使用BoltDB的一个优势是,它容许Consul继续接收新的事务即便旧状态正在被快照,不会产生任何的问题。ide

  只要有法定人数的节点可用,Consensus是容错的。若是法定人数的节点不可用,那么不可能处理日志或者成员关系。例如,假设这里有两个节点:A和B。法定人数也是2,意味着两个节点都必须赞成提交日志记录。若是A或者B失败了,则不可能达到法定人数。这意味着集群没法添加或者删除或者提交任何日志记录。这个结果是不可用的,在这个时候须要手工干预来删除A或者B,而后以引导模式重启。性能

  3个节点Raft集群能够容忍一个节点的故障,5个节点的集群能够容忍两个节点故障。推荐的配置是每一个数据中心运行3或5个Consul Server。这能够最大限度的提升可用性,而不会有太大的性能牺牲。下面的部署表总结了潜在的集群大小和每一个集群的故障容忍。学习

  在性能方面,Raft比得上Paxos。假设都存在稳定的leader,提交一个日志记录须要往返集群半数节点。所以性能受限于磁盘IO和网络延迟。尽管Consul不是设计为高吞吐的写系统,可是它可否处理每秒成百上千的事务依赖于网络和硬件配置。

Raft in Consul

   只有Consul server节点加入Raft。全部的Client节点转发请求到Server。这样设计的一部分缘由是,随着更多的节点加入集群,法定人数的节点也会增长。这会引入性能问题,由于你可能须要等待数百机器而不是少数的来赞成一条记录。

  当开始时,一个Consul Server被设置成“bootstrap”模式。这个模式容许它选举本身为leader。一旦一个leader被选举,其它机器可以保持一致性和安全性的加入peer set。最终,一旦第一部分机器已经加入,bootstrap模式能够被禁用。更多细节看这个文档

  因为全部的server都加入做为peer set的一部分,它们都知道当前的leader。当一个RPC请求到达一个非leader的server时,请求被转发到leader。若是一个RPC是一个查询类型,意味着它是只读,leader生成基于FSM当前状态的结果。若是RPC是一个事务类型,意味着它修改状态,leader生成一个新的日志记录而且将其用于Raft。一旦一个日志记录被提交且应用于FSM,则事务完成。

  因为Raft的复制性质,性能对网络延迟是敏感的。因为这个缘由,每一个数据中心选择一个独立的leader并维护一个不相交的peer set。数据按照数据中心分区,因此每一个leader只负责它数据中心的数据。当一个请求被一个远程数据中心接到,请求被转发到正确的leader。这种设计在不牺牲一致性的状况下有较低的事务延迟和更高的可用性。

Consistency Modes

  虽然全部的写入都经过Raft的日志复制,读取更灵活。为了支持可能须要的各类权衡,Consul支持3中不一样的读一致性模式。

  三种模式分别是:

  • default——Raft使用leader租赁过程,该过程提供了一个时间窗口,在该窗口内leader保持稳定的角色。然而,若是一个leader与其余节点分区,当旧的leader仍然持有租赁时一个新的leader会被选举出来。这意味着有两个leader节点。这里没有脑裂的风险,由于旧的leader不能提交新日志。然而,若是旧的leader任然提供任何读取服务,读取的值多是旧的。默认的一致性模式只依赖于leader的租赁期,可能暴露给client旧值。作这样的权衡是由于读取时快速的,通常是强一致的,而且只有旧值是很难触发的。读取旧值的时间窗口也是有界的,由于leader会因为分区而下台。
  • consistent——这种模式是强一致的,没有任何隐忧。它要求leader验证法定人数的节点,证实它任然是leader。这会引入一个额外的往返全部节点的过程。这种权衡老是一致性的读取,可是会增长延迟由于有额外的往返时间。
  • stale——这种模式容许在任何服务器上读取,无论它是否是leader。这意味着可能读取到任意的陈旧值,可是一般与leader差距50毫秒。这种权衡是快速和可扩展的读取,可是可能有陈旧值。这种不用leader模式的读取意味着一个不可用的集群也可以响应。

Deployment Table

   下表展现了不一样集群大小的法定人数和故障容忍。推荐的部署是3或5个server。单台服务是很是不可取的,由于在故障的状况下数据丢失是不可避免的。

相关文章
相关标签/搜索