分布式事务之2PC

Posted 码农心经

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分布式事务之2PC相关的知识,希望对你有一定的参考价值。

2PC又称两阶段提交协议。

2PC是一个非常经典的强一致、中心化的原子提交协议

它执行过程中需要协调者、参与者两种角色,一个协调者中心化节点,N个参与者节点共同合作完成分布式事务操作。


下面以一个订单支付的场景案例进行对2PC协议的解析。

支付成功后,需要修改订单状态为支付完成,否则修改状态为支付失败。


2PC协议主要分为两个阶段:投票阶段、提交/执行阶段


第一阶段:投票

  1. 首先协调者收到请求后向参与者(订单服务)和参与者(支付服务)发出prepare预处理指令,通知它们进入2PC处理逻辑,并等待它们的响应。

  2. 订单服务修改订单状态为支付完成,但不commit,支付服务开始进行支付动态,但不commit。

  3. 支付服务支付成功后向协调者返回Yes,否则返回No,订单服务修改订单状态成功后向协调者返回Yes,否则返回No。


第二阶段:提交/执行(成功)

    4. 订单服务和支付服务在上一阶段都返回Yes后,协调者会向两个参与者发送commit指令。

    5. 订单服务和支付服务收到commit指令后会执行commit操作,至此,完成了整个事务操作。


第二阶段:提交/执行(失败)

    4. 在投票阶段如果参与者有其中一个返回的是No的话,那么协调者会向两个参与者发送rollback指令,通知两个参与者都回滚。

    5. 订单服务和支付服务收到rollback指令后,都会执行rollback。


上述就是2PC协议的整体执行流程,但是也存在非常明显的缺点。


2PC缺点

  1. 性能问题

    在2PC执行的整个过程中,参与者都需要等其他参与者执行完并向协调者响应Yes或No后才能执行commit/rollback操作,在等待的过程中资源是被锁定的,只有执行完commit/rollback操作才会释放,显而易见性能是低下的。

  2. 单点问题 

    1. 协调者单点

      1. 如果协调者在发送完prepare指令后宕机,则在参与者执行完相应逻辑后,回复Yes/No后,则再也无法收到协调者的指令,会一直等待,直到超时。

      2. 如果协调者在发送完commit/rollback指令后宕机,如果所有参与者都收到了commit/rollback指令影响不大,但是如果只有部分参与者收到了commit指令,那么就会导致数据不一致,如果只有部分参与者收到了rollback指令,这种情况不会导致数据不一致,因为未收到rollback指令的参与者会在等待超时后自动rollback。

      解决方案

      1.  协调者冗余,设置协调者备份,当协调者挂掉后,可启用备份协调者,原协调者记录日志,备用协调者可在原协调者宕机后,根据日志继续完成操作。

      2. 在协调者宕机后,可在参与者中重新选举一个新的协调者

    2. 参与者单点

      1. 如果参与者在收到prepare指令后,突然宕机,那么它就无法向协调者响应Yes/No,协调者会一直等待直到超时,最后向其他参与者发送rollback指令,进行回滚。

      2. 如果参与者在执行完相应逻辑向协调者响应Yes/No之前,与i会发生相同的现象。

      3. 如果参与者在收到commit指令后宕机,那么就会出现数据不一致的情况,因为其他参与者收到commit指令后进行commit操作。

      4. 如果参与者在收到rollback指令后宕机,不会出现数据不一致的情况,数据库会在事务超时后自动回滚。


以上是关于分布式事务之2PC的主要内容,如果未能解决你的问题,请参考以下文章

:分布式事务解决之2PC剖析

分布式事务之2PC

分布式事务之两阶段提交(2PC)

让您轻松理解分布式事务解决方案之2PC

分布式场景之刚性事务-2PC详解

分布式场景之刚性事务-2PC详解