分布式事务基础

分布式事务

基础理论

CAP理论

CAP:Consistency(一致性) Availability(可用性) Partition tolerance(分区容忍性)

在所有分布式事务场景中不会同时具备 CAP 三个特性,因为在具备了P的前提下C和A是不能共存的。所以个分布式系统最多只能同时满足:一致性(Consistency)、可用性(Availability)和分区容忍性(Partition tolerance)这三项中的两项。

C-Consistency

​ 一致性是指写操作后的读操作可以读取到最新的数据状态,当数据分布在多个节点上,从任意结点读取到的数据都是最新的状态

特点
  1. 由于存在数据同步的过程,写操作的响应会有一定的延迟。
  2. 为了保证数据一致性会对资源暂时锁定,待数据同步完成释放锁定资源。
  3. 如果请求数据同步失败的结点则会返回错误信息,一定不会返回旧数据。
A-Availability

可用性是指任何事务操作都可以得到响应结果,且不会出现响应超时或响应错误。

特点

所有请求都有响应,且不会出现响应超时或响应错误

P-Partition tolerance

通常分布式系统的各个结点部署在不同的子网,这就是网络分区,不可避免的会出现由于网络问题而导致结点之间通信失败,此时仍可对外提供服务。

组合方式
AP

放弃一致性,追求分区容忍性和可用性。这是很多分布式系统设计时的选择。(Eureka)

当网络分区出现后,为了保证可用性,系统B可以返回旧值,保证系统的可用性。 结论:违背了一致性C的要求,只满足可用性和分区容错,即AP

CP

放弃可用性,追求一致性和分区容错性(Zookeeper)

CA

放弃分区容忍性,即不进行分区,不考虑由于网络不通或结点挂掉的问题,则可以实现一致性和可用性。那么系统将不是一个标准的分布式系统,最常用的关系型数据就满足了 CA。

BASE 理论

BASE Basically Available(基本可用)Soft state(软状态) Eventually consistent (最终一致性),满足BASE理论的事务,我们称之为柔性事务

Basically-Available

基本可用:分布式系统在出现故障时,允许损失部分可用功能,保证核心功能可用。如电商网站交易付款出现问题了,商品依然可以正常浏览。

Soft-state

软状态:由于不要求强一致性,所以BASE允许系统中存在中间状态(也叫软状态),这个状态不影响系统可用性,如订单的"支付中"、“数据同步中”等状态,待数据最终一致后状态改为“成功”状态。

Eventually-consistent

最终一致是指经过一段时间后,所有节点数据都将会达到一致。如订单的"支付中"状态,最终会变 为“支付成功”或者"支付失败",使订单状态与实际交易结果达成一致,但需要一定时间的延迟、等待。

解决方案

刚性事务

XA

基于数据库层面的分布式事务协议,其分为两部分:事务管理器(Transaction Manager)和本地资源管理器(Resource Manager)。事务管理器作为一个全局的调度者,负责对各个本地资源管理器统一号令提交或者回滚。

分布式事务处理模型DTP(Distributed Transaction Processing Reference Model)

DTP 模型定义如下角色:

  • AP(Application Program):即应用程序,可以理解为使用 DTP 分布式事务的程序。
  • RM(Resource Manager):即资源管理器,可以理解为事务的参与者,一般情况下是指一个数据库实例,通过资源管理器对该数据库进行控制,资源管理器控制着分支事务。
  • TM(Transaction Manager):事务管理器,负责协调和管理事务,事务管理器控制着全局事务,管理事务生命周期,并协调各个 RM。全局事务是指分布式事务处理环境中,需要操作多个数据库共同完成一个工作,这个工作即是一个全局事务
  • DTP 模型定义TM和RM之间通讯的接口规范叫 XA,简单理解为数据库提供的 2PC 接口协议,基于数据库的 XA 协议来实现 2PC 或 3PC 又称为 XA 方案
问题
  1. 需要本地数据库支持XA协议。
  2. 资源锁需要等到两个阶段结束才释放,性能较差。

2PC

两阶段提交协议,是将整个事务流程分为两个阶段,准备阶段(Prepare phase)、提交阶段(commit phase)。计算机中部分关系数据库如 Oracle、MySQL 支持两阶段提交协议。

  1. 准备阶段(Prepare phase):事务协调者给每个参与者发送 Prepare 消息,每个数据库参与者在本地执行事务,并写本地的 Undo/Redo 日志,此时事务没有提交。(Undo 日志是记录修改前的数据,用于数据库回滚,Redo 日志是记录修改后的数据,用于提交事务后写入数据文件)
  2. 提交阶段(commit phase):如果事务协调者收到了参与者的执行失败或者超时消息时,直接给每个参与者发送回滚(Rollback)消息;否则,发送提交(Commit)消息;参与者根据事务管理器的指令执行提交或者回滚操作,并释放事务处理过程中使用的锁资源。注意:必须在最后阶段释放锁资源
问题
1. 网络抖动导致的数据不一致

第二阶段发送提交(Commit)消息时,由于网络原因导致一部分参与者接收到了commit请求并执行,可其他未接到commit请求的参与者无法执行事务提交。

2.超时导致的同步阻塞问题

2PC中的所有的参与者节点都是事务阻塞,如果某一个参与者节点出现通信超时,其余参与者都会被动阻塞占用资源不能释放。

3.单点故障的风险

2PC严重依赖事务管理器,当事务管理器发生故障,而此时存在参与者处于锁定资源的状态,无法完成事务commit操作。

适用性

2PC只适用两个数据库(数据库实现了XA协议)之间;但是2PC有诸多问题,在实践中一般很少使用。

3PC

三段提交(3PC)是对两段提交(2PC)的一种优化,3PC在2PC的第一阶段和第二阶段中插入一个准备阶段。保证了在最后提交阶段之前,各参与者节点的状态都一致。同时在协调者和参与者中都引入超时机制,当参与者各种原因未收到协调者的commit请求后,会对本地事务进行commit,不会一直阻塞等待,解决了2PC的单点故障问题.

3PC的三个阶段

CanCommit、PreCommit、DoCommit

CanCommit

向所有参与者发送CanCommit命令,询问是否可以执行事务提交操作。如果全部响应YES才进入下一个阶段。

PreCommit

事务协调者向所有参与者发送PreCommit命令,询问是否可以进行事务的预提交操作,参与者接收到PreCommit请求后,进行相关事务操作,如果参与者成功执行了事务操作,则返回Yes响应,进入最终commit阶段。但是参与者中有向协调者发送了No响应,或因网络造成超时,事务协调者没有接到参与者的响应,事务协调者向所有参与者发送abort请求,参与者接受abort命令执行事务的中断。

DoCommit

当CanCommit和Precommit均成功执行,事务协调者向参与者发送DoCommit命令正式提交事务,当事务协调者没有接收到参与者发送的ACK响应时,会向所有参与者发送abort请求命令,执行事务的中断。

适用性

3PC工作在同步网络模型上,它假设消息传输时间都是高性能的,这样只存在在机器失败而不存在消息传输失败。在真实使用中机器失败是无法完美地检测出来的,反而消息传输可能因为网络拥堵花费很多时间。
当存在协调者和参与者同时失败的情形下, 3PC事务依然会阻塞。

##柔性事务

TCC

补偿事务,TCC与2PC的思想很相似,事务处理流程也很相似,但2PC是应用于在DB层面,TCC则可以理解为在应用层面的2PC,是需要我们编写业务逻辑来实现

TCC的三个阶段

Try 操作做业务检查及资源预留,Confirm 做业务确认操作,Cancel 实现一个与 Try 相反的操作即回滚操作。

  1. Try 阶段是做完业务检查(一致性)及资源预留(隔离),此阶段只是一个初步操作,它和后续的 Confirm 一起才能真正构成一个完整的业务逻辑。

  2. Confirm 阶段是做确认提交,Try 阶段所有分支事务执行成功后开始执行 Confirm。通常情况下,采用 TCC 则认为 Confirm 阶段是不会出错的。即:只要 Try 成功,Confirm 一定成功。若 Confirm 阶段真的出错了,需引入重试机制或人工处理

  3. Cancel 阶段是在业务执行错误需要回滚的状态下执行分支事务的业务取消,预留资源释放。通常情况下,采用 TCC 则认为 Cancel 阶段也是一定成功的。若 Cancel 阶段真的出错了,需引入重试机制或人工处理

问题
1.空回滚

当一个分支事务所在的服务发生宕机或者网络异常导致调用失败,并未执行try方法,当恢复后事务执行回滚操作就会调用此分支事务的cancel方法,当cancel未做优化处理时,就会出现空回滚。

空回滚解决方案
当主业务发起事务时,生成一个全局事务记录,并生成一个全局唯一ID,ID贯穿整个事务,创建一张分支事务记录表,用于记录分支事务,try执行时将全局事务ID和分支事务ID存入分支事务表中,表示执行了try阶段,当cancel执行时,先判断表中是否有该全局事务ID的数据,如果有则回滚,否则不做任何操作。

2.幂等问题

当存在服务宕机或者网络问题,方法的调用可能出现超时,为了保证事务正常执行往往会存在重试的机制,重试机制需要保证confirm和cancel阶段操作的幂等性。

解决方案
在分支事务记录表中添加事务执行的状态,在每次执行confirm和cancel方法时查询该事务的执行状态,如果已执行,不在重复执行。

3.悬挂问题

TCC执行时,调用try之前会先注册分支事务,注册分支事务之后,调用出现超时,此时try请求还未到达对应的服务,TCC执行cancel调用,当cancel执行完成后,try请求又到达了,这时执行了try之后没有commitcancel的后续操作(已执行cancel),导致资源挂起,无法释放。

解决方案
在分支事务记录表中添加事务执行的状态,执行try方法时判断confirm或者cancel方法是否执行,如果执行了就不再执行try。

TM 事务管理器

TM事务管理器可以实现为独立的服务,也可以让全局事务发起方充当 TM 的角色,TM 独立出来是为了成为公用组件,主要是考虑系统结构和软件复用。

TM 在发起全局事务时生成全局事务记录,全局事务 ID 贯穿整个分布式事务调用链条,用来记录事务上下文, 追踪和记录状态,由于 Confirm 和 Cancel 失败需进行重试,因此需要实现为幂等,幂等性是指同一个操作无论请求多少次,其结果都相同

2PC对比

如果拿 TCC 事务的处理流程与 2PC 两阶段提交做比较,2PC 通常都是在跨库的 DB 层面,而 TCC 则在应用层面的处理,需要通过业务逻辑来实现。这种分布式事务的实现方式的优势在于,可以让应用自己定义数据操作的粒度,使得降低锁冲突、提高吞吐量成为可能
而不足之处则在于对应用的侵入性非常强,业务逻辑的每个分支都需要实现 Try、Confirm、Cancel 三个操作。此外,其实现难度也比较大,需要按照网络状态、系统故障等不同的失败原因实现不同的回滚策略。

本地消息表

本地消息表最初由eBay提出,核心思路是将分布式事务拆分成本地事务进行处理。

实现方式
事务主动方

在事务主动发起方额外新建事务消息表,事务发起方处理业务和记录事务消息在本地事务中完成,轮询事务消息表的数据发送事务消息
轮询事务消息表,防止发送失败,被动方无法接收.

事务被动方

事务被动方基于消息中间件消费事务消息表中的事务

优点
方案轻量,容易实现

从应用设计开发的角度实现了消息数据的可靠性,消息数据的可靠性不依赖于消息中间件,弱化了对 MQ 中间件特性的依赖

缺点
与业务耦合性强,不可复用
业务数据库需要新增事务消息表,会占用业务系统资源
业务系统如果使用关系型数据库,消息服务性能会受到关系型数据库并发性能的局限

可靠消息事务(MQ事务)

MQ 的分布式事务方案其实是对本地消息表的封装,将本地消息表基于 MQ 内部,其他方面的协议基本与本地消息表一致。(通过MQ half消息 + commit/rollback消息)

优点

消息数据独立存储 ,降低业务系统与消息耦合
吞吐量大于本地消息表方案

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

最大努力通知

MQ事务方案的进一步优化,在事务主动方增加了消息校对的接口,如果事务被动方没有接收到消息,此时可以调用事务主动方提供的消息校对的接口主动获取。
事务主动方尽最大努力(重试,轮询…)将事务发送给事务接收方,但是仍然存在消息接收不到,此时需要事务被动方主动调用事务主动方的消息校对接口查询业务消息并消费,这种通知的可靠性是由事务被动方保证的

Saga

Saga由一系列的本地事务构成。当每一个本地事务在更新完数据库之后,发布一条消息或者一个事件来触发Saga中的下一个本地事务的执行,当其中一个本地事务因为某些业务规则无法满足而失败,Saga会对这个失败的事务之前成功提交的所有事务进行补偿操作。

实现方式
基于事件的方式

处于Saga下的各个服务,会产生某类事件,或者监听其它服务产生的事件并决定是否需要针对监听到的事件做出响应. C服务订阅B服务某个成功事件,B订阅C的失败事件,B服务订阅A服务的某个事件,A订阅B的失败操作事件,依次类推。

优点
简单且容易理解。各参与方相互之间无直接沟通,完全解耦。

缺点
果涉及比较多的业务参与方,则比较容易失控。各业务参与方可随意监听对方的消息,最后可能无法知道到底有哪些系统在监听哪些消息。可能产生环形监听,也就是两个业务方相互监听对方所产生的事件。

基于命令的方式

通过协调中心协调所有服务工作,协调中心通过命令/回复的方式来和Saga中其它服务进行交互。

优点

  1. 避免业务参与方之间形成环形依赖。
  2. 将事务管理交由协调中心管理,协调中心对整个逻辑非常清楚。
  3. 减少业务参与方的复杂度。业务参与方不需要监听不同的消息,只需要响应命令并回复消息。
  4. 容易测试(分布式事务逻辑存在于协调中心,而不是分散在各业务方)。
  5. 容易回滚

缺点
需要一个单独的协调中心

Seata

Seata为用户提供了 AT、TCC、SAGA 和 XA 事务模式,打造一站式的分布式解决方案

Seata对对业务无侵入并
高性能:减少分布式事务解决方案所带来的性能消耗

官网
 http://seata.io/zh-cn/
demo
https://github.com/seata/seata-samples
支持RPC框架
  1. AT 模式支持Dubbo、Spring Cloud、Motan、gRPC 和 sofa-RPC。

  2. TCC 模式支持Dubbo、Spring Cloud和sofa-RPC。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值