分布式共识算法Paxos-Leslie Lamport
算法作者: Leslie Lamport(就是大名鼎鼎的LaTeX中的“La”)
1. 前言
1.1 共识算法的作用
主要是为了解决分布式系统CAP问题中C-Consistency问题
- 处理分布式环境下的Consistency问题:即分布式集群环境下不同节点的消息一致性问题;
- 避免一个分布式系统整体对外部的客户端表现出数据不一致性:比如未作更新操作的前提下,在t0时刻客户端A,B访问得到的目标值结果不一致;
1.2 共识算法的发展
-
Basic Paxos
-
初版Paxos 1990-提出分布式节点三角色-Proposer、Acceptor、Learner,分别用于发出提案、接受/否决提案、学习并同步最新的提案,从理论上给出了分布式系统中CAP问题的解决方案。但因LA在算法中的示例“古希腊城邦”不被论文审稿人接受而放弃发表;
-
第二版Paxos 1998-时隔八年后LA大佬将重新整理的论文成功发表到ACM Transaction on Computer System,引起业界人士的一定反响,但影响范围较小;
-
第三版 Paxos 2001-时隔三年,LA放弃"古希腊城邦"的案例说明,重新整理Paxos并发表到SIGATC News杂志,此次发表以Paxos Made Simple为主题,表示LA已经用其认为的最简洁的方式来阐述了Paxos,但大多数人还是无法看懂,所以此次引起的反响依旧不大。。。
-
2006年直到Google Chubby,Mega Store,Spanner等基于Paxos的分布式项目成功问世,Paxos理论才真正进入业界的视线,这几个项目的成功极大的吸引了其他科技公司对Paxos算法的研究兴趣。
-
-
Multi-Paxos(选主)
-
虽然Paxos是一个复杂、逻辑严密的算法理论,但是其是一个针对广义分布式系统领域的纲领意义上的算法,这就导致其并不能在特定的商业领域表现出其优越性,且其存在如下问题:
- 协商过程复杂且易发生多次协商的问题
- “活锁”问题-即多个proposer在提案阶段成功,在接受阶段都失败的现象;
因此LA设计了Multi-Paxos的算法,其主要的改动就是增加了分布式系统的选主功能-即增加了Leader节点角色-选主,解决了Proposer角色过多导致提案协商过程性能较差以及可能的活锁问题。Multi-Paxos只有Leader节点能发起提案,然后再接受多个Acceptor的提案相应即可,避免了提案协商过程,提高了性能;
-
2 共识算法工作原理
2.1 Paxos共识算法原理
-
节点有三种角色,proposer/acceptor/learner,proposer是提案者,acceptor是决议者,learner是记录节点,整个消息一致性处理的流程如下:
-
Prepare阶段:分布式各节点收到不同客户端的不同请求时,会将不同请求生成不同的提案(唯一ID +单增)发给集群acceptor节点获取"提案回复" promise,promise包含两个承诺和一个响应:
-
两个承诺
- 承诺不再接受ID小于/等于n的提案proposal
- 承诺不再接受ID小于n的许可accept
-
一个回复
- 若当前提案ID大于节点已经保存的最大提案ID,则将返回已保存的与修改对象相关的最大提案的ID以及修改过的值,若该节点没有修改过该值,则返回空;
- 若当前提案ID小于等于节点已保存的最大提案ID,则不做响应(即否决提案)
- 若当前提案ID大于节点已经保存的最大提案ID,则将返回已保存的与修改对象相关的最大提案的ID以及修改过的值,若该节点没有修改过该值,则返回空;
-
-
Accept阶段:若某个proposer A收到了集群中大多数节点的promise,则认为提案通过,开始进行accept请求阶段,accept请求分如下两种情况:
-
若proposer收到的promise中值为空,则proposer可以随意决定目标的值,并构建accept请求发给集群中的所有acceptor节点;
-
否则必须从所有promise中选出提案ID最大且值非空的那个,以其值为基础构建(id, maxAcceptValue)并发给所有的acceptor节点;
每个决策节点在不违反前面的承诺规则的前提下对accept请求的提案内容持久化并给出accept响应,否则不响应该请求;
-
-
决议扩散阶段:若proposer A收到了大多数决议节点的响应,则将该accept请求形成决议并分发给所有的learner记录节点以作学习,本质上就是存储决议的数据。
-
-
每个节点可以同时是proposer以及acceptor,否则就是learner,具体的Paxos算法流程可参看官方示例图,如下
2.2 Multi-Paxos算法工作原理
相比与Paxos,Multi-Paxos优化了准备阶段,通过增加选主的方式解决多个proposer发出多个提案的问题
2.2.1 为什么设计Multi-Paxos算法
- 活锁问题解决 : 通过对paxos的介绍,可以知道paxos在实际环境中可能存在“活锁”以及其他异常情况,而这些异常基本上是在准备阶段的提案协商时发生的,这是因为在paxos算法中存在多个proposer角色,每个proposer在接受到请求后都需要向所有决策节点发送提案,而每个proposer节点的性能、网络状况可能会有所差别,这会导致各种异常情况。因此,Multi-Paxos增加leader节点角色,只有leader节点才能发起提案,而集群中其他节点收到请求后都需要将请求转发给leader,由leader提出accept请求,并发给所有的决策节点,获取批准结果,由此省略了提案阶段。
2.2.2 Multi-Paxos工作原理
1 流程
- 选主阶段:Multi-Paxos规定一个集群中存在一个Leader节点,其他所有节点和Leader节点保持心跳通信。当集群中多数节点都发现无法与Leader心跳通信后,集群中节点就会发出要竞选主节点的请求,若多数决策节点许可该请求,则该节点成为主提案节点,专门负责提案操作。若提案节点收到请求,则将提案转发给主节点,此时分布式下的提案操作都经由主节点执行,因此提案操作是有序的,即可忽略准备阶段(因为经由主节点有序提案的情况下,当前的提案ID肯定大于主节点已保存的提案ID),节省时间,避免活锁;
- 批准阶段:Leader节点将提案构建成Accept请求,广播给所有的决策节点,决策节点基于承诺原则持久化提案数据,返回Accept响应
- 决议分发阶段:若Leader节点收到多数决策节点的批准响应,则将提案形成决议分发给所有的记录节点(Learner)