几种分布式事务实现方案

目录

 

CAP(Consistency、Availability、Partition Tolerence)理论

BASE理论

2PC两阶段提交方案/XA方案

TCC方案

可靠消息最终一致性方案

最大努力通知方案


CAP(Consistency、Availability、Partition Tolerence)理论

一、一致性(C)

就是说一个分布式系统中,一旦你做了一个数据的修改,那么这个操作成功的时候,就必须是分布式系统的各个节点都是一样的。

例如客户端发起一个数据修改的请求,然后服务器返回成功了,结果去查的时候,从某个节点上查询数据,发现这个数据不对,这样的话就成了数据不一致了,就是分布式系统的各个节点上的数据是不一样的,也就是所谓的强一致性。

弱一致性,就是更新数据后,不确定各个节点间是否都更新成功;最终一致性,就是更新后,一段时间内不一致,但是最后过了一段时间各个节点间都更新成功。

二、可用性(A)

就是说分布式系统必须是可用的

三、分区容错性(P)

布式系统在遇到任何网络分区故障的时候,仍然需要能够保证对外提供满足一致性和可用性的服务。

四、CP

经典的就是一些分布式存储,比如说zookeeper、mongodb、hbase等等,跟他们都是CP的,也就是说数据100%一致,但是有可能有些时候你请求是失败的,不让你请求到不一致的数据,这就是CP。

五、AP

如果网络故障,数据没同步,数据处于不一致的状态下,要保证A,可用性,你两个节点都要允许任何客户端来查询,都可以查到,这样的话呢,整个系统就处于可用的状态下,但是此时就牺牲掉了C。

对于12306、电商系统,这种业务类系统,一般都是AP,也就是说,你可能看到的商品库存或者火车票的库存,是错的,有可能是旧的啊,那么数据很可能看到的都是不一致的,但是呢,你买东西或者买票的时候,一定会检查库存,就可以了,但是保证了可用性,任何时候都要响应结果。

 

BASE理论

所谓的BASE,Basicly Available、Soft State、Eventual Consistency,也就是基本可用、软状态、最终一致性。

BASE希望的是,CAP里面基本都可以同时实现,但是不要求同时全部100%完美的实现,CAP三者同时基本实现,BASE,基本可用、最终一致性

此时要保证基本可用性,两个节点都可以查询的,但是这个时候会发现有的节点可以返回数据,有的节点无法返回数据,会看到不一致的状态,这个不一致的状态,就是指的是BASE中的S,soft state,软状态;

基本可用,降级,正常情况下,是查询可以负载均衡到各个节点去查的,也就是可以多节点抗高并发查询,但是此时如果你要降级的话,可以降级为,所有客户端强制查询主节点,这样看到的数据暂时而言都是一样的,都是从主节点去查。因为客户端访问量太大了,同时用一个主节点来支撑很坑,扛不住,怎么办呢,主节点做限流降级,也就是说如果流量太大了,直接返回一个空,让你稍后再来查询;

最终一致性,一旦故障或者延迟解决了,数据过了一段时间最终一定是可以同步到其他节点的,数据最终一定是可以处于一致性的。

 

2PC两阶段提交方案/XA方案

将事务的提交过程分成提交事务请求和执行事务提交两个阶段进行处理。这种分布式事务方案,比较适合单块应用里,跨多个库的分布式事务,而且因为严重依赖于数据库层面来搞定复杂的事务,效率很低,不适合高并发的场景。

 

TCC方案

try接口里是锁定资源,confirm是业务逻辑,cancel是回滚逻辑

try接口里,一般就是预留资源,比如说经典的资金转账,卡掉一些锁定资金,要是不这么控制,万一别的分布式事务给干掉了一些资金,那么实际执行confirm的时候一旦检查资金余额就会发现转账失败,余额不足了;有些接口,没有资源锁定的操作,try接口就留空。

confirm就是原来的业务方法,执行实际的转账操作,A银行账户的资金扣减,B银行账户的资金增加。

cnacel接口,要提供回滚的方法,就是把try或者confirm里的操作给回滚。

比如说,如果是try阶段,资金服务的try成功了,资金被冻结了,结果订单服务的try失败了,主业务服务就会通知回滚,调用资金服务的cancel接口,将冻结的金额给解冻。

confirm阶段,资金服务,把钱从iA账号里转移到B账号里去了,结果某一服务的confirm失败了,整个分布式事务回滚,调用各个接口的cancel接口。

(1)、空回滚

当没有调用参与方Try方法的情况下,就调用了二阶段的Cancel方法,Cancel方法需要有办法识别出此时Try有没有执行。如果Try还没执行,表示这个Cancel操作是无效的,即本次Cancel属于空回滚;如果Try已经执行,那么执行的是正常的回滚逻辑。

(2)、倒置请求

比如调用try接口,中间网络超时,结果认定失败,直接调用cancel空回滚;结果过了几秒钟try接口请求到来,要在这个时候不允许执行try接口操作;同理,confirm请求超时了,结果都cancel掉了,但是过了几秒请求来了,也不允许执行confirm操作。

(3)、接口的幂等性保证

try、confirm和cancel都可能被多次调用,所以得保证这几个接口的幂等性,分布式接口幂等性那必须依赖第三方的中间件来实现,可以考虑使用经典的zk,zk非常适用于分布式系统的协调类操作。所以一个接口对同一个参数调用,只能调用一次,保证幂等操作。

 

可靠消息最终一致性方案

这个方案,适合于那那种比较耗时的操作,通过这个消息中间件做成异步调用,发送一个消息出去,由服务消费消息来执行业务逻辑。

1)A系统先发送一个prepared消息到mq,如果这个prepared消息发送失败那么就直接取消操作;

2)如果这个消息发送成功过了,那么接着执行本地事务,如果成功就告诉mq发送确认消息,如果失败就告诉mq回滚消息;

3)如果发送了确认消息,那么此时B系统会接收到确认消息,然后执行本地的事务;

4)mq会自动定时轮询所有prepared消息回调接口,这个消息是不是本地事务处理失败了,所有没发送确认消息?那是继续重试还是回滚?一般来说这里你就可以查下数据库看之前本地事务是否执行,如果回滚了,那么这里也回滚吧。这个就是避免可能本地事务执行成功了,别确认消息发送失败了。

5)这个方案里,要是系统B的事务失败了咋办?自动不断重试直到成功,如果实在是不行,要么就是针对重要的资金类业务进行回滚,比如B系统本地回滚后,想办法通知系统A也回滚;或者是发送报警由人工来手工回滚和补偿

调用第三方运营商系统接口的操作,适合用可靠消息最终一致性的方案。

最大努力通知方案

跟可靠消息最终一致性方案是类似的,可靠消息最终一致性方案,会保证最终必须要让那个执行成功的,但是最大努力通知方案,不一定保证最终一定会成功,可能会失败,但是他会尽力给你去给你通知那个服务的执行。

比较适合那种不太核心一些服务调用的操作,比如说消息服务,充值好了以后发送短信,一般来说肯定是要发出去短信的,但是如果真的不小心发送失败了,发送短信失败了也无所谓的。

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值