分布式理论之2PC协议(2阶段提交协议)

系列文章 -> 分布式理论html

  1. 分布式理论之CAP定理(布鲁尔定理)
  2. 分布式理论之BASE理论
  3. 分布式理论之2PC协议(2阶段提交协议)

2PC是什么

同前文,2PC也是缩写,即Two-phase Commit,即二阶段提交算法

目的

用以保证在分布式事务中,要么全部参与进程都提交事务,要么都取消事务,即实现ACID的原子性(A)。在数据一致中,它的含义是:要么全部副本(备份数据)同时修改某个数值,要么都不更改,以此来保证数据的强一致性。数据库

知识预备 - 预写式日志(Write-Ahead logging(WAL))

在计算机科学中,预写式日志(Write-ahead logging,缩写 WAL)是关系数据库系统中用于提供原子性和持久性(ACID属性中的两个)的一系列技术

二阶段提交算法成立的基本假设

  • 分布式系统中,存在一个节点做为协调者,其余节点做为参与者
  • 全部节点都采用预写式日志,且日志被写入后即被保持在可靠的存储设备上,即便节点损坏也不会致使日志数据消失
  • 全部节点不会永久性损坏,即便损坏后仍然能够恢复,且节点之间能够互相通讯

基本假设是有风险的segmentfault

  • 全部节点能够互相通讯,这个通常不是什么大问题,一般能够从新路由网络通讯
  • 全部节点不会永久损坏,这个问题很大,好比服务器炸了

二阶段提交具体操做

2PC.png

提交请求阶段(投票阶段)

第一阶段也被称做投票阶段,即各参与者投票是否要继续接下来的提交操做服务器

  1. 协调者节点向全部参与者节点询问是否能够执行提交操做(QUERY TO COMMIT),并开始等待各参与者节点的响应。
  2. 参与者节点执行询问发起为止的全部事务操做,并将undo信息和redo信息写入日志(预写式日志)。
  3. 各参与者节点响应协调者节点发起的询问。若是参与者节点的事务操做实际执行成功,则它返回一个"赞成"(YES)消息;若是参与者节点的事务操做实际执行失败,则它返回一个"停止"(NO)消息

提交执行阶段(执行阶段)

第二阶段也被称做完成阶段,由于不管结果怎样,协调者都必须在此阶段结束当前事务。网络

成功

当协调者节点从全部参与者节点得到的相应消息都为"赞成"时:分布式

  1. 协调者节点向全部参与者节点发出"正式提交"(COMMIT)的请求。
  2. 参与者节点正式完成操做,并释放在整个事务期间内占用的资源。
  3. 参与者节点向协调者节点发送"完成"(ACKNOWLEDGMENT)消息。
  4. 协调者节点收到全部参与者节点反馈的"完成"消息后,完成事务。

失败

若是任一参与者节点在第一阶段返回的响应消息为"终止",或者 协调者节点在第一阶段的询问超时以前没法获取全部参与者节点的响应消息时:post

  1. 协调者节点向全部参与者节点发出"回滚操做"(ROLLBACK)的请求。
  2. 参与者节点利用以前写入的undo信息执行回滚,并释放在整个事务期间内占用的资源。
  3. 参与者节点向协调者节点发送"回滚完成"(ACKNOWLEDGMENT)消息。
  4. 协调者节点收到全部参与者节点反馈的"回滚完成"消息后,取消事务。

2PC是否能够在任何状况下均可以解决一致性问题

咱们仅从理论上分析各类意外,由于实际的网络生产中,各类状况都有可能发生spa

协调者不一样阶段宕机的不一样现象

状况 分析及解决方案
协调者挂了,参与者没挂 只要找一个协调者的替代者,新的协调者询问全部参与者它们最后那条事务的执行状况,新协调者就知道该作什么样的操做了。这种状况不会致使数据不一致
参与者挂了(没法恢复),协调者没挂 若是挂了以后没有恢复,则不会致使数据不一致
参与者挂了(后来恢复),协调者没挂 恢复后参与者若是发现有未执行完的事务操做,直接取消,而后再询问协调者我应该怎么作,协调者就会比对本身的事务执行记录和该参与者的事务执行记录,告诉他应该怎么作来保持数据的一致
参与者挂了,协调者也挂了 须要再细分为几种类型来讨论,以下

参与者挂了,协调者也挂了的状况日志

  • 协调者和参与者在投票阶段挂了

    • 因为这时尚未执行提交操做,新选出来的协调者能够询问各个参与者的状况,再决定是进行提交仍是回滚。由于没有提交,不会致使数据不一致
  • 协调者和参与者在执行阶段挂了,可是挂的这个参与者在挂以前尚未作相关操做

    1. 选出新的协调
    2. 协调者询问全部参与者的状况。

      • 有参与者执行了roolback操做或投票阶段返回的信息是No,那么协调者指导参与者执行roolback操做。
      • 若是存在参与者执行了commit操做且其他参与者没有abort,那么协调者就指导参与者执行commit操做。由于挂掉的机器并无作 commit 或者 roolback 操做,而没有挂掉的机器们和新的协调者又执行了一样的操做,那么这种状况不会致使数据不一致现象
  • 协调者和参与者在第二阶段挂了,挂的这个参与者在挂以前已经执行了操做

    • 挂的参与者没有恢复:这种状况下,就变成和上述状况一致了,由于即便执行了,永远没有恢复就和没有执行时同样的。因此此时不会致使数据不一致现象
    • 挂掉的参与者恢复了:因为参与者在挂以前执行了操做,此时是没有人知道它执行了什么操做,它已经执行完了以前的事务

      • 若是它执行的是commit:此时这个挂掉且恢复的参与者和其它参与者保持一致了
      • 若是它执行的是roolback此时会致使数据的不一致,虽然这个时候能够再经过手段让他和协调者通讯,再想办法把数据变成一致的,可是,这段时间内他的数据状态已是不一致了

小结

2PC协议中,若是出现协调者和参与者都挂了的状况,有可能致使数据不一致。为了解决这个问题,衍生出了3PC,这是后话。

2PC 优缺点和解决方案

优缺点

  • 优势:原理简洁清晰、实现方便;
  • 缺点:同步阻塞、单点问题、某些状况可能致使数据不一致。

解决方案

关于这几个缺点,在实际应用中,都是对2PC 作了相应的改造:

  • 同步阻塞:2PC 有几个过程(好比协调者等待全部参与者表决的过程当中)都是同步阻塞的,在实际的应用中,这可能会致使长阻塞问题,这个问题是经过超时判断机制来解决的,但并不能彻底解决同步阻塞问题;
  • 协调者单点问题:实际生产应用中,协调者都会有相应的备选节点;
  • 数据不一致:在提交阶段,协调者和参与者都出现挂掉的状况下,是有可能致使数据不一致的,衍生出了3PC。

总结

在分布式系统中,每一个节点能够知道本身的操做是成功仍是失败,但没法知道其余节点的操做状态,为了在跨多个节点的事务中保持事务的ACID特性,咱们会引入一个“协调者”的组件来统一掌握全部节点(参与者)的操做状态,并指示这些节点(参与者)是否须要把操做结果进行真正的提交(好比将更新后的数据写入磁盘等等)。
所以,二阶段提交的算法思路能够归纳为:参与者将操做结果通知协调者,在由协调者根据全部参与者的反馈情报决定各参与者是否要提交操做仍是停止操做

参考

The Two-Phase Commit Protocol
二阶段提交
分布式理论(三) - 2PC协议
分布式系统的一致性协议之 2PC 和 3PC

相关文章
相关标签/搜索