首先得放该开头,分布式系统的一致性协议一直是分布式系统的难题,本人没有阅读过 Lamport 老人家的论文原文(估计直接读也未必读的懂),以下所有内容来自网络博文、书籍和网站的整理,加上自己的理解润色。水平有限不敢说全都正确,仅供参考。
Paxos
说到分布式一致性协议,Paxos 肯定是绕不开的,关于它和其作这 Lamport 的传奇故事也是有很多,这里就不啰嗦了,感兴趣的可以自行搜索。作为几种常见协议的基础,Paxos 提供了“选举” 的思想,Lamport 为了简化 Paxos,也为了讲述这个算法,假想了一个叫做 Paxos 的希腊城邦进行选举的情景,这个算法也是因此而得名。
Paxos 算法的步骤是这样:
- 首先有两种角色,一个是“提议者”,一个是“接受者”。提议者可以向接受者提出提议,然后接受者表达意见。
- 因为存在多个提议者,如果同时表达意见会出现意见不一致的情况,所以首先需要尽快选出一个领导者,让意见统一。
- 然后领导者会给接受者发出提议,如果一个提议被大多数接受者接纳,这个提议就通过了。
大致的流程是这样,再完善一下细节:
- 如何明确领导者?这里会有两个阶段:
- 第一阶段是先达成一致,协商出领导者,具体方法就是通过编号,提议者会先报告一个编号,谁的编号最大谁就是领导(Lamport 巧妙的比喻为“贿选”,谁出的钱多就选谁)。
- 然后第二阶段就是上一轮胜出的领导提出提议,发送给各个接受者。
- 跟常识不太一样的是,每个提议者不会执着于当领导,而是谋求尽快达成共识,所以如果在一个提议者提议的时候,如果发现接受者已经接受了其他领导者的提议,也会默默的把自己的提议改为前面领导者的提议。
- 编号不能太小,很小的话前两个阶段都会直接失败,接受者拒绝接受你的提议。
- 在步骤 2 中,还有可能出现冲突:比如如果一个提议者在对接受者 A 提议的时候,发现 A 接受了领导者 L1 的提议,然后又去接受者 B 那里提议,发现 B 接受了领导者 L2 的提议,已知这个提议者肯定会跟随前面已经存在的提议,那么他会把自己的提议改为上面两个的哪个呐?答案是数值更大的那个。
- 在达成共识之前,这整个阶段,哪个提议者先来,哪个后来,接受者什么时候收到提议者的信息,都是不可控的。所以有可能产生这样一种情况:一个提议者已经晋升为领导者,但是还没发起提议,这时候另外一个“土豪”提议者过来,疯狂“贿选”,还是存在机会让自己胜出的。这时就形成了一种博弈:
- 上一个领导者要赶在土豪提议者贿赂到接受者前,赶到接受者面前让他接受自己的提议,否则会因为自己的之前贿赂的钱比土豪少而被拒绝。
- 土豪“提议者”要赶在上一个领导者将提议传达给接受者前,贿赂到接受者,否则土豪提议者即便贿赂成功,也要默默的将自己的提议改为前任意见领袖的提议。
这整个博弈的过程,最终就看这两个提议者谁的进展快了。但最终一定会有一个领导者,先得到多数接受者的认可,那他的提议就胜出了。
总结来看,Paxos 包括以下几个原则:
- Paxos 算法包括两个阶段:第一个阶段主要是贿选,还没有提出提议;第二个阶段主要根据第一阶段的结果,明确接受谁的提议,并明确提议的内容是什么(这个提议可能是贿选胜出提议者自己的提议,也可能是前任意见领袖的提议,具体是哪个提议,往下看,见下面第 3 点的内容)。
- 编号(贿赂金额)很重要,无论在哪个阶段,编号(贿赂金额)小的,都会被拒绝。
- 在第一阶段中,一旦接受者已经接受了之前领导者的提议,那后面再来找这个接受者的提议者,即便在贿赂中胜出,也要被洗脑,默默将自己的提议改为前任意见领袖的提议,然后他会在第二阶段提出该提议(也就是之前意见领袖的提议,以力争让大家的意见趋同)。如果接受者之前没有接受过任何提议,那贿选胜出的提议者就可以提出自己的提议了。
以上,我们说的 Paxos 其实又叫 Basic Paxos,只具备理论基础,实际上实现起来很麻烦而且效率低。因为每次同步一个信息,就要进行上述繁杂的达成共识阶段,无异会产生巨大的开销。
于是后来又有了进阶版的 Multi Paxos 协议。只要 Leader 是相对稳定不变的,第 1 阶段就变得不必要。 这样,系统可以在接下来的 Paxos 算法实例中,跳过的第 1 阶段,直接使用同样的 Leader。
Multi Paxos 本身对一些边缘情况没有定义,所以大多数实际应用是基于 Multi Paxos 进行补充,或者使用它的变种 Raft。
从网上查询得知,工业界中三种协议的应用情况基本如下:
- 微信背后的高可用存储系统 PaxosStore 是基于 Multi Paxos 开发的
- 广为人知的高可靠的 kv 存储系统 etcd 用的 Raft
- 阿里的高性能存储 PolarFS 用到的 Raft 变种 ParallelRaft 协议
- TiDB 用的 Raft
- ZAB 的名字就叫 ZooKe