一 Paxos 算法
1.1 基本定义
算法中的参与者主要分为三个角色,同时每个参与者又可兼领多个角色:
⑴、proposer 提出提案,提案信息包括提案编号和提议的value;
⑵、acceptor 收到提案后可以接受(accept)提案;
⑶、learner 只能"学习"被批准的提案;
算法保重一致性的基本语义:
⑴、决议(value)只有在被proposers提出后才能被批准(未经批准的决议称为"提案(proposal)");
⑵、在一次Paxos算法的执行实例中,只批准(chosen)一个value;
⑶、learners只能获得被批准(chosen)的value;
有上面的三个语义可演化为四个约束:
⑴、P1: 一个acceptor必须接受(accept)第一次收到的提案;
⑵、P2a:一旦一个具有value v的提案被批准(chosen),那么之后任何acceptor 再次接受(accept)的提案必须具有value v;
⑶、P2b:一旦一个具有value v的提案被批准(chosen),那么之后任何 proposer 提出的提案必须具有value v;
⑷、P2c:如果一个编号为n的提案具有value v,那么存在一个多数派,要么他们中所有人都没有接受(accept)编号小于n的任何提案,要么他们已经接受(accpet)的所有编号小于n的提案中编号最大的那个提案具有value v;
1.2 基本算法(basic paxos)
算法(决议的提出与批准)主要分为两个阶段:
1. prepare阶段:
(1). 当Porposer希望提出方案V1,首先发出prepare请求至大多数Acceptor。Prepare请求内容为序列号<SN1>;
(2). 当Acceptor接收到prepare请求<SN1>时,检查自身上次回复过的prepare请求<SN2>
a). 如果SN2>SN1,则忽略此请求,直接结束本次批准过程;
b). 否则检查上次批准的accept请求(SNx,Vx),并且回复(SNx,Vx);如果之前没有进行过批准,则简单回复OK;
2. accept批准阶段:
(1a)、经过一段时间,收到一些Acceptor回复,回复可分为以下几种:
a)、回复数量满足多数派,并且所有的回复都是<OK>,则Porposer发出accept请求,请求内容为议案(SN1,V1);
b)、回复数量满足多数派,但有的回复为:(SN2,V2),(SN3,V3)……则Porposer找到所有回复中超过半数的那个,假设为(SNx,Vx),则发出accept请求,请求内容为议案(SN1,Vx);
c)、回复数量不满足多数派,Proposer尝试增加序列号为SN1+,转1继续执行;
(1b)、 经过一段时间,收到一些Acceptor回复,回复可分为以下几种:
a)、回复数量满足多数派,则确认V1被接受;
b)、回复数量不满足多数派,V1未被接受,Proposer增加序列号为SN1+,转1继续执行;
(2)、在不违背自己向其他proposer的承诺的前提下,acceptor收到accept 请求后即接受并回复这个请求。
二 Fast Paxos
Lamport在40多页的论文中不仅提出了Fast Paxos算法,并且还从工程实践的角度重新描述了Paxos,使其更贴近应用场景。从一般的Client/Server来考虑,Client其实承担了Proposer和Learner的作用,而Server则扮演Acceptor的角色,因此下面重新描述了Paxos算法中的几个角色:
Client/Proposer/Learner:负责提案并执行提案
Coordinator:Proposer协调者,可为多个,Client通过Coordinator进行提案
Leader:在众多的Coordinator中指定一个作为Leader
Acceptor:负责对Proposal进行投票表决
就是Client的提案由Coordinator进行,Coordinator存在多个,但只能通过其中被选定Leader进行;提案由Leader交由Server进行表决,之后Client作为Learner学习决议的结果。
这种方式更多地考虑了Client/Server这种通用架构,更清楚地注意到了Client既作为Proposer又作为Learner这一事实。同样要注意到的是,如果Leader宕机了,为了保证算法的正确性需要一个Leader的选举算法,但与之前一样,Lamport并不关心这个Leader选举算法,他认为可以简单地通过随机或超时机制实现。
另外在Classic Paxos中,从每次Proposer提案到决议被学习,需要三个通信步骤:
Proposer-----Leader-----Acceptor-----Learner
从直观上来说,Proposer其实更“知道”提交那个Value,如果能让Proposer直接提交value到Acceptor,则可以把通信步骤减少到2个。Fast Paxos便是基于此而产生。
2.1、Make Paxos Faster
我们再回顾下Classic Paxos的几个阶段:
Phase1a:Leader提交proposal到Acceptor
Phase2b:Acceptor回应已经参与投票的最大Proposer编号和选择的Value
Phase2a:Leader收集Acceptor的返回值
Phase2a.1:如果Acceptor无返回值,则自由决定一个
Phase2a.2: 如果有返回值,则选择Proposer编号最大的一个
Phase2b:Acceptor把表决结果发送到Learner
很明显,在Phase2a.1中,如果Leader可以自由决定一个Value,则可以让Proposer提交这个Value,自己则退出通信过程。只要之后的过程运行正常,Leader始终不参与通信,一直有Proposer直接提交Value到Acceptor,从而把Classic Paxos的三阶段通信减少为两阶段,这便是Fast Paxos的由来。因此,我们形式化下Fast Paxos的几个阶段:
Phase1a:Leader提交proposal到Acceptor
Phase1b:Acceptor回应已经参与投票的最大Proposer编号和选择的Value
Phase2a:Leader收集Acceptor的返回值
Phase2a.1:如果Acceptor无返回值,则发送一个Any消息给Acceptor,之后Acceptor便等待Proposer提交Value
Phase2a.2:如果有返回值,则根据规则选取一个
Phase2b:Acceptor把表决结果发送到Learner(包括Leader)
算法主要变化在Phase2a阶段,即:
若Leader可以自由决定一个Value,则发送一条Any消息,Acceptor便等待Proposer提交Value
若Acceptor有返回值,则Acceptor需选择某个Value
先不考虑实现,从形式上消息仅需在
Proposer-----Acceptor-----Learner
之间传递即可,也即仅需2个通信步骤。下面我们详细说明算法过程