关于 2PC/3PC

查看 17|回复 1
作者:giiiiiithub   
关于 2PC 和 3PC
本质上这是一个分布式环境下关于原子性的协议。也就是 N 个参与者对同一事务:要么都成功要么都失败。
理解它的关键是以“投票”模型来思考,这里的“票”仅仅是:参与者表示自己是否可以完成本次事务。2PC 的两个阶段:
[ol]

  • 投票阶段: 协调者向所有参与者分发投票请求。 参与者各自将投票结果上报给协调者(等同于告知协调者:自己(可以/不可以)完成本次事务)

  • 广播并执行投票意志阶段:协调者拿到所有参与者的投票后,开始向所有参与者广播投票结果,参与者根据投票结果来执行 commit or abort 。
    [/ol]
    问题的关键是:在投票阶段,有参与者的投票丢了怎么办?即:协调者还未收到所有参与者的投票就挂了,期间参与者也挂了。协调者恢复正常(或者重新选举)后,它还是得死等:挂掉的参与者重新恢复正常,再次问询它的投票是 yes or no ?得到回复后协调者才可以决定继续向前(commit)或者后退(abort)。它不能贸然进入第二阶段,告诉其他参与者投票结果是:abort or commit ,因为挂掉的参与者可能已经发出了 yes 的投票,也可能发出了 no 的投票,只不过他俩在次期间挂了,票丢在了半路上。
    丢票后必须死等参与者恢复,这是 2PC 被称为阻塞协议的原因。
    3PC 是通过引入临时状态寄存票选结果+超时,来解决阻塞问题的:
    在投票阶段达成一致的 yes 之后,再插入一个阶段: 去中心化投票结果阶段
    该阶段协调者向所有参与者分发一阶段的最终投票结果,参与者收到后会将其保存下来,并回复协调者:已保存。
    这一阶段使得所有参与者手中都有了一阶段最终投票结果,而不再是仅仅在协调者手中。
    所以:
    无论在哪个阶段,挂掉的协调者恢复(或重新选举)后,都可以根据之前的投票结果继续做出决策,而不是阻塞:
    [ol]
  • 未收到全体参与者在一阶段的投票结果,于是:等待,但不死等,超时后发起 abort 。
  • 有参与者说 no ,于是:发起 abort 。
  • 投票结果还未广播完成:于是:继续广播投票结果。
  • 投票结果已广播完成:于是:保持沉默。
    [/ol]
    而挂掉的参与者恢复后会向协调者或者其他参与者询问:这个事务在一阶段投票的最终结果是 yes 还是 no ? (优先询问协调者,如果协调者挂了,就询问其他参与者。注意:协调者如果超时不能恢复也会被重新选举,所以参与者总是能得到回复)。
    回复只有 3 个结果:
    [ol]

  • yes 。于是 commit 事务。该回复如果是来自其他参与者,那原因就是:其他参与者至少有一个已经进入了第二、第三阶段。

  • no 。 该回复如果来自其他参与者,那原因就是:有其他参与者已经收到协调者的 abort 请求。

  • 未知。 原因是:协调者挂了,其他参与者都处于一阶段,(或者也都挂了)。这种情况下安静等待协调者恢复(或者重新选举)后,做出的决策。协调者恢复后,会向所有参与者继续分发一阶段投票结果。
    [/ol]
    所以 3PC 不在阻塞的关键就是:
    引入中间阶段,在完成去中心化投票结果之前,可以放心 abort 。在去中心化投票结果完成之后,才去请求所有参与者执行投票意志,期间发生意外的的选手在恢复后可以问询其他选手投票结果。
    另外:
    以上像 保存票选结果 这类描述只是为了好理解,不涉及具体实现细节。
  • laminux29   
    这玩意本质上是数学的概率问题,甚至可以扩展到 nPC 、RAIDn 、纠删码等等。
    相关的还有谷歌的数据 3 副本可以保证正常情况下不会丢数据。
    您需要登录后才可以回帖 登录 | 立即注册

    返回顶部