Paxos Made Simple [续][原文解释版][转载]

    有兄弟说上一篇关于 paxos 算法的文章不够清楚, 于是我从 fast paxos 这篇文章中, 把对 basic paxos的介绍的章节选择性翻译出来, 放到这里给大家做参考.

    下面的内容都集中关注于算法的有效性证明, 至于算法的具体实现, 优化等, 都不做介绍.
    所有的基本概念, 基本定义这里不再重复, 默认大家已经了解了算法的总体的目的, 主要的角色.

 

    括号中的内容是我加的一些解释, –基本都是多余的—, 其他的都可以在 fast paxos 这篇文章的 2.2 章节找到. 
 
    算法会执行很多个 round. 每个 round 都使用一个正整数进行编号. round 并不需要按照它们编号的次序去执行,  一个 round 不必须被完整的执行, round 可以被直接跳过, 不同的 round 可以同时并行的执行. 一个 round 可能选择一个 value.  一个 round 中, 一个 acceptor 可以投票给某个 value 或者不投票(不可以投票给不同的value).  
    
    为了达到一致性, 不能让两个不同的 value 被投票通过. 因为一个 round 里, 任何一个 acceptor 只能给一个 value 投票. 那么任何一个 round 中, 经过一个多数派批准的 value 一定是单一的, 不可能出现在一个 round 中, 两个不同的 value 都得到多数派的批准的情况. 但是一个 acceptor 在不同的 round 中可以投票给不同的 value, 所以保持一致性的关键在于在不同的 round 中, 要保证不会有不同的 value 被选出.

 

    每个 acceptor a 需要记住下面这些信息:

 

    rnd[a]  a 参与的所有 round 中编号最大的那个. 初始值为0。 0不是一个 round 的编号, 0表示没参与任何round

 

    vrnd[a] a 投过票的所有 round 中编号最大的那个 round, 初始值为0。 vrnd[a] <= rnd[a] 总是成立的.

 

    vval[a] a 在 vrnd[a] 这个 round 中, 投票批准的 value 值. 初始值, 也就是当 vrnd[a] = 0 时的值, 无意义.

 

    任何一个 round i 都具有一个被预先指派好的 coordinator(leader). coordinator 负责选出本 round 大家要投票的 value. coordinator c 需要保持以下信息:
    
    crnd[c] c 启动的所有 round 里编号最大的那个, 初始值为0。
    
    cval[c] c 在 round crnd[c] 中, 所挑选的用于投票的 value. 如果 c 在 round crnd[c] 中还没有挑选 value 则为 none. 初始值无意义.

 

    这里要求每个 round 中有一个事先指派好的 coordinator. 如何确定这个 coordinator 不在这里讨论, 有很多方式在绝大多数情况下可以很好的选出唯一的一个 coordinator. 而且即便选择 coordinator 的算法在特殊情况下失败, 导致系统中有不止一个 coordinator 确信自己是唯一的 coordinator, 也不影响下面描述的一致性算法的正确性.
    
    round i 按照下面的阶段进行, 其中 c 是本 round 的 coordinator.

 

    1  (a) 如果 crnd[c] < i 则 c 设置 crnd[c] 为 i, 从而开始 round i. 先把 cval[c] 设置成 none, 然后给所有的 acceptor 发请求, 要求它们加入到 round i中来.

 

        (b) 如果一个 acceptor a 收到了要求加入 round i 的请求, 并且 i > rnd[a],  那么 a 把 rnd[a] 置成 i, 然后向 coordinator c 发送一个消息. 消息包含了 round 的编号 i, 以及 a 的两个当前值 vrnd[a] 和 vval[a].
             如果i <= rnd[a], 这说明, a 已经开始了 round i, 或者是开始了一个编号更高的 round. 那么 a 就简单的忽略该请求.

    2 (a) 当 c 收到1b 消息的时候, 因为消息中有 round 的编号, 不妨设为i, 如果 crnd[c] = i, 那么说明 c 没有开始一个更高编号的 round. cval[c] = none 说明 c 在本round 没有执行2a阶段的操作. 这个时候, 如果c 从一个 acceptor 的多数派中收到本 round 的1b 阶段的消息, c 可以根据一定的规则选择一个 value v, 设置 cval[c] 为 v, 并且向所有的 acceptor 发请求, 要求它们在 round i 投票给 v.  选择 v 的规则后面详述.

       
       (b) 如果一个 acceptor a 收到了一个请求, 要求它在 round i 投票给 value v, 并且 i >= rnd[a] and vrnd[a] <> i; 那么 a 在 round i 投票给 v, 并且设置 vrnd[a] 和 rnd[a] 为 i, 设置 vval[a] 为 v, 然后发消息给所有的 learner, 宣布它的 round i 的投票结果.

 

            如果 i < rnd[a] 或者 vrnd[a] = i, 说明 a已经开始一个编号更高的round 或者在round i中 已经投过票了, 那么 a 忽略该请求.

 

    learner 如果在 round i 中, 收到acceptor 中一个多数派的 2b 消息, 都宣称它们已经投票给 value v, 那么 learner 可以确认 v 获得了通过.
    
    一个 coordinator 可以在任何时候开始一个新的 round 并且开始执行 1a 阶段的动作. 只要这个 round 的编号不低于它已经开始执行了的 round的编号. 不同的 round 可以同时执行, 但是, 一个 acceptor 如果收到了编号更高的 round 的消息, 它必须停止参与当前的 round. 阶段 2a 是允许在不同的round 里发送不同的 value 的. 但是在一个特定的 round 中, 不会出现不同的 value 被发送.

 

    算法的核心部分在于如何在阶段2a中挑选一个合适的value v. 为了保证一致性, 这个 v 应该有什么样的属性呢?
    
    CP. 对于任意 round i 和 j , j < i, 如果一个 value v 在round j 已经被批准通过, 或者有可能被批准通过, 那么, 在 round i, 没有 acceptor 可以批准 v 以外的值.

 

    CP.的一个等价的表述是: 对于任意的 round i 和 j , j < i, 如果一个 acceptor 在 round i 批准了 v, 那么在 round j 被批准通过, 或有可能在 round j 被批准通过的值只有v.
    
    我们前面已经说过, 在同一个 round 中, 不可能有两个不同的 value 被批准通过(因为批准通过需要一个多数派, 按照我们的规则, 不可能有两个不同的 value 在同一个 round 中都得到了多数派的批准), 而 CP 实际上保证了在不同的 round 中, 不会有不同的 value 被批准通过. 所以 CP 保证了一致性.

 

    算法只有保持属性 CP 就能保证一致性, 因为 round i 中的 v 是 coordinator 在阶段 2a 中挑选出来的, 所以我们只需要确定 v 满足如下的属性:

 

        CP(v,i)  对于任何的 round j, 其中 j < i. 除了 v , 其他的 value 都不可能被批准通过.

 

    先看在 round j 中 v 被批准通过或者有可能被批准通过的条件. 当且仅当, 存在一个多数派Q, Q 中的每一个 acceptor 要么在 round j 中投票给了 v, 要么在 round j 中还没有投票. 我们注意到, 一个 acceptor a从来不会减小 rnd[a] 的值, 并且, 在 round j 中, 如果 j < rnd[a] 它就会忽略 round j的投票请求, 所以我们有:

 

    Observation 1  一个 value v 在 round j 被批准通过, 或者可能被批准通过的条件是, 有一个多数派Q, 其中 Q 中的每一个 acceptor a, 要么在 round j 投票给 v, 要么满足 rnd[a] <= j(还没有在round j 投票).

 

    因为任何两个多数派, 最少有一个公共成员, 所以 observation 1 暗示了下面两个 observation.

    observation 2 如果有一个多数派 Q, 其中 Q 中的每一个 acceptor a 满足rnd[a] > j 并且, 在round j 没有投票, 那么 round j 不可能批准任何值.

    observation 3 如果存在一个多数派Q和一个 value v, Q 中的每一个 acceptor a 满足 rnd[a] > j, 并且 a 要么在 round j 投票给 v, 要么在 round j没投票. 那么round j不可能批准除 v 之外的任何 value.
    
    假设 coordinator 从一个多数派Q收到了 round i的阶段1b的消息. 因为一个acceptor a 在发送了1b消息的时候会设置 rnd[a] 为 i, 并且 acceptor 从来不会减低rnd[a] 的值, 所以对于Q中的所有 acceptor 来说, 均满足 rnd[a] >= i. 用 vr(a) 和 vv(a) 来表示 acceptor 在消息 1b 中汇报的值 vrnd[a] 和 vval[a]. 让k取得Q中vr(a)的最大值, 我们考虑两种情况:
    
    K1 k=0
    K2 k>0

 

    在情形K1, 因为Q中的每个 acceptor a, 都有vrnd[a] = 0, 所以对于任何 round j, j < i, Q中的acceptor 都没有投票批准任何的 value. 根据 observation 2, 我们知道在任何 round j, j<i, 不可能有任何的value被批准, 或者有可能被批准. 这种情况下, coordinator 选择任何vaule v, 都可以满足CP(v,i), 这个时候, coordinator 只需要在被提议的 value 中选择一个就可以了.

 

    在情形K2, 至少一个acceptor 汇报说在 round k 投过票, 没有 acceptor 在round j ,j>k, 中投过票. 我们让 a0 为Q 中在round k投过票的 acceptor, 于是有 vr(a0) =k. 在阶段2a, coordinator 要选出的 value 就是 vv(a0). 为了证明这种选择满足CP(v,i), 我们必须证明, 对于任意的 round j, j <i, 除了 value v外, 不可能有其他的value 被选出或者可能被选出. 因为 vrnd[a] <= rnd[a] 并且 acceptor a 只有在 i > rnd[a] 的时候才会回复 round i的消息, 所以 k < i. 我们将证明分为下面三种情况.

 

    当 k < j < i, 用 a 表示 Q 中的任意一个 acceptor, vr(a) 是a投过票的 round 中编号最大的那个, 所以 vr(a) <=k < j, 所以在那个时候 a 还没有在round j进行投票. 因为它回复 round i的消息的时候会把rnd[a] 设置成i, 并且保证不会对编号小于i的round 投票, 所以 Q 中的acceptor 都不会在 round j中进行投票, 通过 observation 2 我们知道, 在round j 不会有任何value 被选出, 或者有可能被选出.

    当 j=k, acceptor a0 在 round k中投票批准了value v, 那么它设置 srnd[a0] 为k, vval[a0] 为v. 因为acceptor 只能对 coordinator 提议的 value 投票, 所以, 每一个acceptor 要么在round k中投票给了v, 要么没参与投票.(这里我来解释一下, 虽然系统中可能有多个 coordinator 相信自己是唯一的 coordinator, 但是他们开始在一个round里提出value之前, 必须得到一个多数派的加入该round的回应. 这保证了即便选择coordinator的算法失败, 系统中有多个coordinator, 被提出开始投票的 value 仍旧是唯一的).  因为Q中的任意 acceptor a, 都满足rnd[a] >= i >k. 通过 observation 3, 我们知道, 除了 value v以外, 不可能有其他的 value 在round j被批准或者可能被批准.

 

    当j<k, 通过归纳法, 我们可以假定 CP 一直保持着, 当 acceptor a0 在 round k 投票给 v 就说明了在round j 不可能有 v 以外的 value 被批准.

 

    至此, 我们证明了在同一个round 中, 不会有超过一个的value 被批准, 又证明了, 在不同的 round 中, 也不会有超过一个value 被批准, 所以一致性得到了保证.

 

    下面是选择value的具体方法:

 

    设Q是在round i中 发送了消息 1b 的任一多数派.
    vr(a) 和 vv(a) 是 Q 中 acceptor a在消息1b中汇报的 vrnd[a] 和 vval[a].
    k 是 Q 中的 a 所汇报所有的 vr(a) 中最大的那个
    V 是Q 中当vr(a) =k 时, vv(a) 的集合.
    如果 k=0 , 则 v 可以是任何被提议的 value.
    否则 V应该只包含一个元素, 选择该元素为 value.

注:本文转载自 http://rdc.taobao.com/blog/cs/?p=261
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值