• 分布式系统:怎么简单地解释Paxos算法?从二段提交、三段提交讲到Paxos


    原文:https://www.quora.com/Distributed-Systems/What-is-a-simple-explanation-of-the-Paxos-algorithm

    作者:Vineet GuptaShips software

    我想在一些尝试解决达成共识问题的案例中理解Paxos会比较容易,但也有不足之处,让我们讨论一下Paxos吧。

    对达成共识这个词语的直观理解是结婚宣誓:

    • “Do you …?” “I do!” “I do!”
    • “I now pronounce you …”


    假定现在婚礼限定只是两个人,而是像电视连续剧Robert Jordan’s Wheel中的 Aiel 人,一个或多个 Aiel 女人可以是 first-sisters ,一个男人要么娶了全部姐妹,要么一个都不能娶。对于 Aiel来说,婚礼宣誓的场景就变成这样了:

    • “Do you …?” “I do!” “I do!” “I do!” …
    • “I now pronounce you …”


    如果有任何一个 Aiel 姐妹不回答 “I do!” ,婚礼就无法进行了。

    计算机科学领域将这种情况称为二段提交。

    二段提交 (2PC)

    1. 投票阶段 – 一个协调者提交一个值给所有节点,然后收集所有节点的反馈 (无论它们是否同意这个值)。在我们的场景中,一个事务的协调者询问是否所有的资源管理者 (数据库服务实例,以下简称RMs )可以提交事务。 RMs回复 yes 或者 no.
    2. 提交阶段 - 如果所有参与者同意, 协调者联系所有节点让他们知道这个值是最终的值。如果有任何一个节点不同意,通知所有节点这个值不是最终值。在我们的场景中,协调者询问RMs提交或者终止事务。


    注意投票只真的提议的值 – 参与者节点只能说 yes 或者 no,它不能提议其它值。如果一个节点像提议一个值,那么它应该自己开启的二段提交过程。很明显这个算法可以起作用 – 参与者决定是否同意协调者提议的值。而且这个算法也没没那么低效率 – 对于 N 个节点, 只需要进行3N次通讯。

    但如果其中一个节点死机了怎么办?例如,假设协调者在第一阶段的时候死机了,提议的值已经发送到了其中一些参与者那里,但还没发送到全部参与者。

    • 现在一些节点已经开始二段提交进程了,但仍然有一些节点还没有收到任何信息,没有参与到二段提交当中。
    • 在我们的场景中,一个 RM 可能已经投完票了,然后锁定了一些资源等待下一步操作,可能会一直处于等待当中,等待协调者随时会恢复正常时继续第二阶段的操作。


    如果协调者在第二阶段的时候给部分参与者发送完提交命令后死机,也会有类似的问题。如果有其它节点检测超时然后接手协调者的工作,这个资源一直锁定等待的问题是可以解决的。这个节点可以和所有其它节点联系,从而发现它们的投票结果 (需要节点们持久化投票结果) 然后接手继续完成事务,但进一步参与者的失败可能会发生在此过程中,这样的话事务就永远不会恢复了。 最后结论 – 二段提交在节点失效时不具备可靠性。

    三段提交 (3PC)
    二段提交的关键问题是一旦协调者死掉了,没有任何参与者有足够能力来继续完成事务。这个问题可以通过增加一个额外的步骤来解决:

    1. 第一阶段 – 和以前一样 – 一个协调者向所有参与者提议一个值
    2. 第二阶段 – 这是新加进来的阶段 – 在上一个步骤接收到所有参与者回复 yes 之后,协调者发送一个准备提交的消息。参与者可以执行数据更新操作了,但是这是要保证这些更新对外不可见,即未提交状态,而且可以随时回滚
    3. 第三阶段 – 类似二段提交的第二阶段 – 如果协调者接收到所有的参与者的对“准备提交”命令的确认消息后,协调者就可以向所有参与者发送提交命令了。但是如果收不到所有参与者的对准备提交命令的确认消息,那么协调者就终止事务。


    现在如果协调者死机了,任何参与者都可以接手它的工作,查询所有节点的状态,继续进行事务

    • 如果任何 RM 向新接手的协调者报告自己没有收到 “准备提交” 命令,那么新的协调者就可以知道事务还没有开始提交。现在事务不能永久地终止也不能重新开始新的事务。
    • 如果一个已经提交事务的 RM 死掉了,我们知道其它 RM 已经接收和承认 “准备提交”命令,否则协调者不会到达提交阶段。所以协调者可以继续发送提交命令。


    所以三段提交可以工作得很好,除了没提交的节点操作失败的情况。当然,增加一个阶段会导致更多得通讯延迟。

    在网络分隔的情况下(例如:一个集群两拨服务器之间通讯中断,会形成两个集群,可以说是脑裂)。假如所以接收到 “准备提交”命令的RM在其中一拨,另外的RM在另外一拨。现在每一拨RM各自选出新的协调者,就有两个协调者,如果一个协调者提交了事务,另外一个协调者终止了事务,那么当网络分隔取消的时候一拨RM提交了事务,另外一拨RM取消了事务,这样就造成了不一致的状态。


    Paxos - 为什么要用Paxos?
    第一 – 除了三段提交我们还有什么更好的方法吗?唯一的问题是网络分隔,是吧?为了开始,让我们假设网络分隔是唯一的问题(事实上这不是唯一的问题,等一下我们会提到)。网络分隔的问题是否值得去解决?今天,云计算和英特网范围的服务,不同的服务器之间可能跨洋跨大陆,我们需要一个分区容忍性算法。

    第二点网络分隔不是唯一的问题。 当我们着手处理阶段永久失败的情况,最常见的情况是服务器死机,然后从死掉的地方重新恢复。这种失败-恢复模型也可以描述一个节点回应消息无时间上限的异步网络模型,因为你不能假设一个节点死掉了 – 它们可能只是慢一点或者网络慢一点。在这个模型,你不能设置超时。

    三段提交是失败-停止,但不是失败-恢复。不幸的是真实的需求往往要求失败-恢复,因此我们需要更通用的解决方案。这就是Paxos协议诞生的原因

    Paxos – 实现原理
    在Paxos中,最基本的步骤很像二段提交:

    • 选择一个节点作为提议者
    • 提议者选择一个值,然后发送给所有接受者。接受者可用回复拒绝或接受
    • 一旦大多数节点接受提议,共识就达成了,协调者向所有接受者发送提交命令


    和二段提交主要的不同是,不像二段提交需要所有节点同意,这样只需要大多数节点同意即可。这是个有趣的想法。这保证了在一个回合内,如果大多数节点同意了一个值,而后的任意节点尝试提议一个值的时候都会学习大多数节点同意的那个值。这也意味着 Paxos 不会阻塞,即使一小半节点响应失败。
    当然协调者本身也可能失败。为了处理这个问题, Paxos 不会只指定一个协调者那么简单。它允许任何节点都可以成为协调者。两个协调者可能提议不同的值,那么怎么协调达成共识呢?为了解决共识达成一致的问题 Paxos 引入了两个机制:

    • 分配一个序列号给协调者。 不同协调者的序列号不同,这样可以防止旧的协调者 (例如从失败中恢复过来的协调者) 对达成的共识有异议。
    • 限定协调者的选值。一旦共识达成,Paxos 强制让后来的协调者选择已有的值,保证共识延续。这个可以通过让参与者发送自身同意的最新的值以及协调者的序列号来获得。新的协调者可以选择选择参与者返回的其中一个值,当没有任何参与者返回值的时候,就选择自己的值。


    协议的步骤:

    1) 准备阶段

    • 一个节点选择成为一个协调者,然后选择了一个序列号 x 和一个值 v 来建立一项提议 P1(x, v)。 它将这个提议发送给所有参与者,然后等待大多数参与者的响应。
    • 参与者接收到了提议 P1(x, v1) ,然后做如下事情:
      • 如果收到的是第一个提议,就回复 ‘agree’ – 它承诺会拒绝后来序列号 < x的所有请求
      • 如果已经同意过某个提议:
        • 将 x 和它同意过的最大的序列号的提议 P2(y, v2)对比
        • 如果 x < y, 回复 ‘reject’ 和 y
        • 如果 x > y, 回复 ‘agree’ 和 P2(y, v2)


    2) 接受阶段

    • 如果大多数参与者失败或者回复拒绝,协调者会抛弃提案然后重新开始
    • 如果大多数参与者回复“同意”, 协调者也会接收到它们收到的提议的值。协调者拿到这些值任意一个 (如果还没有值被接受就用它自己的值) 然后发送一个“请接受我”的请求,这个请求会带上一个序列号和一个要提议的值。
    • 当参与者接收到一个“接受请求”的消息,当满足下面的两个条件的时候,它会发送一个‘接受’ 消息, 否则会发送一个拒绝消息:
      • 值和之前接受的任意值相同
      • 序列号是参与者所接受所有值的最大值
    • 如果协调者没有得到大多数参与者 ‘接受’ 的消息,它的提议将会被摒弃,重新开始一次事务。然而如果协调者没有得到大多数参与者的“接受”,事务可以终止了。为了优化,协调者可能发送 ‘提交’ 命令给其它节点


    Paxos 处理失败
    如果授权时Paxos只有一个协调者, 用授权来代替投票,所有节点都必须投票吗?你猜对了 – 二段提交就是这样的。 二段提交是Paxos的某个特殊情况。

    如你所见, Paxos  比二段提交有更高的失败容忍性:

    • 协调者失败 – 另外一个协调者可以代替它,提出自己的提议。
    • 原来的协调者恢复 – 两个协调者可以同时存在,多亏了这个规则:只同意最大的序列号以及只能提交前一个同意的值


    Paxos也比三段提交更具有容错性。特别地,Paxos的分区容忍性不同于三段提交。在三段提交,如果两个隔离的分区同意了一个值,当分区合并的时候,就会出现违反一致性的情况。在Paxos,这种情况是不会出现的,因为有大多数选票机制。除非一个分区有大多数参与者同意,否则不会达成一致。如果一个分区有大多数参与者同意能够达成一致,这个值会被其它分区采取。

    Paxos的一个问题是两个协调者,不能互相观察,当有分区隔离的时候,可能会尝试提出一个比前一个提议更高的序列号的提议。这会导致Paxos事务永远不会休止(成为活锁)。尽管两个协调者期望观察另外一个,并且其中一个需要退出。

    这是个安全和可用性之间的平衡。Paxos是一个安全的算法 – 一旦共识达成,被同意的值不会改变。然而 Paxos不保证可用性 – 在某些很少的情况下它会终止。事实上一个异步的一致性算法不能同时保证安全和可用性,这被称为 FLP 不可能结果.

    译者注:已经翻译完毕,但可能存在翻译语言生硬、可读性和可理解性差等问题,以后有时间再完善,谢谢关注。

    进一步阅读

      • Principles of Transaction Processing, Chapter 8 provides a detailed overview of the Two Phase Commit
      • Non-blocking Commit Protocols - original paper by Dale Skeen that describes 3PC
      • The Part-time Parliament – the original Paxos paper by Lamport. It uses a parliament analogy which people found hard to get past when the paper was originally published.
      • Paxos Made Simple – the rewrite by Lamport without the Parliament analogy. While simple, one can miss the forest for the trees. Requires multiple readings to grok.
      • Paxos Made Live – Google’s description of their Paxos implementation. The most readable of the Paxos papers.
  • 相关阅读:
    数的划分终极版--背包法解决各类数的划分
    128.最长公共子序列
    整数划分类型题目--专练
    主函数
    LED类代码
    APM2.8地面站下载地址
    多文件函数调用
    流水灯
    APM的3DR无线数传的安装和调试
    闪烁的LED灯
  • 原文地址:https://www.cnblogs.com/pathrough/p/5112966.html
Copyright © 2020-2023  润新知