分布式事务和解决方案

当事务涉及到多个数据库或多个子系统,就会产生分布式事务。

分布式事务的CAP理论:

  • Consistency一致性:强一致性,必须确保一个分布式事务中的数据是一致的;
  • Availability可用性:事务的操作必须能正常进行,不能发生异常;
  • Partition Tolerance分区容忍:分布式事务中的任何一方故障不会影响整个系统;

CAP的组合方式:

  • CP:满足一致性和分区容忍。这种方式适合对数据一致性要求高的系统,宁可系统不可访问,也要确保数据一致。例如银行转账场景;
  • AP:满足可用性和区分容忍。大部分互联网系统都是这种模式,确保系统的高可用性,可以忍受一段时间的数据不一致。例如,下订单后,订单会临时处于处理中的状态。过段时间变成已完成,实现最终一致性;
  • CA:就是单体系统;

实践证明,系统只能同时满足两个条件。当前大多数互联网系统满足的都是AP,即实现系统的可用性和稳定性,达到最终一致性。

强一致性和最终一致性:

CAP 理论告诉我们一个分布式系统最多只能同时满足一致性(Consistency)、可用性(Availability)和分区容忍性(Partition tolerance)这三项中的两项,其中AP在实际应用中较多,AP 即舍弃一致性,保证可用性和分区容忍性,但是在实际生产中很多场景都要实现一致性,比如前边我们举的例子主数据库向从数据库同步数据,即使不要一致性,但是最终也要将数据同步成功来保证数据一致。这种一致性和 CAP 中的一致性不同,CAP 中的一致性要求在任何时间查询每个结点数据都必须一致,它强调的是强一致性,但是最终一致性是允许可以在一段时间内每个结点的数据不一致,但是经过一段时间每个结点的数据必须一致,它强调的是最终数据的一致性。

BASE理论

BASE理论是基于AP最终一致性的延伸。BASE指的是Basically Available, S代表Soft State,E代表Eventually Consistent。

  • Basically Available基本可用:即系统确保核心功能的高可用,允许损失部分功能;
  • Soft State软状态:允许在某段时间存在数据不一致的状态。这个状态不应影响系统的功能。例如,电商订单的处理中状态;
  • Eventually Consistent最终一致:经过一段时间,系统数据达到一致性。例如订单最终应该变成已完成的状态;

分布式事务解决方案

2PC: 2阶段提交 和 XA

整个事务分成2个阶段:准备阶段(prepare phase)和提交阶段(commit phase)

角色:

AP:Application Program,应用程序

TM:Transaction Manager,嵌入到程序中的事务管理器,提供编程接口与应用程序交互;管理一个分布式事务的各操作,控制提交,回滚的决策;

RM:Resource Manager,具体执行事务操作;

流程:

AP向TM提出创建事务请求,TM创建分布式事务,并控制其包含的RM执行操作;RM将操作结果返回给TM,所有RM都返回成功时,TM通知其下属所有RM提交;否则通知回滚。

2PC方案是通过数据库的协议实现的。2PC和XA方案的弊端是需要等待提交所有RM提交或回滚完成才释放锁。

Seata方案

Transaction Coordinator(TC):事务协调器,它是独立的中间件,需要独立部署运行,它维护全局事务的运行状态,接收 TM 指令发起全局事务的提交与回滚,负责与 RM 通信协调各各分支事务的提交或回滚。

Transaction Manager(TM):事务管理器,TM 需要嵌入应用程序中工作,它负责开启一个全局事务,并最终向 TC 发起全局提交或全局回滚的指令。

Resource Manager(RM):控制分支事务,负责分支注册、状态汇报,并接收事务协调器 TC 的指令,驱动分支(本地)事务的提交和回滚。

具体的执行流程如下: 1.用户服务的 TM 向 TC 申请开启一个全局事务,全局事务创建成功并生成一个全局唯一的 XID。 2.用户服务的 RM 向 TC 注册分支事务,该分支事务在用户服务执行新增用户逻辑,并将其纳入 XID 对应全局事务的管辖。 3.用户服务执行分支事务,向用户表插入一条记录。 4.逻辑执行到远程调用积分服务时(XID 在微服务调用链路的上下文中传播)。积分服务的 RM 向 TC 注册分支事务,该分支事务执行增加积分的逻辑,并将其纳入 XID 对应全局事务的管辖。 5.积分服务执行分支事务,向积分记录表插入一条记录,执行完毕后,返回用户服务。 6.用户服务分支事务执行完毕。 7.TM 向 TC 发起针对 XID 的全局提交或回滚决议。 8.TC 调度 XID 下管辖的全部分支事务完成提交或回滚请求。

Seata实现2PC与传统2PC的差别

架构层次方面:传统 2PC 方案的 RM 实际上是在数据库层,RM 本质上就是数据库自身,通过 XA 协议实现,而 Seata 的 RM 是以 jar 包的形式作为中间件层部署在应用程序这一侧的。

两阶段提交方面:传统 2PC无论第二阶段的决议是 commit 还是 rollback ,事务性资源的锁都要保持到 Phase2 完成才释放。而 Seata 的做法是在 Phase1 就将本地事务提交,这样就可以省去 Phase2 持锁的时间,整体提高效率。

可靠消息最终一致性

事务流程中有消息队列参与。但在发送和消费消息的过程中,由于网络原因,可能会造成消息丢失、重复消费等情况。eBay的解决方案是通过本地消息日志表和消息幂等性来解决,具体方案如下:

  1. 本地创建消息日志表,将分支事务操作与记录消息日志放在一个本地事务中。这样确保数据和消息的原子性;
  2. 通过定时器遍历日志中的消息,发送给MQ;MQ反馈消息发送成功后,删除这条日志;否则等待下一次定时器运行再次发送;
  3. 消息消费者监听MQ,处理成功则向MQ发送ack;否则MQ继续尝试向消费者发送消息。为避免重复消费,消息消费者需要确保消息的处理幂等性;

 可靠消息最终一致性就是保证消息从生产方经过消息中间件传递到消费方的一致性: 本地事务与消息发送的原子性问题。 事务参与方接收消息的可靠性。

可靠消息最终一致性事务适合执行周期长且实时性要求不高的场景。引入消息机制后,同步的事务操作变为基于消息执行的异步操作, 避免了分布式事务中的同步阻塞操作的影响,并实现了两个服务的解耦。

常见场景:注册送积分、购买送积分、订单与库存处理等。

最大努力通知

业务流程处理完毕需要通知服务调用方,调用方依据处理结果执行相应的操作。但是回调通知的过程中可能会出现消息丢失,而无法通知到调用者。所以需要分布式事务对通知流程做处理。最大努力通知的第一个方案流程如下:

  1. 服务调用者调用服务执行操作。执行者完成后向MQ发送处理成功消息;
  2. 通知程序监听MQ,并调用通知接收者的接口完成通知,返回ack给MQ;如果通知程序没有返回ack,则MQ尝试继续通知。

 第二个方案流程,用账户充值案例说明:

  1. 账户系统调用充值系统接口
  2. 充值系统完成支付处理向账户发起充值结果通知,
  3. 若通知失败,则充值系统按策略进行重复通知
  4. 账户系统接收到充值结果通知修改充值状态
  5. 账户系统未接收到通知会主动调用充值系统的接口查询充值结果

 通过上边的例子我们总结最大努力通知方案的目标:发起通知方通过一定的机制最大努力将业务处理结果通知到接收方。

典型的使用场景:银行通知、支付结果通知等。

可靠消息最终一致性和最大努力通知的区别

两者的业务应用场景不同

可靠消息一致性关注的是交易过程的事务一致,以异步的方式完成交易。最大努力通知关注的是交易后的通知事务,即将交易结果可靠的通知出去。

技术解决方向不同

可靠消息一致性要解决消息从发出到接收的一致性,即消息发出并且被接收到。最大努力通知无法保证消息从发出到接收的一致性,只提供消息接收的可靠性机制。可靠机制是,最大努力的将消息通知给接收方,当消息无法被接收方接收时,由接收方主动查询消息(业务处理结果)。

解决方案思想不同

可靠消息一致性,发起通知方需要保证将消息发出去,并且将消息发到接收通知方,消息的可靠性关键由发起通知方来保证。最大努力通知,发起通知方尽最大的努力将业务处理结果通知为接收通知方,但是可能消息接收不到,此时需要接 收通知方主动调用发起通知方的接口查询业务处理结果,通知的可靠性关键在接收通知方。

总结

2PC 最大的诟病是一个阻塞协议。RM 在执行分支事务后需要等待 TM 的决定,此时服务会阻塞并锁定资源。由于其阻塞机制和最差时间复杂度高,因此,这种设计不能适应随着事务涉及的服务数量增加而扩展的需要,很难用于并发较高以及子事务生命周期较长(long-running transactions) 的分布式服务中。 如果拿TCC事务的处理流程与2PC两阶段提交做比较,2PC 通常都是在跨库的 DB 层面,而 TCC 则在应用层面的处理,需要通过业务逻辑来实现。这种分布式事务的实现方式的优势在于,可以让应用自己定义数据操作的粒度,使得降低锁冲突、提高吞吐量成为可能。而不足之处则在于对应用的侵入性非常强,业务逻辑的每个分支都需要实现 Try、Conrm、Cancel 三个操作。此外,其实现难度也比较大,需要按照网络状态、系统故障等不同的失败原因实 现不同的回滚策略。典型的使用场景:满减,登录送优惠券等。 可靠消息最终一致性事务适合执行周期长且实时性要求不高的场景。引入消息机制后,同步的事务操作变为基于消息执行的异步操作, 避免了分布式事务中的同步阻塞操作的影响,并实现了两个服务的解耦。典型的使用场景:注册送积分,登录送优惠券等。 最大努力通知是分布式事务中要求最低的一种,适用于一些最终一致性时间敏感度低的业务;允许发起通知方处理业务失败,在接收通知方收到通知后积极进行失败处理,无论发起通知方如何处理结果都会不影响到接收通知方的后续处理;发起通知方需提供查询执行情况接口,用于接收通知方校对结果。典型的使用场景:银行通知、支付结果通知等。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

做IT的小伟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值