[分布式事务-TCC] 4. TCC的优化方案之一:最末参与者优化(LPO)

Posted dm_vincent

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[分布式事务-TCC] 4. TCC的优化方案之一:最末参与者优化(LPO)相关的知识,希望对你有一定的参考价值。

文章导航

优化动机和指导原则

当一笔分布式事务的参与者较多时,同时每个参与者都涉及到一阶段和二阶段,还有异常场景下的幂等控制,空回滚以及防资源悬挂处理,调用关系会显著复杂化。特别当业务并发量很大的情况下。比如国内领先的第三方支付场景,并发量在高峰期十分惊人。

那么如何尽可能地提高分布式事务的性能就是一个值得深入思考的问题。

其实优化的原则也很直观:在能够满足业务诉求,保证各个参与方数据能够达成最终一致性的前提下,在下面两个方面努力:

  1. 增加系统的整体吞吐量
  2. 减少最终响应给终端用户的响应时间

那么反应在系统设计上,就是要想方设法减少网络调用的次数以及尽可能地降低每次调用的耗时。

没有调用就没有伤害。

在复杂的分布式网络环境下,减少一次非必要的调用很可能就可以显著地降低系统的整体复杂度。毕竟,调用即意味着耦合,无论是单体系统还是分布式系统,降低组件和系统间的耦合性都是我们孜孜不倦追求的目标。

最末参与者优化(LPO)

首先,我们就来看看名为最末参与者优化 - Last Participant Optimization的方案。它旨在减少分布式事务中的网络调用次数。

以之前跨行转账分布式事务的场景为例,看看这里存在的潜在问题:


可以看到,银行A既是分布式事务的发起方,同时它还是参与方之一。所以当银行A完成对银行B的一阶段调用成功之后,马上会开始自己的一阶段调用。如果都成功了,就会通知TC可以执行二阶段了。TC发起各个参与者的二阶段Commit。

我们来仔细观察一下事务发起方,参与者A的执行特点。

当参与者A的一阶段成功执行完成后,意味着分布式事务整体就可以进入到二阶段。TC会触发参与者A和参与者B的二阶段。也就是说,在参与者A的一阶段和二阶段之间隔着一次对TC的调用。调用TC的目的也只是让它感知到这笔分布式事务已经进入到二阶段了,希望TC能够排除万难尽一切可能推进各个参与方的状态到终态。

所以对于参与者A而言,当它成功执行完自身的一阶段之后,就可以认为它的二阶段的执行只是时间问题了。所以我们可以考虑将参与者A的一阶段和二阶段进行合并,也就是将它Try阶段和Confirm阶段合到一起。

那么在异常情况下,如果参与者A在执行合并后的Try和Confirm失败了,那么参与者的本地事务会首先回滚,清理参与者A的本地资源。然后通知TC需要回滚整笔分布式事务,TC随后就会发起参与者B的二阶段Rollback。

所以不管是在正常场景还是异常场景下,此时参与者A就变为了单阶段参与方:它只有一个合并了一阶段和二阶段的单阶段。这样做的结果就是参与者A单阶段的执行结果会决定整个分布式事务的结果:

  • 如果它执行失败了,那么TC会触发其它参与者二阶段Rollback
  • 如果它执行成功了,那么TC会触发其它参与者二阶段Confirm

顾名思义,因为参与者A自己是整个分布式事务的发起方和最后一个发起一阶段的参与者,所以这个优化方案被形象地成为最末参与者优化。

相应的,执行的时序变化为:


这个简单的优化,能够减少至少一次网络调用(TC调用参与者A的二阶段)的开销。减少网络调用不仅是降低了RT,更重要的是将系统执行的时序复杂度降低了。在对数据一致性有一定要求的高并发场景下,还是能够起到很大的作用。

总结一下这个优化方案的核心思想:

  1. 将发起方参与者的一阶段和二阶段操作合并成一个,让发起方作为单阶段的参与方。
  2. 发起方的提交结果会作为整个分布式事务的最终结果,TC的作用只是保证这个最终结果能够顺利地达成。

以上是关于[分布式事务-TCC] 4. TCC的优化方案之一:最末参与者优化(LPO)的主要内容,如果未能解决你的问题,请参考以下文章

[分布式事务-TCC] 4. TCC的优化方案之一:最末参与者优化(LPO)

[分布式事务-TCC] 6. TCC的优化方案之三:二阶段异步化

[分布式事务-TCC] 6. TCC的优化方案之三:二阶段异步化

[分布式事务-TCC] 6. TCC的优化方案之三:二阶段异步化

[分布式事务-TCC] 5. TCC的优化方案之二:同库优化

[分布式事务-TCC] 5. TCC的优化方案之二:同库优化