# Vue还有这种操作？浅析几个新手常常忽略的API

## 二、信息保持及算法流程

2.1 关于提案及Acceptor和Proposer的信息保持

Acceptor保持的信息为：RoP_Max，RoA_Max和Value_Acc。

RoP_Max含义是某Acceptor参与的最大轮次（the max round of participation），相当于原论文中的rnd[a]，初始为0。

RoA_Max的含义是某Acceptor已批准的提案的最大轮次（the max round of acceptance），相当于原论文中的vrnd[a]，初始值为0。

Value_Acc代表被当前已批准的提案，相当于原论文中的vval[a]，初始为NULL。

Proposer保存的信息为R_Max和Value_Pick。

R_Max表示某Proposer发起的最大轮次号，相当于原论文中的crnd[c]，初始值为0。

Value_Pick表示Proposer在P2-A阶段挑选的提案值，相当于原论文中的cval[c]，初始值为NULL。

R_Max和Value_Pick组合可产生一个提案：[R_Max,Value_Pick]，当然不是每轮都具备条件产生一个提案。

2.2原论文中的算法流程

Phase 1：
(a) A proposer selects a proposal number n and sends a prepare request with number n to a majority of acceptors.-->记作P1-A
(b) If an acceptor receives a prepare request with number n greater than that of any prepare request to which it has already responded,then it responds to the request with a promise not to accept any more proposals numbered less than n and with the highest-numbered proposal (if any) that it has accepted.-->记作P1-B

Phase 2：
(a) If the proposer receives a response to its prepare requests (numbered n) from a majority of acceptors, then it sends an accept request to each of those acceptors for a proposal numbered n with a value v, where v is the value of the highest-numbered proposal among the responses, or is any value if the responses reported no proposals.-->记作P2-A
(b) If an acceptor receives an accept request for a proposal numbered n, it accepts the proposal unless it has already responded to a prepare request having a number greater than n.-->P2-B

Fast Paxos[2]中的Section 2:The Classic Paxos Algorithm中作者给出了一个比较具体的算法流程（少数单词已根据本文语境做替换）：

P1-A:
If R_Max < i, then proposer starts round i by setting R_Max to i,setting Value_Pick to NULL, and sending a message to each acceptor a requesting that a participate in round i.
P1-B:
If an acceptor a receives a request to www.huayi1.cn participate in round i and i > RoP_Max, then a sets RoP_Max to i and sends proposer p a www.wanmeiyuele.cn message containing the round number i and the current values of RoA_Max and Value_Acc.
If i <= RoP_Max (so a has begun round i or a higher-numbered round), then a ignores the request.

P2-A:
If R_Max = i (so p has not begun a higher-numbered round),Value_Pick = NULL (so p has not yet performed phase 2a for this round), and p has received phase 1b messages for round i from a majority of the acceptors; then by a rule described below, p uses the contents www.mhylpt.com of those messages to pick a value v, sets Value_Pick to v,and sends a message to the acceptors requesting that they vote in round i to accept v.
P2-B:
If an www.hbs90.cn/  acceptor a receives a www.taohuayuan178.com request to vote in round i to accept a value v, and i >= RoP_Max www.leyouzaixan.cn and RoA_Max != i; then a votes in round i www.chushiyl.cn to accept v, www.chushiyl.cn sets RoA_Max and RoP_Max to i, sets Value_Acc to v, and sends a message to all learners announcing its round i vote.
If i < RoP_Max or RoA_Max = i (so a has begun a higher-numbered round or already voted in this round), then a ignores the request.

以上流程应该是比较精确的描述，英文本身的内容也不难理解，不再需要过多的翻译。本文也会遵循这个流程去模拟一些实例。

2.3 本文对算法流程的约定。

1、为方便起见，各阶段的消息通信以(X)或者(X,[Y,Z])或者([Y,Z])的形式表示，具体视情况而定。

2、P1-A中Proposer向Acceptor集合发送的提案请求称作Prepare请求，消息内容包括轮次号N：(N)。

3、P1-B中Acceptor的响应Proposer的过程称作Promise响应，消息内容包含轮次号和某提案（=提案编号+提案值）：(N,[K,VK])。

4、P2-A中Proposer向Acceptor集合发送批准请求称作Accept请求，消息内容是一个提案：([K,VK])。

## 三、实例及算法模拟

3.1 一个最基础实例

1）按照P1-A约定，Proposer发起轮次为1 的Prepare请求；

2）假设所有Acceptor均收到请求，按照约定P1-B，满足1大于所有Acceptor持有的RoP_Max值的条件，于是将自己的RoP_Max值设置为1，所有的Acceptor均响应Prepare请求，此时所有的Acceptor之前并未批准任何提案。

3）假设Proposer收到了所有的5个Acceptor的Promise响应，按照P2-A的约定，收到响应的数量已经超过Acceptor集合的半数，同时由于之前并未存在批准的提案，Proposer可以任意选择一个提案值，这里暂且记为选择了V1这个提案，Proposer应该发送Accept请求，希望Acceptor集合批准该提案。

4）假设所有Acceptor均收到了Accept请求，按照P2-B的约定，5个Acceptor尚未参与任何编号比1更大的提案（此时只存在一个Proposer且之前只发起了一轮提案），所以所有Acceptor应该批准V1这个提案，批准之后Acceptor的状态如下：

3.2 异常情况下算法的工作流程

1）初始状态

Acceptor集合持有状态：

Proposer持有状态：

2）Proposer发起第一轮Prepare请求；假设由于暂时网络中断或者网络分化等网络异常，只有Acceptor1和Acceptor5收到了提案请求，这两个Acceptor正常响应Prepare请求。

3）Proposer收到了这两个响应，此时根据P2-A的约定，响应数不足半数，不具备发送Accept请求的条件，于是Proposer重新发起第二轮Prepare请求。假定这次有四个Acceptor收到了请求，唯独发往Acceptor1的请求丢失了。成功收到消息的四个Acceptor给予正常响应。

4）Proposer也成功收到了四个响应，根据P2-A的约定，Proposer任选一个提案V1发送Accept请求：(2,V1)。但是Acceptor集合中只有Acceptor2和Acceptor3两个收到了这个Accept请求。此时[2,V1]只被两个Acceptor批准，目前为止仍然没有任何一个提案被选定。

5）Proposer发起第三轮提案Prepare请求，全部的Acceptor收到了提案请求，并给予响应。

6）Proposer收到全部的响应，应该评估这些响应，并从中响应的提案中挑选一个提案值。此时根据P2-A的约定，挑选的应该是最大的RoA_Max所对应的提案值。max{0,2,2,0,0}=2，对应的提案是V1，因此Proposer在本轮挑选的提案值为V1。Proposer向Acceptor集合发送Accept请求:[3,V1]，假设这次有Acceptor1，Acceptor3和Acceptor5收到了Accept请求并批准了该提案。

3.3 关于时序问题

3.4 “活锁”现象

3.5 关于Pcik a Value规则

Pcik a Value的规则可以说是该算法的核心，也是保证了该算法安全性的关键。

Acceptor当前状态（达到这种状态是完全有可能的）：

1）Aroposer以N=3发起第三轮Prepare请求：(3)，Acceptor1和Acceptor3收到请求，并作出响应。

2）Proposer成功收到响应，发起Accept请求：[3,V1]，但只有Acceptor1和Acceptor3收到了Accept请求，满足批准条件。

Proposer也必定收到了超过半数的Promise响应，否则无法发起Accept请求。然后Proposer挑选了VK，顺利发起了Accept请求：([k,VK])。（注意：因为前面已经设立了第K轮后VK被选定的题设，故这里Accept请求中必定是VK无疑，VK并非特指某一个提案，可以是任意一个，具有任意性。）

接下来发起第K+1轮的Prepare请求：(K+1)，假设这一轮也很顺利。

Proposer收到超过半数Acceptor的Promise响应，记这些半数以上的Acceptor集合为Q。此时可以断定，所有的这些Promise响应中，由RoA_Max组成的集合中最大值必定为K，因为集合S与集合Q的交集必定至少有一个公共元素。同时，这个RoA_Max=K的Promise响应中Value必定为VK，因为这就是在第K轮被集合S中每个Acceptor批准的提案。因此根据P2-A的约定，第K+1轮被挑选出来的Value是VK，该轮产生的提案是[K+1,VK],发送该提案希望Acceptor能够批准，当然在该轮的P2-B阶段，可能没有一个Acceptor批准VK（所有消息均丢失），也有可能某些Acceptor批准了VK。总之，经过第K+1轮之后，批准VK的Acceptor不会比第K轮减少，只会越来越多。

3.6 Learner学习被选定的提案

Learner学习的目的就是需要找出某一个超过半数的Acceptor批准的提案。要实现这一目的，最简单的办法是一旦Acceptor批准了一个提案，就将该批准的提案告知每一个Learner，显然从通信次数的角度来看，这样有点麻烦，至少需要Count(Acceptor)XCount(Learner)次通信才能确定被选定的。

## 四、一点总结

1）Paxos算法在网络通信比较好的情况下能够快速高效的让一个提案被半数以上的Acceptor接受，选定一个提案，从而达成一致意见。

2）Paxos算法的容错能力是2F+1。即在总共有2F+1个服务端的情况，只要不超过F个服务端同时出现损毁，该算法就能够正常运作。

2）采用“超过半数”的机制，保证在某轮次只能有一个提案没选定，采用Pick a Value规则挑选提案值，保证不同的轮次只能有一个提案值被选定。不同的轮次可能有不同的提案被选定，但是这些选定的提案仅仅是提案编号不同，其提案值必定相同。

4）当某个提案被选定，那么从此以后，所有的Acceptor只能批准该提案值，这是由Pick a Value的规则保障的。

5）假设所有的Acceptor都接批准某个提案值，将这些提案值的集合记为S（例如S={V1，V2，V3}），那么，即使现在尚未有提案值被选定，但是可以肯定，在将来被选定的提案值一定是集合S中的某一个提案值，绝不可能是其他的提案值了，保证了一种“封闭”特性。保证这个特性的正是P1-B中Acceptor响应给Proposer时的约束：Acceptor只会将自己曾经批准的提案中最高编号的提案响应给Proposer。举例来说，对于5个Acceptor来说，排除冗余情况，Proposer最多只有三次能够任选提案值的机会（收到所有的Promise响应中均为NULL并且Accept请求存在消息丢失），考虑任选提案值也有可能会选择到相同的提案值，因此集合S最多只能有三个不同的提案值。更一般的，当Acceptor集合的大小为奇数R时，集合S的大小最多为R/2+1。

## 五、 Reference

[1] Leslie Lamport. Paxos made simple.2001,11,1

[2] Leslie Lamport.Fastpaxos. DistributedComputing,19(2):79–103,2006.

[3] 《从Paxos到Zookeeper 分布式一致性原理与实践》

[4] 《分布式系统原理介绍 刘杰》

[5] http://www.infoq.com/cn/articles/wechat-paxosstore-paxos-algorithm-protocol