Java并发来一发(十六)分布式事务一致性

目录

一、概论

二、CAP定理

三、BASE理论

四、2PC

五、3PC

六、XA协议

七、TCC模型

八、Raptor


一、概论

系统或DB的拆分会使得数据服务往往不在一个单点系统中,数据一致性也就变成了分布式事务问题。本文主要讨论分布式事务一致性解决方案。

一致性可理解为所有节点都能访问到最新版本的数据,单机情况下使用共享内存和锁就可以解决,但在分布式环境下,要满足一致性,就需要更高的成本了,CAP定理提供了理论指导。

二、CAP定理

CAP定理,指的是在一个分布式系统中,Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可得兼 。

  • 一致性(C):在同一时刻的各个节点上数据是否一致。或客户端的一系列操作是否同时生效。
  • 可用性(A):每个操作都必须以可预期的响应结束
  • 分区容错性(P): 即使出现单个节点不可用,操作依然可以完成。

系统不能同时具备C、A、P也很好理解,由于分布式系统中,单个节点的可靠性、系统网络的可靠性是不可能完美保证的,且节点间有通信成本,也就是说随时保证系统所有节点无时延正确响应操作是不可能做到的。因此,一般系统设计上,会偏重CP或AP,由于系统节点是无法保证一定可靠的,所以分区容错性是必须满足的。

这里有两个需要注意的点,一个是对于CP或AP系统,并不是说这个系统就只重视一致性或可用性,而是在保证一致性的前提下尽量优化另一个特性;另外,很多时候定义的粒度需要更细,一个系统中可能某些场景优先考虑CP,有些场景优先考虑AP。

实际系统设计的时候往往可以按照BASE进行设计,可以满足多数业务场景的需求。

三、BASE理论

BASE是Basically Available(基本可用)、Soft state(软状态)和Eventually consistent(最终一致性)三个短语的简写,BASE理论是对CAP中一致性和可用性权衡的结果。

  • 基本可用:指分布式系统在出现不可预知故障的时候,允许损失部分可用性。如响应时间上的损失、功能上的损失。
  • 最终一致性:强调的是系统中所有的数据副本,在经过一段时间的同步后,最终能够达到一个一致的状态。因此,最终一致性的本质是需要系统保证最终数据能够达到一致,而不需要实时保证系统数据的强一致性。
  • 软状态:是指允许系统中的数据存在中间状态。

四、2PC

Two Phase Commit(2PC)即两阶段提交,其实就是个准备加确认的过程,如果准备和确认都成功了,那么整个事务就成功了。系统中的角色分为分布式事务的协调者和执行操作的参与者,2PC执行过程具体如下:

第一阶段:

1)协调者询问所有的参与者,是否可以执行提交操作;

2)各参与者开始事务执行的准备工作,包括锁资源;

3)参与者回应协调者,可以提交,或拒绝提交。

第二阶段:

1)协调者判断参与者返回的结果,如果所有参与者都可以提交,那么协调者会通知所有参与者确认提交;

2)如果有参与者回应拒绝提交,那么协调者通知所有参与者执行回滚操作。

两阶段提交的好处是,在第一阶段如果有协调者回应拒绝提交,那么就不需执行第二阶段;反之,如果第一阶段都回应可以提交,那么第二阶段成功的概率也很高,这是由于主要的逻辑操作都在第一阶段完成,第一阶段的耗时往往远长于第二阶段,因此第二阶段异常的概率也远低于第一阶段。

关于两阶段提交,有个非常有意思的例子,例子来源于文末的参考资料,耗子叔的博客。

西方教堂结婚的时候,都有这样的桥段:

第一阶级:牧师分别问新郎和新娘:你是否愿意……不管生老病死……(询问阶段)

第二阶段:当新郎和新娘都回答愿意后(锁定一生的资源),牧师就会说:我宣布你们……(事务提交)

例子非常精彩,一看就懂了。

2PC的几个问题:

* 同步阻塞:2PC 有几个过程(比如 Coordinator 等待所有参与者表决的过程中)都是同步阻塞的,在实际的应用中,这可能会导致长阻塞问题,这个问题是通过超时判断机制来解决的,但并不能完全解决同步阻塞问题;

* 数据不一致:如果在第二阶段,Coordinator 和参与者出现挂掉的情况下,是有可能导致数据不一致的。

五、3PC

3PC在2PC的基础上,将2PC的第一阶段拆成了两步,并且引入超时机制。3PC总共三步:

第一步CanCommit:协调者先询问所有参与者是否同意执行操作,参与者做业务检查;

第二步PreCommit:如果都同意操作,则协调者通知所有参与者,开始执行操作。参与者完成后,各自通知协调者。如果收不到协调者的PreCommit执行通知,那么超时后也会执行失败操作。

第三步DoCommit:所有参与者准备好之后,协调者通知参与者提交或回滚。

这样做的好处是,如果第一步返回成功,那么可以认为第二步冲突的概率会较小,也就提高了事务成功的概率。且超时机制使得参与者不会出现一直锁资源的问题。当然,最后阶段通知失败的问题,还是没有解决。并且相对于2PC,3PC多了一次协调者和参与者的交互,增加了网络开销。

六、XA协议

XA协议是一种分布式事务模型,基于2PC实现的。

XA协议中有三个参与方:应用程序AP、事务管理器TM(协调者)、资源管理器RM(参与者)。具体实现就不讲了,其实就是2PC。

XA协议中,事务协调工作都由TM来做,所以XA协议对业务几乎没有入侵,但对RM要求高,要求所有 RM 同等可信、可靠,要求故障恢复机制可靠、快速,在网络故障隔离的情况下,服务基本不可用。

单应用分库分表的分布式事务管理,用XA解决就可以了。

七、TCC模型

TCC(Try-Confirm-Cancel)分布式事务模型相对于 XA 等传统模型,其特征在于它不依赖资源管理器(RM)对分布式事务的支持,而是通过对业务逻辑的分解来实现分布式事务。

TCC其实就是业务层的2PC,分三步:

第一步:try阶段,主业务系统调用所有从业务系统做业务检查,预留业务资源;

第二步:confirm阶段,真正执行业务,所有从业务的confirm操作支持幂等,以便在网络异常情况下可以重试;

第三步:cancel阶段,取消执行业务,同样,所有从业务的cancel操作支持幂等。

TCC 模型的隔离性思想就是通过业务的改造,在第一阶段结束之后,从底层数据库资源层面的加锁过渡为上层业务层面的加锁,从而释放底层数据库锁资源,放宽分布式事务锁协议,提高业务并发性能。但TCC的业务接入成本高。

举例:

假设交易操作需要扣减库存、使用红包、调用支付三步,那么一次交易过程的TCC流程如下:

第一步:交易系统调用库存系统减库存预处理,调用红包系统使用红包预处理,调用支付系统做支付;

第二步:若调支付成功,执行confim操作,调库存系统减库存(可异步重试),调红包系统使用红包(可异步重试),返回交易成功;

第三步:若调支付失败,执行cancel操作,调库存系统取消减库存(可异步重试),调红包系统取消使用红包(可异步重试),返回交易失败;若调支付超时,同样执行cancel操作,除调库存和红包系统外,还需调支付系统做退款。

八、Raptor

实际应用的分布式事务模型一般都是基于以上模型或扩展进行的优化,Raptor是公司的分布式事务中间件,基于2PC做的,主要有两点:

1)Raptor(协调者)和业务系统(参与者)之间的交互都是基于异步消息的。好处是对业务流程影响小,避免同步阻塞影响效率;缺点是无法直接得到业务结果,异步执行可能通信失败。解决办法是业务系统需要加本地事务表,最终的一致性状态以此表为依据,如果通信出现问题,则以此表结果为准。

2)协调者如果发生了故障,整个分布式服务就挂了,解决办法是Raptor本身就是个集群,有backup。

九、消息日志

常用的分布式事务处理方式还有一种消息日志的方式,思路是将服务中可以异步执行的RPC操作先加入日志表(带状态),调度扫表或者通过MQ(最好是基于DB事件变化通知的MQ,减少对业务入侵)发起RPC操作,成功后更新日志表状态。如果服务中调用的同步RPC失败,则进行业务回滚,对于上述异步调用的RPC接口,也需要重试调用回滚操作。

 

参考资料:

https://coolshell.cn/articles/10910.html

https://blog.csdn.net/javahongxi/article/details/79666753

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值