【数据结构和算法】paxos算法图解
一、paxos的流程图(https://zh.wikipedia.org/zh-cn/Paxos%E7%AE%97%E6%B3%95)
1、算法的提出和证明
首先将议员的角色分为 proposers,acceptors,和 learners(允许身兼数职)。proposers 提出提案,提案信息包括提案编号和提议的 value;acceptor 收到提案后可以接受(accept)提案,若提案获得多数派(majority)的 acceptors 的接受,则称该提案被批准(chosen);learners 只能“学习”被批准的提案。划分角色后,就可以更精确的定义问题:
- 决议(value)只有在被 proposers 提出后才能被批准(未经批准的决议称为“提案(proposal)”);
- 在一次 Paxos 算法的执行实例中,只批准(chosen)一个 value;
- learners 只能获得被批准(chosen)的 value。
2、算法的流程图
P1:一个 acceptor 必须接受(accept)第一次收到的提案。
P2:一旦一个具有 value v 的提案被批准(chosen),那么之后批准(chosen)的提案必须具有 value v。
P2a:一旦一个具有 value v 的提案被批准(chosen),那么之后任何 acceptor 再次接受(accept)的提案必须具有 value v。
P2b:一旦一个具有 value v 的提案被批准(chosen),那么以后任何 proposer 提出的提案必须具有 value v。
P2c:如果一个编号为 n 的提案具有 value v,该提案被提出(issued),那么存在一个多数派,要么他们中所有人都没有接受(accept)编号小于 n 的任何提案,要么他们已经接受(accept)的所有编号小于 n 的提案中编号最大的那个提案具有 value v。
二、Paxos算法实例详解
Paxos中有三类角色
Proposer(提议者)
Acceptor(审批者)
Learner(学习者)
主要交互过程在Proposer
和Acceptor
之间。(一个物理机实例服务,可以同时担任三个角色,只是每个角色监听的端口号不同)
Proposer
与Acceptor
之间的交互主要有4类消息通信,如下图:
这4类消息对应于paxos算法的两个阶段4个过程:
- phase 1
- a) proposer向网络内超过半数的acceptor发送prepare消息
- b) acceptor正常情况下回复promise消息
- phase 2
- a) 在有足够多acceptor回复promise消息时,proposer发送accept消息
- b) 正常情况下acceptor回复accepted消息
因为在整个过程中可能有其他proposer针对同一件事情发出以上请求,所以在每个过程中都会有些特殊情况处理,这也是为了达成一致性所做的事情。如果在整个过程中没有其他proposer来竞争,那么这个操作的结果就是确定无异议的。但是如果有其他proposer的话,情况就不一样了。
以paxos中文wiki上的例子为例。简单来说该例子以若干个议员提议税收,确定最终通过的法案税收比例。
以下图中基本只画出proposer与一个acceptor的交互。时间标志T2总是在T1后面。propose number简称N。
情况之一如下图:
A3在T1发出accepted给A1,然后在T2收到A5的prepare,在T3的时候A1才通知A5最终结果(税率10%)。这里会有两种情况:
- A5发来的N5小于A1发出去的N1,那么A3直接拒绝(reject)A5
- A5发来的N5大于A1发出去的N1,那么A3回复promise,但带上A1的(N1, 10%)
这里可以与paxos流程图对应起来,更好理解。acceptor会记录(MaxN, AcceptN, AcceptV)。
A5在收到promise后,后续的流程可以顺利进行。但是发出accept时,因为收到了(AcceptN, AcceptV),所以会取最大的AcceptN对应的AcceptV,例子中也就是A1的10%作为AcceptV。如果在收到promise时没有发现有其他已记录的AcceptV,则其值可以由自己决定。
针对以上A1和A5冲突的情况,最终A1和A5都会广播接受的值为10%。
其实4个过程中对于acceptor而言,在回复promise和accepted时由于都可能因为其他proposer的介入而导致特殊处理。所以基本上看在这两个时间点收到其他proposer的请求时就可以了解整个算法了。例如在回复promise时则可能因为proposer发来的N不够大而reject:
如果在发accepted消息时,对其他更大N的proposer发出过promise,那么也会reject该proposer发出的accept,如图:
总结
Leslie Lamport没有用数学描述Paxos,但是他用英文阐述得很清晰。将Paxos的两个Phase的内容理解清楚,整个算法过程还是不复杂的。
至于Paxos中一直提到的一个全局唯一且递增的proposer number,其如何实现,引用如下:
如何产生唯一的编号呢?在《Paxos made simple》中提到的是让所有的Proposer都从不相交的数据集合中进行选择,例如系统有5个Proposer,则可为每一个Proposer分配一个标识j(0~4),则每一个proposer每次提出决议的编号可以为5*i + j(i可以用来表示提出议案的次数)