Paxos 发明者是大名鼎鼎的 Lesile Lamport。Lamport 虚拟了一个叫做 Paxos 的希腊城邦,城邦按照议会民主制的政治模式制定法律。在 Lesile Lamport 的论文中,提出了 Basic Paxos、Multi Paxos、Fast Paxos 三种模型。
Client:系统外部角色,请求发起者,类比于民众。
Proposer:接收 Client 请求,向集群提出提议(Propose)。并在冲突发生时,起到冲突调节的作用。类比于议员,替民众提出议案。
Acceptor(Voter):提议投票和接收者,只有在形成法定人数(Quorum)时,提议才会最终被接受,类比于国会。
Learner:提议接受者,backup 备份,对集群一般没什么影响,类比于记录员。
proposer 失败后议案不会被记录,重提成功后才会记录。
解决方案:被拒绝后等待 random timeout。
由于原生的 Paxos 协议低效,在生产中基本没有实践。实际应用更多的是 Paxos 的简化版本。
Raft、Paxos 可以理解为 Multi Paxos 的衍生版本。
由于 Paxos 协议复杂、不易实现,且效率低,Raft 协议作为 Paxos 协议的简化版应运而生。Raft 协议划分成为了 3 个子问题,并重新定义了以下角色:
(1)leader 通过心跳包证明存活,发送心跳的同时也可以发送同步内容。
(2)follower 未检测到心跳时会发起选取成为 candidate。
(3)多个 candidate 竞选且最高得票数相同时,则等待 random time 后继续发起选举。
(1)不同服务器的 Log 中,如果两个 Log 项目具有相同的全局索引编号以及相同的 Term 编号则这两个项目对应的操作命令也一定相同。—— 由 leader 保证。
(2)不同服务器的 Log 中,如果两个 Log 项目具有相同的全局索引编号以及相同的 Term 编号,那么 Log 中这个项目之前的所有前趋 Log 项目都完全相同。—— 由复制规则保证
Raft 日志提交的过程有点类似两阶段原子提交协议 2PC,不过和 2PC 的最大区别是,Raft 要求超过一半节点同意即可 commited,2PC 要求所有节点同意才能 commited。
Raft 算法规定 follower 强制复制 leader 的日志,即 follower 不一致日志都会被 leader 的日志覆盖,最终 follower 和 leader 保持一致。简单的说,从前向后寻找 follower 和 leader 第一个公共 LogIndex 的位置,然后从这个位置开始,follower 强制复制 leader 的日志。
(1)Election Safety 选举安全性:避免脑裂问题
选举安全性要求一个任期 Term 内只能有一个 leader,即不能出现脑裂现象,否者 raft 的日志复制原则很可能出现数据覆盖丢失的问题。Raft 算法通过规定若干投票原则来解决这个问题:
(2)Leader Append-Only 日志只能由 leader 添加修改
Raft 算法规定,所有的数据请求都要交给 leader 节点处理,要求:
(3)Log Matching 日志匹配特性
这点主要是为了保证日志的唯一性,要求:
(4)Leader Completeness 选举完备性:leader 必须具备最新提交日志
Raft 规定:只有拥有最新提交日志的 follower 节点才有资格成为 leader 节点。具体做法:candidate 竞选投票时会携带最新提交日志,follower 会用自己的日志和 candidate 做比较。
日志更新判断方式是比较日志项的 term 和 index:
(5)State Machine Safety 状态机安全性:确保当前任期日志提交
日志提交有两个条件需要满足:
动画演示:http://thesecretlivesofdata.com/raft/
官网动画:https://raft.github.io/
一致性并不一定代表完全正确性,是否正确还需要由客户端保证。
三个可能的结果:成功、失败、unknown(未达到多数派导致 timeout,取决于系统下一步的状态:恢复 or 换届)。
这个世界上只有一种一致性算法,那就是 Paxos。
Basic Paxos 算法没有 leader proposer 角色,是一个纯粹的去中心化的分布式算法,但是它存在若干不足(只能单值共识 & 活锁 & 网络开销大)。所以才有了以 leader proposer 为核心的 Multi Paxos 算法(由一个去中心化的算法变为 leader-based 的算法)。Raft 算法相当于 Multi Paxos 的进一步优化,主要通过增加两个限制:
(1)日志添加次序性:
(2)选主限制:
个人理解:
(1)作为分布式算法,Raft 的规则限制很多,但是每个规则都简单易懂,最重要的是 leader-based 的,整个程序是一个串行的流程,这使得更加容易理解和实现;
(2)作为对比,Multi Paxos 的限制就很少了,每个节点都可以成为 leader,并发添加日志,这使得理解和落地就没那么简单;
不同业务场景下有着不同的述求,所以一致性算法选择 Multi Paxos 还是 Raft 看各自需求。毕竟程序员更容易理解串行程序。
全称 Zookeeper 原子广播协议(Zookeeper Atomic Broadcast)。基本与 Raft 相同,只是一些名词的叫法上有些区别:如 Zab 将某个 leader 的任期成为 epoch,而 raft 则称为 term。
动画演示:https://rrmoelker.github.io/gossip-visualization/