分布式事务之2PC
Posted 码农心经
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分布式事务之2PC相关的知识,希望对你有一定的参考价值。
2PC又称两阶段提交协议。
2PC是一个非常经典的强一致、中心化的原子提交协议。
它执行过程中需要协调者、参与者两种角色,一个协调者中心化节点,N个参与者节点共同合作完成分布式事务操作。
下面以一个订单支付的场景案例进行对2PC协议的解析。
支付成功后,需要修改订单状态为支付完成,否则修改状态为支付失败。
2PC协议主要分为两个阶段:投票阶段、提交/执行阶段
第一阶段:投票
首先协调者收到请求后向参与者(订单服务)和参与者(支付服务)发出prepare预处理指令,通知它们进入2PC处理逻辑,并等待它们的响应。
订单服务修改订单状态为支付完成,但不commit,支付服务开始进行支付动态,但不commit。
支付服务支付成功后向协调者返回Yes,否则返回No,订单服务修改订单状态成功后向协调者返回Yes,否则返回No。
第二阶段:提交/执行(成功)
4. 订单服务和支付服务在上一阶段都返回Yes后,协调者会向两个参与者发送commit指令。
5. 订单服务和支付服务收到commit指令后会执行commit操作,至此,完成了整个事务操作。
第二阶段:提交/执行(失败)
4. 在投票阶段如果参与者有其中一个返回的是No的话,那么协调者会向两个参与者发送rollback指令,通知两个参与者都回滚。
5. 订单服务和支付服务收到rollback指令后,都会执行rollback。
上述就是2PC协议的整体执行流程,但是也存在非常明显的缺点。
2PC缺点
性能问题
在2PC执行的整个过程中,参与者都需要等其他参与者执行完并向协调者响应Yes或No后才能执行commit/rollback操作,在等待的过程中资源是被锁定的,只有执行完commit/rollback操作才会释放,显而易见性能是低下的。
单点问题
协调者单点
如果协调者在发送完prepare指令后宕机,则在参与者执行完相应逻辑后,回复Yes/No后,则再也无法收到协调者的指令,会一直等待,直到超时。
如果协调者在发送完commit/rollback指令后宕机,如果所有参与者都收到了commit/rollback指令影响不大,但是如果只有部分参与者收到了commit指令,那么就会导致数据不一致,如果只有部分参与者收到了rollback指令,这种情况不会导致数据不一致,因为未收到rollback指令的参与者会在等待超时后自动rollback。
协调者冗余,设置协调者备份,当协调者挂掉后,可启用备份协调者,原协调者记录日志,备用协调者可在原协调者宕机后,根据日志继续完成操作。
在协调者宕机后,可在参与者中重新选举一个新的协调者
参与者单点
如果参与者在收到prepare指令后,突然宕机,那么它就无法向协调者响应Yes/No,协调者会一直等待直到超时,最后向其他参与者发送rollback指令,进行回滚。
如果参与者在执行完相应逻辑向协调者响应Yes/No之前,与i会发生相同的现象。
如果参与者在收到commit指令后宕机,那么就会出现数据不一致的情况,因为其他参与者收到commit指令后进行commit操作。
如果参与者在收到rollback指令后宕机,不会出现数据不一致的情况,数据库会在事务超时后自动回滚。
解决方案
以上是关于分布式事务之2PC的主要内容,如果未能解决你的问题,请参考以下文章