分布式事务(CAP、BASE、XA、2PC、3PC、TCC、MQ事务)

1、ACID–事务的四个基本特性

  • 原子性(Atomicity):一个事务中包含的所有操作,要么全部执行,要么一个都不执行。
  • 一致性(Consistency):一个事务能够正确地将数据从一个一致性的状态,转换到另一个一致性的状态。
  • 隔离性(Isolation):如果多个事务并发执行,各个事务之间的操作和数据是相互隔离的,相互不能干扰。
  • 持久性(Durability):一个事务一旦提交,数据的改变就是永久性的,以后即使发生故障也不影响结果。

PS:一个完整的事务需要满足以上4个特性。


2、分布式事务

2.1 分布式事务概述

分布式事务是指事务的资源分别位于分布式系统的不同节点之上的事务。

分布式事务产生的原因
数据库分库分表:当业务数据量达到单库单表的极限时,就需要考虑分库分表,跨多个数据库的事务操作就需要使用分布式事务。
业务服务化:随着互联网快速发展,微服务等架构模式正在被大规模的使用,现在分布式系统一般由多个独立的微服务组成,跨多个微服务的事务操作就需要使用分布式事务。

2.2 CAP定理

CAP定理:当网络分区发生时,无法同时满足一致性和可用性。

  • C : Consistency 一致性
  • A : Availability 可用性
  • P : Partition tolerance 分区容错性

分布式系统 P 是必须要满足的,所以只能在 C 和 A 之间做选择,即分布式系统只能选择 AP 或者 CP 。

网络分区:分布式系统的节点往往都是分布在不同的机器上进行网络隔离开的,这意味着必然会有网络断开的风险,这个网络断开的场景就叫作网络分区。

2.3 BASE理论

BASE理论核心思想 :即使无法做到强一致性,但每个应用都可以根据自身业务特点,采用适当的方式来使系统达到最终一致性。也就是牺牲数据的一致性来满足系统的高可用性,系统中一部分数据不可用或者不一致时,仍需要保持系统整体的“基本可用”。

BASE理论是对CAP定理中一致性和可用性权衡的结果,其来源于对大规模互联网系统分布式实践的总结,是基于CAP定理逐步演化而来。

BASE理论三要素

  • 基本可用(Basically Available):基本可用是指分布式系统在出现不可预知故障的时候,允许损失部分可用性,即保证核心可用。但是,这绝不等价于系统不可用。
    比如:
    响应时间上的损失:正常情况下,一个在线搜索引擎需要在0.5秒之内返回给用户相应的查询结果,但由于出现故障,查询结果的响应时间增加了1~2秒。
    系统功能上的损失:正常情况下,在一个电子商务网站上进行购物的时候,消费者几乎能够顺利完成每一笔订单,但是在一些节日大促购物高峰的时候,由于消费者的购物行为激增,为了保护购物系统的稳定性,部分消费者可能会被引导到一个降级页面。

  • 软状态(Soft State):软状态指允许系统中的数据存在中间状态,并认为该中间状态不会影响系统的整体可用性,即允许系统不同节点之间的数据同步存在延时。这里的中间状态就是CAP理论中的数据不一致。
    比如:
    在秒杀系统中,用户余额的扣减和商家余额的增加可以存在延时,当用户余额减了之后即可返回支付成功,商家余额的增加可以等系统压力小的时候再做。

  • 最终一致性(Eventually Consistent):最终一致性强调的是系统中的所有数据经过一定时间后,最终能够达到一致的状态。因此,最终一致性的本质是需要系统保证最终数据能够达到一致,而不需要实时保证系统数据的强一致性。

2.4 数据一致性模型

强一致性
当更新操作完成之后,所有的后续访问都会返回最新的值。这也意味着,只要之前的更新操作没有完成,就不能读取数据。

弱一致性
当更新操作完成之后,系统并不保证所有的后续访问都会返回最新的值,但会尽可能保证在某个时间级别后能获取最新的值。

最终一致性
当更新操作完成之后,系统会保证在某个时间段后所有的后续访问都会返回最新的值。系统无法保证强一致性的时间段被称为"不一致性窗口"。最终一致性是弱一致性的一种特例。


3、分布式事务解决方案

3.1 XA协议

X/Open DTP(X/Open Distributed Transaction Processing Reference Model)是 X/Open 这个组织定义的一套分布式事务处理参考模型。X/Open DTP 模型定义以下角色:

  • AP(Application Program):应用程序,即业务层。
  • RM(Resource Manager):资源管理器,控制分支事务和管理实际资源,AP 通过资源管理器对资源进行控制。资源管理器通常是由数据库来实现。
  • TM(Transaction Manager):事务管理器,控制全局事务,管理事务生命周期,并协调各个 RM。

XA 是指由 X/Open 组织提出的分布式事务规范,XA 协议主要定义了 TM 与 RM 之间的通信接口,Oracle、Mysql 等数据库都对 XA 协议进行了实现。

3.2 2PC方案(基于XA协议)

3.2.1 方案简介

2PC(Two-phase Commit)即二阶段提交协议,是常用的分布式事务解决方案,即将事务的提交过程分为两个阶段来进行处理:准备阶段和提交阶段。事务的发起者称协调者(TM),事务的执行者称参与者(RM)。

二阶段提交算法可以概括为:参与者将操作成败通知协调者,再由协调者根据所有参与者的反馈情报决定各参与者是否要提交操作还是中止操作。二阶段提交是一个强一致性算法。

在分布式系统里,每个节点都可以知晓自己操作的成功或者失败,却无法知道其他节点操作的成功或失败。当一个事务跨多个节点时,为了保持事务的原子性与一致性,而引入一个协调者来统一掌控所有参与者的操作结果,并指示它们是否要把操作结果进行真正的提交(commit)或者回滚(rollback)。

3.2.2 2PC处理流程

阶段1:准备阶段
1、协调者向所有参与者发送事务内容,询问是否可以提交事务,并等待所有参与者答复。
2、各参与者执行事务操作,将undo和redo信息记入事务日志中,但不提交事务。
3、如参与者执行成功,给协调者反馈yes,即可以提交;如执行失败,给协调者反馈no,即不可提交。

PS:undo日志是记录修改前的数据,用于回滚;redo日志是记录修改后的数据,用于提交事务后写入数据文件。

阶段2:提交阶段
如果协调者收到了参与者的失败消息或者超时,直接给每个参与者发送回滚(rollback)消息;否则,发送提交(commit)消息;参与者根据协调者的指令执行提交或者回滚操作,释放所有事务处理过程中使用的锁资源。(注意:必须在最后阶段释放锁资源) 接下来分两种情况分别讨论提交阶段的过程。

情况1,当所有参与者均反馈yes,提交事务:

在这里插入图片描述

  1. 协调者向所有参与者发出正式提交事务的请求(即commit请求)。
  2. 参与者执行commit请求,并释放整个事务期间占用的资源。
  3. 各参与者向协调者反馈 ack(应答)完成的消息。
  4. 协调者收到所有参与者反馈的ack消息后,即完成事务提交。

情况2,当任何阶段1的一个参与者反馈no,中断事务:

在这里插入图片描述

  1. 协调者向所有参与者发出回滚请求(即rollback请求)。
  2. 参与者使用阶段1中的undo信息执行回滚操作,并释放整个事务期间占用的资源。
  3. 各参与者向协调者反馈 ack 完成的消息。
  4. 协调者收到所有参与者反馈的ack消息后,即完成事务中断。

3.2.3 2PC方案总结

2PC方案实现起来简单,实际项目中使用比较少,主要因为以下问题:

  1. 性能问题:整个事务期间,资源都被锁定,处于同步阻塞状态,导致性能瓶颈。也因此二阶段提交是一个强一致性算法。
  2. 可靠性问题:协调者存在单点故障问题,如果协调者出现故障,参与者将一直处于锁定状态。
  3. 数据一致性问题:在阶段2中,如果发生局部网络问题,一部分事务参与者收到了提交消息,另一部分事务参与者没收到提交消息,那么就导致了节点之间数据的不一致。

3.3 3PC方案(2PC的改进方案)

3.3.1 方案简介

3PC即三阶段提交协议,是二阶段提交协议的改进版。三阶段提交协议在协调者和参与者中引入了超时机制,所以不会出现阻塞,优化了性能,但没有根本解决性能问题,数据一致性问题也没有解决。

3.3.2 处理流程

阶段1:canCommit

协调者向参与者发送 canCommit 请求,参与者如果可以提交就返回yes响应(参与者不执行事务操作),否则返回no响应:

  1. 协调者向所有参与者发出包含事务内容的 canCommit 请求,询问是否可以提交事务,并等待所有参与者答复。
  2. 参与者收到 canCommit 请求后,如果认为可以执行事务操作,则反馈yes并进入预备状态,否则反馈no。

阶段2:preCommit

协调者根据阶段1 canCommit 参与者的反应情况来决定是否可以基于事务的 preCommit 操作。根据响应情况,有以下两种可能。

情况1:阶段1所有参与者均反馈yes,参与者预执行事务:

在这里插入图片描述

  1. 协调者向所有参与者发出 preCommit 请求,进入准备阶段。
  2. 参与者收到 preCommit 请求后,执行事务操作,将undo和redo信息记入事务日志中,但不提交事务。
  3. 各参与者向协调者反馈ack响应或no响应,并等待最终指令。

情况2:阶段1任何一个参与者反馈no,或者等待超时后协调者尚无法收到所有参与者的反馈,即中断事务:

在这里插入图片描述

  1. 协调者向所有参与者发出abort请求。
  2. 无论收到协调者发出的abort请求,或者在等待协调者请求过程中出现超时,参与者均会中断事务。

阶段3:doCommit

该阶段进行真正的事务提交,也可以分为以下两种情况:

情况1:阶段2所有参与者均反馈ack响应,执行真正的事务提交:

在这里插入图片描述

  1. 如果协调者处于工作状态,则向所有参与者发出 doCommit 请求。
  2. 参与者收到 doCommit 请求后,会正式执行事务提交,并释放整个事务期间占用的资源。
  3. 各参与者向协调者反馈ack完成的消息。
  4. 协调者收到所有参与者反馈的ack消息后,即完成事务提交。

情况2:阶段2任何一个参与者反馈no,或者等待超时后协调者尚无法收到所有参与者的反馈,即中断事务:

在这里插入图片描述

  1. 如果协调者处于工作状态,向所有参与者发出abort请求。
  2. 参与者使用阶段1中的undo信息执行回滚操作,并释放整个事务期间占用的资源。
  3. 各参与者向协调者反馈ack完成的消息。
  4. 协调者收到所有参与者反馈的ack消息后,即完成事务中断。

注意:进入阶段3后,无论协调者出现问题,或者协调者与参与者网络出现问题,都会导致参与者无法接收到协调者发出 doCommit请求或abort请求。此时,参与者都会在等待超时之后,继续执行事务提交。

3.3.3 3PC方案总结

  1. 优化性能问题:相比二阶段提交,三阶段提交降低了阻塞范围,在等待超时后协调者或参与者会中断事务。
  2. 优化可靠性问题:避免了协调者单点问题,阶段3中协调者出现问题时,参与者会继续提交事务。
  3. 数据一致性问题:数据不一致问题依然存在,当在参与者收到 preCommit 请求后等待 doCommit 指令时,此时如果协调者请求中断事务,而协调者无法与参与者正常通信,会导致参与者继续提交事务,造成数据不一致。

3.4 TCC(Try-Confirm-Cancel)— 最终一致性

3.4.1 方案简介

TCC类似2PC,TCC的Try、Confirm、Cancel 3个方法均由业务编码实现。Try操作作为一阶段,负责资源的检查和预留;Confirm操作作为二阶段提交操作,执行真正的业务;Cancel是预留资源的取消。

TCC两阶段提交与XA两阶段提交的区别是

  • XA是资源层面的分布式事务,强一致性,在两阶段提交的整个过程中,一直会持有资源的锁。

  • TCC是业务层面的分布式事务,最终一致性,由多个独立的本地事务组成,因此不会对资源一直加锁。

    Try是本地事务,保证资源预留的业务逻辑的正确性;

    Confirm / Cancel是本地事务,执行确认/取消预留资源,以保证最终一致性,也叫补偿型事务(Compensation-Based Transactions)。

3.4.2 TCC处理流程

为了方便理解,以电商下单为例进行分析,把整个下单过程简单的分为扣减库存和订单创建2个步骤,库存服务和订单服务分别在不同的服务器节点上。

1、Try 阶段
TCC机制中的Try仅是一个初步操作,它和后续的确认一起才能真正构成一个完整的业务逻辑,这个阶段主要完成:

  • 完成所有业务检查( 一致性 )
  • 预留必须业务资源( 准隔离性 )

假设商品库存为100,购买数量为2,Try阶段所做的工作如下:

  • 库存服务:更新库存为98,并设置冻结库存+2,本地事务提交。
  • 订单服务:创建订单,订单状态为待确认状态,本地事务提交。

在这里插入图片描述

2、Confirm / Cancel 阶段
根据Try阶段服务是否全部正常执行,继续执行确认操作(Confirm)或取消操作(Cancel)。Confirm和Cancel操作必须满足幂等性,如果Confirm或Cancel操作执行失败,将会不断重试直到执行完成 (补偿机制)。

Confirm:当Try阶段服务全部正常执行, 执行确认业务逻辑操作。

在这里插入图片描述
Confirm阶段使用的资源一定是Try阶段预留的业务资源。在TCC事务机制中认为,如果在Try阶段能正常的预留资源,那Confirm一定能完整正确的提交。Confirm阶段也可以看成是对Try阶段的一个补充,Try+Confirm一起组成了一个完整的业务逻辑。

Cancel:当Try阶段存在服务执行失败, 进入Cancel阶段

在这里插入图片描述
Cancel取消执行,释放Try阶段预留的业务资源,上面的例子中,Cancel操作会把冻结的库存释放,并更新订单状态为取消。

3.4.3 TCC方案总结

  1. 性能提升:由多个独立的本地事务组成,因此不会对资源一直加锁。
  2. 数据最终一致性:基于Confirm和Cancel的幂等性,事务最终完成确认或者取消,保证数据的最终一致性。
  3. 可靠性:解决了XA协议的协调者单点故障问题,由主业务方发起并控制整个业务活动,业务活动管理器变成多点。
  4. 业务耦合度高:TCC的Try、Confirm和Cancel操作功能要按具体业务来实现,业务耦合度较高,提高了开发成本。

3.5 MQ事务 — 最终一致性

3.5.1 方案简介

MQ事务的核心思路是利用可靠消息队列将分布式事务拆分成本地事务进行处理。

3.5.2 处理流程

RocketMQ 4.3 版本开始支持分布式事务,基于RocketMQ的分布式事务方案如下:

正常情况——事务主动方发消息
这种情况下,事务主动方服务正常,没有发生故障,发消息流程如下:

在这里插入图片描述

  • 图中1、发送方向 MQ服务端(MQ Server)发送 half 消息。
  • 图中2、MQ Server 将消息持久化成功之后,向发送方 ACK 确认消息已经发送成功。
  • 图中3、发送方开始执行本地事务逻辑。
  • 图中4、发送方根据本地事务执行结果向 MQ Server 提交二次确认(commit 或是 rollback)。
  • 图中5、MQ Server 收到 commit 状态则将半消息标记为可投递,订阅方最终将收到该消息;MQ Server 收到
    rollback 状态则删除半消息,订阅方将不会接受该消息。

异常情况——事务主动方消息恢复
在断网或者应用重启等异常情况下,图中4提交的二次确认超时未到达 MQ Server,此时处理逻辑如下:

在这里插入图片描述

  • 图中5、MQ Server 对该消息发起消息回查。
  • 图中6、发送方收到消息回查后,需要检查对应消息的本地事务执行的最终结果。
  • 图中7、发送方根据检查得到的本地事务的最终状态再次提交二次确认。
  • 图中8、MQ Server基于commit / rollback 对消息进行投递或者删除。

3.5.3 方案总结

优点:低耦合、吞吐量高。

缺点:一次消息发送需要两次网络请求(half消息 + commit/rollback消息);业务处理服务需要实现消息状态回查接口。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值