文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

如何选择分布式事务解决方案?

2024-12-24 17:29

关注

概述

事务是一组不可分组的操作集合,这些操作要么都成功执行,要么都取消执行。最典型的需要事务的场景是银行账户间的转账:假如 A 账户要给 B 账户转账 100 元,那么 A 账户要扣减 100 元,B 账户要增加 100 元,这两个账户的数据变更都成功才可算作转账成功。更严格来说,可以用 ACID 四个特性表述事务:

单体数据库不涉及网络交互,所以在多表之间实现事务是比较简单的,这种事务我们称之为本地事务。

但是单体数据库的性能达到瓶颈的时候,就需要分库(分物理实例),就会出现跨库(数据库实例)的事务需求;随着企业应用的规模越来越大,企业会进一步进行服务化改造,以满足业务增长的需求;当前微服务架构越来越流行,跨服务的事务场景也会越来越多。

这些都是分布式事务的需求。分布式事务是指是指事务的发起者、参与者、数据资源服务器以及事务管理器分别位于分布式系统的不同节点之上。

概括起来,分布式事务有三种场景:

 

分布式事务中涉及的参与者分布在异步网络中,参与者通过网络通信来达到分布式一致性,网络通信不可避免出现失败、超时的情况,因此分布式事务的实现比本地事务面临更多的困难。下面介绍几种常见的分布式事务解决方案。

分布式事务模式

XA Specification

最早的分布式事务产品可能是 AT&T 在 20 世纪 80 年代推出的 Tuxedo (Transactions for Unix, Extended for Distributed Operations),Tuxedo 最早是为了电信领域的 OLTP 系统研发的分布式事务中间件,后来标准化组织 X/Open 吸收采纳了 Tuxedo 的设计思想和一些接口,推出了分布式事务规范:XA Specification。

XA 规范中定义了分布式事务处理模型,这个模型中包含四个核心角色:

下图是 XA 规范中定义的事务模型图,其中:发起分布式事务的 TM 实例称之为 root 节点,其他的 TM 实例可以统称为事务的参与者。事务发起者负责开启整个全局事务,事务参与者各自负责执行自己的事务分支。如果TM实例发起了对其他 TM 实例的服务调用,那么发起者就被成为 Superior,被调用这就被称之为 Subordinate 节点。

 

图源:《Distributed Transaction Processing:Reference Model, Version 3》 Page 32,Figure 3-2

XA 规范中分布式事务是构建在 RM 本地事务(此时本地事务被看作分支事务)的基础上的,TM 负责协调这些分支事务要么都成功提交、要么都回滚。XA 规范把分布式事务处理过程划分为两个阶段,所以又叫两阶段提交协议(two phrase commit):

1)预备阶段

TM 记录事务开始日志,并询问各个 RM 是否可以执行提交准备操作。

RM 收到指令后,评估自己的状态,尝试执行本地事务的预备操作:预留资源,为资源加锁、执行操作等,但是并不提交事务,并等待 TM 的后续指令。如果尝试失败则告知 TM 本阶段执行失败并且回滚自己的操作,然后不再参与本次事务(以 MySQL 为例,这个阶段会完成资源的加锁,redo log 和 undo log 的写入)。

TM 收集 RM 的响应,记录事务准备完成日志。

2)提交/回滚阶段

这个阶段根据上个阶段的协调结果发起事务的提交或者回滚操作。

如果所有 RM 在上一个步骤都返回执行成功,那么:

如果有 RM 在上一个步骤中返回执行失败或者超时没有应答,则 TM 按照执行失败处理,那么:

 

针对部分场景,XA 规范还定义了如下优化措施:

XA 规范中详细定义了各个核心组件之间的交互接口,以 TM 和 RM 的交互接口为例,如下图,一次完整的全局事务,TM 和 RM 之间的交互还是比较频繁的:

 

事务的执行过程中,宕机和网络超时都有可能发生,针对这些异常场景,不同 XA 规范的实现,对异常处理做法可能不同,可参考如下:

特点剖析

XA 两阶段提交协议设计上是要像本地事务一样实现事务的 ACID 四个特性:

XA 是出现最早的分布式事务规范,主流数据库 Oracle、MySQL、SQLServer 等都支持 XA 规范,J2EE 中的 JTA 规范也是参照 XA 规范编写的,与 XA 规范兼容。

XA 是在资源管理层面实现的分布式事务模型,对业务的入侵度较低。

XA 两阶段提交协议可以覆盖分布式事务的三种场景,但是全局事务的执行过程中,RM 一直持有资源的锁,如果参与的 RM 过多,尤其是跨服务的场景下,网络通信的次数和时间会急剧变多,所以阻塞的时间更长,系统的吞吐能力变得很差,事务死锁出现的概率也会变大,所以并不适合微服务架构场景中的跨服务的分布式事务模式。

每一个 TM 域来说,由于 TM 是单点,存在单点故障风险,如果 TM 在阶段1之后挂掉,会导致参与的 RM 长时间收不到阶段 2 的请求而长期持有资源的锁,影响业务的吞吐能力。同时一次完整的全局事务,TM 和 RM 之间的交互多达 8 次,太繁琐,非常影响系统的处理性能。

XA 两阶段协议可能会造成脑裂的异常,假如 TM 在阶段 2 通知 RM 提交事务时,如果指令发出后就宕机了,而只有部分 RM 收到了提交请求,那么当 TM 恢复的时候,就无法协调本次事务所有的 RM 本地事务的一致性了。

XA 要处理的异常场景非常多,对框架的实现有一定的挑战,开源的实现,可以参考:Atomikos,Bitronix。

针对 XA 两阶段提交中的问题,有人提出了三阶段提交的改进方案,三阶段提交方案主要解决了单点故障问题,并在 RM 侧也引入了超时机制,以避免资源的长时间锁定。但是三阶段提交方案依然无法避免脑裂的异常情况出现,实际应用案例很少,感兴趣的同学可以自行找相关资料了解。

TCC

TCC (Try、Commit、Cancel) 是一种补偿型事务,该模型要求应用的每个服务提供 try、confirm、cancel 三个接口,它的核心思想是通过对资源的预留(提供中间态),尽早释放对资源的加锁,如果事务可以提交,则完成对预留资源的确认,如果事务要回滚,则释放预留的资源。

TCC 也是一种两阶段提交协议,可以看作 2PC/XA 的一种变种,但是不会长时间持有资源锁。

TCC 模型将事务的提交划分为两个阶段:

1)阶段 1

完成业务检查(一致性)、预留业务资源(准隔离性),即 TCC 中的 try。

2)阶段 2

如果 try 阶段所有业务资源都预留成功,则执行 confirm 操作,否则执行 cancel 操作:

 

TCC 模式中,事务的发起者和参与者都需要记录事务日志,事务的发起者需要记录全局事务和各个分支事务的状态和信息;事务的参与者需要记录分支事务的状态。

TCC 事务在执行过程中的任意环节,均可能发生宕机、重启、网络中断等异常情况,此时事务处于非原子状态和非最终一致状态,此时就需要根据主事务记录和分支事务记录的日志,去完成剩余分支事务的提交或者回滚,使整个分布式事务内所有参展达到最终一致的状态,实现事务的原子性。

举例

我们以一个简单的电商系统为例,小明在淘宝上花 100 元买了一本书,获赠 10 个积分,产品上有如下几个操作:

订单系统创建商品订单

支付系统接受小明的支付

库存系统扣减产品库存

会员系统给小明账户增加会员积分

这几个动作需要作为一个事务执行,要同时成功或者同时撤销。

如果采用 TCC 事务模式,那么各个系统需要改造为如下状态:

1)订单系统

2)支付系统

3)库存系统

4)会员系统

特点剖析

TCC 事务具备事务的四个特性:

TCC 事务模型对业务方侵入较大,需要业务方把功能的实现上由一个接口拆分为三个,开发成本较高。

同时 TCC 事务为了解决异步网络中的通信失败或超时带来的异常情况,要求业务方在设计实现上要遵循三个策略:

TCC 事务将分布式事务从资源层提到业务层来实现,可以让业务灵活选择资源的锁定粒度,并且全局事务执行过程中不会一直持有锁,所以系统的吞吐量比 2PC/XA 模式要高很多。

支持 TCC 事务的开源框架有:ByteTCC、Himly、TCC-transaction。

Saga

Saga 并不是一个新概念,其相关论文在 1987 年就发布了,和 XA 两阶段提交规范出现的时间差不多。

Saga 和 TCC 一样,也是一种补偿事务,但是它没有 try 阶段,而是把分布式事务看作一组本地事务构成的事务链。

事务链中的每一个正向事务操作,都对应一个可逆的事务操作。Saga 事务协调器负责按照顺序执行事务链中的分支事务,分支事务执行完毕,即释放资源。如果某个分支事务失败了,则按照反方向执行事务补偿操作。

假如一个 Saga 的分布式事务链有 n 个分支事务构成,[T1,T2,...,Tn],那么该分布式事务的执行情况有三种:

 

举例

假如国庆节小明要出去玩,从北京出发,先去伦敦,在伦敦游玩三天,再去巴黎,在巴黎游玩三天,然后再返回北京。整个行程中涉及不同航空公司的机票预订以及伦敦和巴黎当地的酒店预订,小明的计划是如果任何一张机票或酒店预订不上,就取消本次出行计划。假如综合旅游出行服务平台提供这种一键下单的功能,那么这就是一个长事务,用 Saga 模式编排服务的话,就如下图所示:任何一个环节失败的话,就通过补偿操作取消前面的行程预订。

 

特点剖析

Saga 事务是可以保障事务的三个特性:

但是 Saga 不保证事务隔离性的,本地事务提交后变更就对其他事务可见了。其他事务如果更改了已经提交成功的数据,可能会导致补偿操作失败。比如扣款失败,但是钱已经花掉了,业务设计上需要考虑这种场景并从业务设计上规避这种问题。

Saga 事务和 TCC 事务一样,对业务实现要求高,要求业务设计实现上遵循三个策略:

虽然 Saga 和 TCC 都是补偿事务,但是由于提交阶段不同,所以两者也是有不同的:

Saga 模式非常适合于业务流程长的长事务的场景,实现上对业务侵入低,所以非常适合微服务架构的场景。同时 Saga 采用的是一阶段提交模式,不会对资源长时间加锁,不存在“木桶效应”,所以采用这种模式架构的系统性能高、吞吐高。

阿里巴巴的 Seata 开源项目和华为的 ServiceComb 开源项目都支持 Saga 模式。

基于消息的分布式事务

基于消息的分布式事务模式核心思想是通过消息系统来通知其他事务参与方自己事务的执行状态。

消息系统的引入更有效的将事务参与方解耦,各个参与方可以异步执行。

该种模式的难点在于解决本地事务执行和消息发送的一致性:两者要同时执行成功或者同时取消执行。

实现上主要有两种方式:

基于事务消息的分布式事务

普通消息是无法解决本地事务执行和消息发送的一致性问题的。因为消息发送是一个网络通信的过程,发送消息的过程就有可能出现发送失败、或者超时的情况。超时有可能发送成功了,有可能发送失败了,消息的发送方是无法确定的,所以此时消息发送方无论是提交事务还是回滚事务,都有可能不一致性出现。

解决这个问题,需要引入事务消息,事务消息和普通消息的区别在于事务消息发送成功后,处于 prepared 状态,不能被订阅者消费,等到事务消息的状态更改为可消费状态后,下游订阅者才可以监听到次消息。

本地事务和事务消息的发送的处理流程如下:

 

基于本地消息的分布式事务

基于事务消息的模式对 MQ 系统要求较高,并不是所有 MQ 系统都支持事务消息的,RocketMQ 是目前为数不多的支持事务小的 MQ 系统。如果所依赖的 MQ 系统不支持事务消息,那么可以采用本地消息的分布式模式。

该种模式的核心思想是事务的发起方维护一个本地消息表,业务执行和本地消息表的执行处在同一个本地事务中。业务执行成功,则同时记录一条“待发送”状态的消息到本地消息表中。系统中启动一个定时任务定时扫描本地消息表中状态为“待发送”的记录,并将其发送到 MQ 系统中,如果发送失败或者超时,则一直发送,知道发送成功后,从本地消息表中删除该记录。后续的消费订阅流程则与基于事务消息的模式雷同。

 

特点剖析

基于消息的分布式事务模式对 ACID 特性的支持如下:

基于消息的分布式事务可以将分布式系统之间更有效的解耦,各个事务参与方之间的调用不再是同步调用。

对 MQ 系统的要求较高,对业务实现也有一定的侵入性,要么提供事务消息状态查询接口,要么需要维护本地消息表。并且原则上只接受下游分支事务的成功,不接受事务的回滚,如果失败就要一直重试,适用于对最终一致性敏感度较低的业务场景,例如跨企业的系统间的调用,适用的场景有限。

最大努力通知型分布式事务

最大努力通知型的分布式事务解决方案,也是基于 MQ 系统的一种解决方案,但是不要求 MQ 消息可靠。

举例

假设小明通过联通的网上营业厅为手机充话费,充值方式选择支付宝支付。整个操作的流程如下:

特点剖析

最大努力通知型方案本质是通过引入定期校验机制来对最终一致性做兜底,对业务侵入性较低、对 MQ 系统要求较低,实现比较简单,适合于对最终一致性敏感度比较低、业务链路较短的场景,比如跨平台、跨企业的系统间的业务交互。

分布式事务中间件

阿里巴巴有两个分布式事务中间件可选择:

XTS 和 TXC 的功能差不多,都支持 TCC 事务模式,也都提供了对业务入侵度较低的分布式事务方案,目前这两个团队应该是在共建开源版的分布式事务中间件 Seata。此处我们介绍一下 Seata。

Seata

简单说一下 Seata (Simple Extensible Autonomous Transaction Architecture) 的历史:

Seata 支持 TCC 模式、Saga 模式。但是 Seata 对 TCC 模式的支持提供了一种对业务入侵度为0的解决方案,这种方案叫做 AT (Automatic Transaction) 模式。下面我们重点说一下 AT 模式的运行机制:

 

AT 模式通过自动生成回滚日志的方式,使得业务方接入成本低,对业务入侵度很低,但是应用 AT 模式也有一些限制:

总结

单体数据库事务很容易满足事务的 ACID 四个特性,提供强一致性保证,但是分布式事务要完全遵循 ACID 特性会比较困难。为了追求分布式系统的高可用和高吞吐,分布式事务的解决方案一般提供的是最终一致性。

我们把提供强一致性的事务称之为刚性事务,把提供最终一致性的事务称之为柔性事务。刚性事务可以完全满足 ACID 四个特性,柔性事务对事务的 ACID 特性的支持情况如下:

柔性事务一般遵循的是分布式领域中的 BASE 理论:

BASE 理论,是对 CAP 理论的延伸,是对 CAP 中的一致性和可用性进行一个权衡的结果,理论的核心思想就是:我们无法做到强一致,但每个应用都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性。

CAP 理论告诉我们一个分布式系统无法同时满足一致性, 可用性, 分区容错性,所以在设计上对这三点做取舍。刚性事务追求强一致性,所以牺牲了高可用性;柔性事务通过牺牲一致性换来了系统的高可用性。

在系统选择分布式方案时,可以根据对一致性的要求进行选择,业务上有强一致性要求的场景时,优先考虑 XA 规范的两阶段提交;业务上只需要最终一致性的场景时,可以在根据具体场景在柔性事务方案中进行选择。

参考

[1]分布式事务中间件TXC(http://mw.alibaba-inc.com/product-txc.html)

[2]弹力设计之补偿事务(https://www.jianshu.com/p/8095001d79bb)

[3]分布式事务中间件ServiceComb

(http://servicecomb.apache.org/cn/docs/distributed-transactions-saga-implementation/)

[4]深入理解两阶段提交(https://sq.163yun.com/blog/article/165554812476866560)[5]Seata(https://seata.io/zh-cn/)

[6]TCC事务原理

(https://www.cnblogs.com/jajian/p/10014145.html)

[7]TCC事务异常场景(https://blog.csdn.net/dm_vincent/article/details/92432059

[8]Compensating Transaction Pattern

(https://docs.microsoft.com/en-us/azure/architecture/patterns/compensating-transaction)

[9]基于消息的分布式事务(https://www.jianshu.com/p/04bad986a4a2)

[10]分布式事务概述(http://www.tianshouzhi.com/api/tutorials/distributed_transaction/383)

[11]初识Open/X XA

(https://www.jianshu.com/p/6c1fd2420274)

[12]DTP: XA Specification

(https://pubs.opengroup.org/onlinepubs/009680699/toc.pdf)

[13]DTP Model

(https://pubs.opengroup.org/onlinepubs/009249599/toc.pdf)

【本文为51CTO专栏作者“阿里巴巴官方技术”原创稿件,转载请联系原作者】

​戳这里,看该作者更多好文​

来源:51CTO专栏内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯