常见分布式事务解决方案

前言

关于分布式事务,工程领域主要讨论的是强一致性和最终一致性的解决方案。典型方案包括:

两阶段提交(2PC, Two-phase Commit)方案
eBay 事件队列方案
TCC 补偿模式
缓存数据最终一致性

一致性理论

分布式事务的目的是保障分库数据一致性,而跨库事务会遇到各种不可控制的问题,如个别节点永久性宕机,像单机事务一样的ACID是无法奢望的。另外,业界著名的CAP理论也告诉我们,对分布式系统,需要将数据一致性和系统可用性、分区容忍性放在天平上一起考虑。两阶段提交协议(简称2PC)是实现分布式事务较为经典的方案,但2PC 的可扩展性很差,在分布式架构下应用代价较大,eBay 架构师Dan Pritchett 提出了BASE 理论,用于解决大规模分布式系统下的数据一致性问题。BASE 理论告诉我们:可以通过放弃系统在每个时刻的强一致性来换取系统的可扩展性。

CAP理论

在分布式系统中,一致性(Consistency)、可用性(Availability)和分区容忍性(Partition Tolerance)3 个要素最多只能同时满足两个,不可兼得。其中,分区容忍性又是不可或缺的。
在这里插入图片描述

BASE 理论核心思想:

  1. 基本可用(BasicallyAvailable):指分布式系统在出现故障时,允许损失部分的可用性来保证核心可用。
  2. 软状态(SoftState):指允许分布式系统存在中间状态,该中间状态不会影响到系统的整体可用性。
  3. 最终一致性(EventualConsistency):指分布式系统中的所有副本数据经过一定时间后,最终能够达到一致的状态。

数据的一致性模型可以分成以下 3 类:

  1. 强一致性:数据更新成功后,任意时刻所有副本中的数据都是一致的,一般采用同步的方式实现。
  2. 弱一致性:数据更新成功后,系统不承诺立即可以读到最新写入的值,也不承诺具体多久之后可以读到。
  3. 最终一致性:弱一致性的一种形式,数据更新成功后,系统不承诺立即可以返回最新写入的值,但是保证最终会返回上一次更新操作的值。分布式系统数据的强一致性、弱一致性和最终一致性可以通过Quorum NRW算法分析。

下面开始介绍分布式事务解决方案

1、2PC方案——强一致性

2PC 即两阶段提交协议,是将整个事务流程分为两个阶段,准备阶段(Prepare phase)、提交阶段(commit phase),2 是指两个阶段,P 是指准备阶段,C 是指提交阶段。

第一阶段(prepare):每个参与者执行本地事务但不提交,进入ready状态,并通知协调者已经准备就绪
在这里插入图片描述
第二阶段(commit)当协调者确认每个参与者都ready后,通知参与者进行commit操作;如果有参与者fail,则发送rollback命令,各参与者做回滚。
在这里插入图片描述

会出现的问题:

  1. 单点故障:一旦事务管理器出现故障,整个系统不可用(参与者都会阻塞住)
  2. 数据不一致:在阶段二,如果事务管理器只发送了部分commit消息,此时网络发生异常,那么只有部分参与者接收到commit消息,也就是说只有部分参与者提交了事务,使得系统数据不一致。
  3. 响应时间较长:参与者和协调者资源都被锁住,提交或者回滚之后才能释放
  4. 不确定性:当协事务管理器发送commit之后,并且此时只有一个参与者收到了commit,那么当该参与者与事务管理器同时宕机之后,重新选举的事务管理器无法确定该条消息是否提交成功。

三阶段协议:主要是针对两阶段的优化,解决了2PC单点故障的问题

阶段一:发送CanCommiti消息,确认环境是否正常
在这里插入图片描述

阶段二:发送PreCommiti消息,完成Sql语句的操作,但未提交事务,和二阶段的一阶段一致。

阶段三:DoCommit阶段,在阶段二中如果所有的参与者节点都返回了Ack,那么协调者就会从"预提交状态"转变为“提交状态"。然后向所有的参与者节点发送"doCommit’"请求,参与者节点在收到提交请求后就会各自执行事务提交操作,并向协调者节点反馈"Ack"消息,协调者收到所有参与者的Ack消息后完成事务。相反,如果有一个参与者节点未完成PreCommit的反馈或者反馈超时,那么协调者都会向所有的参与者节点发送abort请求,从而中断事务。

相比较2PC而言,3PC对于事务管理器和资源管理器都设置了超时时间,而2PC只有事务管理器才拥有超时机制。这解决了一个什么问题呢?这个优化点,主要是避免了资源管理器在长时间无法与事务管理器节点通讯(事务管理器挂掉了)的情况下,无法释放资源的问题,因为参与者自身拥有超时机制会在超时后,自动进行本地commit从而进行释放资源。而这种机制也侧面降低了整个事务的阻塞时间和范围。

另外,通过CanCommit、PreCommit、DoCommit三个阶段的设计,相较于2PC而言,多设置了一个缓冲阶段保证了在最后提交阶段之前各参与节点的状态是一致的。

以上就是3PC相对于2PC的一个提高(相对缓解了2PC中的前两个问题),但是3PC依然没有完全解决数据不一致的问题

3、TCC (Try-Confirm-Cancel)补偿模式——最终一致性

由服务 A、服务B、服务C、服务D 共同组成的一个微服务架构系统。服务A 需要依次调用服务B、服务C 和服务D 共同完成一个操作。当服务A 调用服务D 失败时,若要保证整个系统数据的一致性,就要对服务B 和服务C 的invoke 操作进行回滚,执行反向的revert 操作。回滚成功后,整个微服务系统是数据一致的。

针对每个操作,都要注册一个与其对应的确认和补偿(撤销)操作
Try操作做业务检查及资源预留,Confirm做业务确认操作,Cancel3实现一个与Try相反的操作既回滚操作。

TM首先发起所有的分支事务的try操作,任何一个分支事务的try操作执行失败,TM将会发起所有分支事务的Cancel操作,若try操作全部成功,TM将会发起所有分支事务的Confirm操作,其中Confirm/Cancel操作若执行失败,TM会进行重试。
TCC模型对业务的侵入性较强,改造的难度较大,每个操作都需要有try、confirm、cancel三个接口实现,

实现关键要素:

  1. 服务调用链必须被记录下来。
  2. 每个服务提供者都需要提供一组业务逻辑相反的操作,互为补偿,同时回滚操作要保证幂等。
  3. 必须按失败原因执行不同的回滚策略。
3、基于消息队列——最终一致性

消息队列的事务消息:
发送preparei消息到消息中间件
发送成功后,执行本地事务
如果事务执行成功,则commit,消息中间件将消息下发至消费端(commit前,消息不会被消费)
如果事务执行失败,则回滚,消息中间件将这条preparei消息删除
消费端接收到消息进行消费,如果消费失败,则不断重试

待完成

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值