[分布式事务-TCC] 5. TCC的优化方案之二:同库优化
Posted dm_vincent
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[分布式事务-TCC] 5. TCC的优化方案之二:同库优化相关的知识,希望对你有一定的参考价值。
同库优化
在上一篇文章中,介绍了最末参与者优化(LPO),它能够减少网络调用的开销。减少网络调用不仅是降低了RT,更重要的是将系统执行的时序复杂度降低了。在对数据一致性有一定要求的高并发场景下,还是能够起到很大的作用。
进行最末参与者优化后的时序如下:
以减少网络调用次数和每次调用的耗时为切入点,我们来思考一下看看还有没有优化的空间。
注意到发起方需要和TC的几次交互如下:
- 分布式事务开始时,发起方会向TC注册一条主事务记录。
- 参与者的一阶段(包括单阶段参与者)开始前都会向TC注册一条分支事务记录,同时在一阶段执行完毕之后还会向TC更新这条事务记录。
做这些事情的目的都是将事务的最新状态给同步到TC端,方便它执行每个参与者的二阶段,保证分布式事务最终能够达到终态。对于每个参与者而言,这一去一来就多了至少2次网络调用。如果一笔分布式事务的参与者数量较多的话,那么调用次数还是比较可观的。
所以很直观地,我们可以考虑一种方案将这些调用给省掉。原来主事务以及分支事务(其实也就是异常处理环节提到的事务控制记录)的持久化都是在TC端完成的,如果将它们直接保存到发起方的本地存储中不就可以将网络调用改成本地调用了吗?
这个想法很美好,但是还有一个问题需要解决。就是如果发生了异常,TC会抱怨它怎么知道该如何处理,毕竟事务的元数据都不在TC那儿持久化了。
其实这个问题也好解决,既然TC的任务是依赖事务元数据来保证事务的推进,那么当TC本身不再保存这些数据后,谁保存这些数据谁负责事务的推进就好了啊,正所谓“你行你上”。
所以此时TC的职责被发起方给承接了,发起方需要设置定时任务来批量获取未走到终态的事务,然后根据事务元信息推进它们。如何推进?找到对应的参与方,调用它们的二阶段方法即可,成功后再更改事务的状态。如果还不成功,那么等待下次调度继续重试。
秉持这个思路进行改造后,对应的时序图成了下面这样:
这里主要有两个重要的变更点:
- 原来单独的TC角色被事务发起方给承担了(深蓝色部分)
- 参与者B一阶段不会直接和TC交互,调用参与者B的参与者A代它完成分支事务的更新,这通常可以由拦截器等机制透明地实现,不需要侵入业务代码
优化后,由于发起方直接扮演了TC的角色,那么各个参与方和TC的交互基本上都从网络调用变成了本地调用,这无疑是质的变化。
对于业务量大的分布式事务发起方而言,这是最理想的一种架构,因为它显著地减少了网络调用的次数,对于系统的吞吐量和最终给用户的RT而言都能够起到极大的性能提升。
只不过在这种模式下,发起方承担的职责也更重了。它不仅要负责对各个参与方的调用,更需要扛起推进分布式事务状态的重任。单纯地从设计角度来说,这并非一个好的设计方案,无论是在类层面的单一职责原则(SRP),还是在组件层面的共同闭包原则(CCP)都被破坏了。
但是系统架构就是这样,没有银弹。
在不违背重大设计原则的前提下,根据业务发展的阶段找到最理想的落地方案才是正途。
以上是关于[分布式事务-TCC] 5. TCC的优化方案之二:同库优化的主要内容,如果未能解决你的问题,请参考以下文章
[分布式事务-TCC] 5. TCC的优化方案之二:同库优化
[分布式事务-TCC] 6. TCC的优化方案之三:二阶段异步化
[分布式事务-TCC] 6. TCC的优化方案之三:二阶段异步化
[分布式事务-TCC] 6. TCC的优化方案之三:二阶段异步化