Consul使用一致性协议来提供一致性(如CAP定义的)。一致性协议基于“Raft: In search of an Understandable Consensus Algorithm”。Raft的直观展现,见The Secret Lives of Data。html
提示:本页覆盖了Consul内部的全部技术细节。有效的操做和使用Consul并不须要这些细节。这些细节是为了那些不想查阅源代码但又但愿学习的人准备的。算法
Raft是一个基于Paxos的一致性算法。与Paxos相比,Raft被设计得有更少的状态,更简单和更好理解。bootstrap
当讨论Raft时,有一些关键的术语须要知道:安全
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不是设计为高吞吐的写系统,可是它可否处理每秒成百上千的事务依赖于网络和硬件配置。
只有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。这种设计在不牺牲一致性的状况下有较低的事务延迟和更高的可用性。
虽然全部的写入都经过Raft的日志复制,读取更灵活。为了支持可能须要的各类权衡,Consul支持3中不一样的读一致性模式。
三种模式分别是:
下表展现了不一样集群大小的法定人数和故障容忍。推荐的部署是3或5个server。单台服务是很是不可取的,由于在故障的状况下数据丢失是不可避免的。