来源:微信公众号蚂蚁金服“金融级分布式架构”Antfin_SOFA,
为你解读 SOFA-DTX 分布式事务的设计演进路线上篇
为你解读 SOFA-DTX 分布式事务的设计演进路线下篇
蚂蚁金服内部结合BASE 理论的思想,选择在业务层实现 2PC(两阶段事务提交)的方式来解决该问题。
BASE 理论是指 BA(Basic Availability,基本业务可用性);S(Soft state,柔性状态);E(Eventual consistency,最终一致性)。该理论认为为了可用性、性能与降级服务的需要,可以适当降低一点一致性的要求,即“基本可用,最终一致”。
如本文开篇所述,蚂蚁金服大部分系统的分布式事务解决方案以BASE最终一致性思想为基础,在业务层实现两阶段提交的 TCC(Try-Confirm-Cancel)分布式事务解决方案,以确保在一致性问题的保障和性能方面达到最佳平衡。
TCC 分布式事务模型包括三部分,如下所示
主业务服务:主业务服务为整个业务活动的发起方,服务的编排者,负责发起并完成整个业务活动。
从业务服务:从业务服务是整个业务活动的参与方,负责提供 TCC 业务操作供主业务服务调用
初步操作 Try:完成所有业务检查,预留必须的业务资源。
确认操作 Confirm:真正执行的业务逻辑,不作任何业务检查,只使用 Try 阶段预留的业务资源。因此,只要 Try 操作成功,Confirm 必须能成功。另外,Confirm 操作需满足幂等性,保证一笔分布式事务有且只能成功一次。
取消操作 Cancel:释放 Try 阶段预留的业务资源。同样的,Cancel 操作也需要满足幂等性。
业务活动管理器:业务活动管理器管理控制整个业务活动,包括记录维护 TCC全局事务的事务状态和每个从业务服务的子事务状态,并在业务活动提交时调用所有从业务服务的Confirm 操作,在业务活动取消时调用所有从业务服务的Cancel 操作。
1.1.1 TCC 与 XA 对比 --- 并发性优势
TCC 把两阶段拆分成了两个独立的阶段,通过资源业务锁定的方式进行关联。资源业务锁定方式的好处在于,既不会阻塞其他事务在第一阶段对于相同资源的继续使用,也不会影响本事务第二阶段的正确执行。
XA 模型的并发事务
TCC 模型的并发事务
从上面的对比可以发现,TCC 模型相比 XA 模型进一步减少了资源锁的持有时间。XA 模型下,在 Prepare 阶段是不会把事务1所持有的锁资源释放掉的,如果事务2和事务1争抢同一个资源,事务2必须等事务1结束之后才能使用该资源。
而在 TCC 里,因为事务1在 Try 阶段已经提交了,那么事务2可以获得互斥资源,不必再等待事务1的 Confirm 或 Cancel 阶段执行完。也就是说,事务2的 Try 阶段可以和事务1的 Confirm 或 Cancel 阶段并行执行,从而获得了一个比较大的并发性能提升。
1.2.1 极致性能优化之同库模式
之前的业务活动管理器是一个单独的服务,每次启动业务活动、登记业务操作、提交或回滚业务活动等操作都需要与业务活动管理器交互,并且交互次数与参与者个数成正相关。
因此,为了追求极限性能,将业务活动管理器的远程存储替换成本地存储,如下所示:
减少了 RPC 的调用,同时还会做一些减少存储次数的优化,从而获得性能收益。
通过这种方式,减少 RPC 调用耗时,大幅降低事务执行时间。同时还针对支付、账务等访问频繁的特殊从业务服务,优化处理过程,不再创建单独的分支事务记录,而是将这个信息与主事务记录合并,在创建主事务记录的同时,记录分支事务,最大程度减少与数据库的交互次数,从而获得更高的性能收益。
下面是同库模式优化前后的时序图对比:
优化前时序图
优化后时序图
其中,绿色方块表示本地数据库访问。可以发现,优化后减少了:(2+n) 次 PRC 延迟 + 1次数据库访问延迟(n表示参与者个数)。
1.2.2 极致性能优化之异步化
从理论上来说,只要业务允许,事务的第二阶段什么时候执行都可以,因此资源已经被业务锁定,不会有其他事务动用该事务锁定的资源。如下图所示:
这就是 TCC 分布式事务模型的二阶段异步化功能,各从业务服务的第一阶段执行成功以后,主业务服务就可以提交完成,框架会保证正确记录事务状态,然后再由框架异步的执行各从业务服务的第二阶段,从而比较完整的诠释最终一致性。
大促的尖峰时刻是从零点开始的几十秒或一分钟之内,在这个时刻的交易,我们会把二阶段的操作从同步转成异步,在冲高的那一刻,二阶段就停止了,一阶段正常扣款,等着交易零点三十分或者夜里一点开始回落的时候,我们才开始打开二阶段,集中做二阶段的动作。
优化后,Confirm 阶段在空闲时段异步执行:
假设 Confirm 阶段与 Try 阶段耗时相同,单个事务耗时减少50%
数据库资源消耗减少50%
本篇总结
为了满足支付业务的核心需求,保障分布式环境下交易一致性。蚂蚁基于 BASE 思想,在业务层实现了 TCC 模型,
并且为了业务发展的需求,优化了其工程实践,实现海量并发处理能力,让它的性能可以达到比业界其它产品高很多的状态。
接着,上层业务系统的复杂、业务种类的丰富等等业务需求向分布式事务提出了更高的要求,我们如何思考和应对的呢?
我们在 TCC 模型基础上又加入了框架托管(FMT)模型,其简单易用,对业务无侵入的特点,可以较好的解决金融云场景下接入便捷性问题。
在2014年蚂蚁金服全面开启了金融云时代,也会对外赋能合作方和客户。在这些新的场景下面,分布式事务产品面临新的挑战,客户的性能需求可能不像蚂蚁金服内部要求那么高,而是更关注接入的便利性和通用性,要求简单易用,对业务代码无侵入。因此,分布式事务产品开始全面升级,满足更多客户对云端产品的需求。
TCC 模型作用于业务层,负责协调从业务服务的最终一致性。所有被纳入到分布式事务的从业务服务,需要为框架提供Try、Confirm、Cancel三个方法,并且需要满足幂等性。由于方法实现和要满足的约束条件都需要业务方提供,这无疑就大大提高了接入门槛。所以我们在TCC 模型上继续往前推进发展,提出了FMT 模型来解决接入便捷性的问题。
FMT 分布式事务模型与 TCC 模型类似,也同样包含主业务服务、从业务服务、业务活动管理器,如下所示:
不同的是,从业务服务不再需要提供 Try、Confirm、Cancel三个方法,而是直接按照JDBC 标准,通过托管框架与底层数据库交互,就像使用普通数据源一样。托管框架对业务来说是透明的,主要负责解析SQL语义,自动生成两阶段操作。
托管框架的两阶段操作如下图所示:
FMT 框架要求从业务服务只需要正常执行SQL操作就可以了,框架会把业务的本地事务操作作为第一阶段。在第一阶段,框架会拦截用户SQL,解析SQL语义,然后把业务SQL涉及数据执行前后的状态保存下来,即数据快照,这个就相当于在逻辑上完成了数据库内的undo和redo操作。在第二阶段,如果这个事务要提交,那么框架直接把快照数据删除就可以了,因为第一阶段的正常操作已经执行完成。如果该事务要回滚,那么会先校验脏写,根据第一阶段保存的执行后的快照,检查在本事务执行过程中,数据有没有被其他操作修改,如果没有,则把数据执行前的快照拿出来,完成回滚操作。
举个例子,上图左边这张表有两列,一列是账号,另一列是金额。这时如果要针对该账户执行一条update操作,框架会怎么做呢?
在 update 之前,会先把账户的金额保存下来,执行 update 操作,然后把执行之后的金额保存下来。因为在二阶段有可能会是回滚操作,回滚的时候如果想把执行之前的数据覆盖回去的话,必须要保证在覆盖的那个时刻,这些行上面的数据没有被别人变更过,所以最后会加一个逻辑行锁,这个就是金融系统的特性需求。
为了更加简化云上用户接入,我们继续和内部产品数据访问代理DBP合作集成,如下所示:
分布式事务产品框架可以认为是被集成在数据访问代理里,当进行一个事务时,上层业务方对于底下的分布式事务和本地事务是一视同仁的,通过数据代理看一个事务,并执行SQL。如果是分布式事务,数据访问代理会通知框架去执行前面提到的一系列保证事务的操作,以保证数据的最终一致。
三. 上下篇总结
总结关于分布式事务服务的关键设计考量,首先为了保障支付业务的核心需求,保障分布式环境下交易一致性的问题,我们基于BASE思想,在业务层实现了 TCC 模型,并且为了业务发展的需求,优化了其工程实践,实现海量并发处理能力,让它的性能可以达到比业界其它产品高很多的状态。
其次,因为上层业务系统的复杂、业务种类的丰富等等业务需求,对分布式事务解决方案提出了全新的要求,所以我们在 TCC 模型基础上又加入了框架托管(FMT)模型,其简单易用,对业务无侵入的特点,可以较好的解决金融云场景下接入便捷性问题。