分布式事务

分布式事务的一致性的解决方案及其优缺点

转账问题,利用消息队列保证事务一致性

金融转账

消息堆积,重复,丢失解决方案

链接

CAP理论详解

BASE 理论
BASE 理论, 是对CAP中AP的一个扩展,对于我们的业务系统,我们考虑牺牲一致性来换取系统的可用性和分区容错性。BASE是Basically Available(基本可用),Soft state(软状态),和 Eventually consistent(最终一致性)三个短语的缩写。

Basically Available

基本可用:通过支持局部故障而不是系统全局故障来实现的。如将用户分区在 5 个数据库服务器上,一个用户数据库的故障只影响这台特定主机那 20% 的用户,其他用户不受影响。

Soft State

软状态,状态可以有一段时间不同步

Eventually Consistent

最终一致,最终数据是一致的就可以了,而不是时时保持强一致。

常用的分布式事务解决方案有:

两阶段提交
三阶段提交
TCC
本地消息表
最大努力通知
saga

目前分布式事务是怎么解决的呢?
以购买基础商品成功后发送支付订单完成消息为例:

假设支付下单购买基础商品,此刻已经收到支付回调,订单已经处理成功了,这个时候kafka服务故障,消息发送失败;而这个时候处理订单的事务已经提交了,怎么保证订单完成的消息一定能发出去呢?
在这里插入图片描述

解读一下这个流程:

绿色部分,表示流程正常运行的交互过程:

先往JobController中提交一个job(用于故障恢复)
提交成功后,开始处理订单逻辑
处理完订单逻辑之后,开始发送kafka消息
消息也发送成功后,删除第一步提交的job
黄色部分,表示流程出现了异常,数据可能存在不一致现象。这个时候就需要进行流程恢复

JobController任务控制器定时去redis查询延时任务列表(每个任务都有一个时间戳,按时间戳排序过滤)
将任务进行恢复(调用job注册时定义的处理方法)
任务执行成功,表示流程完成;否则下一个定时周期重试

saga,则是一种基于补偿的消息驱动的用于解决long-running process的一种解决方案。目标是为了在确保系统高可用的前提下尽量确保数据的一致性。 还是上面的例子,如果用saga来实现,那就是这样的流程:服务器A的事务先执行,如果执行顺利,那么事务A就先行提交;如果提交成功,那么就开始执行事务B,如果事务B也执行顺利,则事务B也提交,整个事务就算完成。但是如果事务B执行失败,那事务B本身需要回滚,这时因为事务A已经提交,所以需要执行一个补偿操作,将已经提交的事务A执行的操作作反操作,恢复到未执行前事务A的状态。这样的基于消息驱动的实现思路,就是saga。我们可以看出,saga是牺牲了数据的强一致性,仅仅实现了最终一致性,但是提高了系统整体的可用性。

补偿事务(TCC)
TCC 其实就是采用的补偿机制,其核心思想是:针对每个操作,都要注册一个与其对应的确认和补偿(撤销)操作。TCC模型是把锁的粒度完全交给业务处理。它分为三个阶段:

Try 阶段主要是对业务系统做检测及资源预留
Confirm 阶段主要是对业务系统做确认提交,Try阶段执行成功并开始执行 Confirm阶段时,默认 Confirm阶段是不会出错的。即:只要Try成功,Confirm一定成功。
Cancel 阶段主要是在业务执行错误,需要回滚的状态下执行的业务取消,预留资源释放
下面对TCC模式下,A账户往B账户汇款100元为例子,对业务的改造进行详细的分析:
在这里插入图片描述

本地消息表(异步确保)
本地消息表这种实现方式应该是业界使用最多的,其核心思想是将分布式事务拆分成本地事务进行处理,这种思路是来源于ebay。我们可以从下面的流程图中看出其中的一些细节:
在这里插入图片描述

基本思路就是:

消息生产方,需要额外建一个消息表,并记录消息发送状态。消息表和业务数据要在一个事务里提交,也就是说他们要在一个数据库里面。然后消息会经过MQ发送到消息的消费方。如果消息发送失败,会进行重试发送。

消息消费方,需要处理这个消息,并完成自己的业务逻辑。此时如果本地事务处理成功,表明已经处理成功了,如果处理失败,那么就会重试执行。如果是业务上面的失败,可以给生产方发送一个业务补偿消息,通知生产方进行回滚等操作。

生产方和消费方定时扫描本地消息表,把还没处理完成的消息或者失败的消息再发送一遍。如果有靠谱的自动对账补账逻辑,这种方案还是非常实用的。

事务消息
事务消息作为一种异步确保型事务, 将两个事务分支通过MQ进行异步解耦,事务消息的设计流程同样借鉴了两阶段提交理论,整体交互流程如下图所示:
1.在这里插入图片描述
1.事务发起方首先发送prepare消息到MQ。
2.在发送prepare消息成功后执行本地事务。
3.根据本地事务执行结果返回commit或者是rollback。
4.如果消息是rollback,MQ将删除该prepare消息不进行下发,如果是commit消息,MQ将会把这个消息发送给consumer端。
5.如果执行本地事务过程中,执行端挂掉,或者超时,MQ将会不停的询问其同组的其它producer来获取状态。
6.Consumer端的消费成功机制有MQ保证。

有一些第三方的MQ是支持事务消息的,比如RocketMQ,但是市面上一些主流的MQ都是不支持事务消息的,比如 RabbitMQ 和 Kafka 都不支持。

尽最大努力通知
通过定期校对,实现数据一致性。
最大努力通知方案的实现:

业务活动的主动方,在完成业务处理之后,向业务活动的被动方发送消息,允许消息丢失。
主动方可以设置时间阶梯型通知规则,在通知失败后按规则重复通知,直到通知N次后不再通知。
主动方提供校对查询接口给被动方按需校对查询,用于恢复丢失的业务消息。
业务活动的被动方如果正常接收了数据,就正常返回响应,并结束事务。
如果被动方没有正常接收,根据定时策略,向业务活动主动方查询,恢复丢失的业务消息
最大努力通知方案的特点:

用到的服务模式:可查询操作、幂等操作。
被动方的处理结果不影响主动方的处理结果;
适用于对业务最终一致性的时间敏感度低的系统;
适合跨企业的系统间的操作,或者企业内部比较独立的系统间的操作,比如银行通知、商户通知等;

分布式共识算法

paoxs算法

Raft算法

zab算法

AT模式(阿里分布式框架seata)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值