对分布式事务的系统理解

前言

前面写了几篇分布式事务相关的博客,有些地方理解不是很到位,知识也没有串联起来,本篇博客讲前面知识串联起来,综合理解分布式事务。

CAP理论与BASE理论

一直有个疑问,CAP理论,到底是在说分布式中不同业务节点,还是在说集群节点。因为从后面的描述来看,一会儿是集群节点的概念,一会儿是分布式不同业务节点的概念,搞的很晕。特意查阅了资料,在CAP理论中,既包括集群节点,又包括分布式不同业务节点。这么理解CAP,就好理解了。

P:分区容错性
先说分区,分布式系统是有很多节点的。当因为网络问题,或者是节点自身宕机等问题,造成节点之间通信异常了,那么就是分区了。分区容错性就是指出现分区后,分布式系统对外依然可用,而不至于由于某个节点或网络问题造成全部崩溃。
搭建集群就是提升分区容错性的一个手段。此外,熔断,降级,也是提升分区容错性的手段。所以,从分区容错性而言,分布式不同业务节点这个角度来理解,是比较合理的。

C:一致性
一致性这个概念,就需要从分布式链路节点和集群节点两个角度去理解了。
在集群节点中,数据一致性就是数据的拷贝复制,达到一致性。无论从集群哪个节点读取数据,数据都是一致的。

从分布式链路节点来理解,就是A节点改变了数据,级联B节点也要改变数据。两个数据的改变要一致。例如,A系统给B系统转账,那么A系统减少的钱数,必须与B系统增加的钱数一致。这也是一致性的含义。

A:可用性
可用性是一致性的矛盾体。要达到强一致性,无论是集群节点的数据复制,还是分布式链路节点的数据一致,都需要等各节点的数据保证一致后,才能对外提供服务。那么在数据同步或者达到数据一致性这个过程期间,系统就是对外不可用的。这就影响了系统抗并发的能力。

上面就是CAP理论。针对CAP理论中C和A如何取舍的问题,BASE理论给出了一个合理的解决方案,那就是在保证系统AP的基础上,不要求系统强一致性。而是有个中间状态,这个中间状态,数据一致性可以不一致。而最终,数据一致性要得到保证。

DTP模型与XA协议

DTP模型是定义分布式事务实现思路的一套模型,其本质就是定义了几个角色,以及这几个角色的分工:

  • 应用程序AP:我们的项目
  • 事务协调器TM:全局事务管理者
  • 数据库RM
  • 通信资源管理器(CRM):是TM和RM间通信的中间件

几个角色的分工就是: AP是分布式系统的链路节点,每个节点有自己的本地事务,保证ACID特性。多个节点的本地事务共同组成一个分布式事务。RM就是多个分布式链路节点对应的要操作的数据库。
那么多个节点的本地事务如何统一管理,组成分布式事务呢?这就用到了TM协调者,来协调各节点的本地事务是统一提交呢,还是统一回滚呢。CRM是TM与RM的通信中间件,负责通信。

DTP模型只是定义了分布式事务的实现思路。那么以上思路而言,有一个问题,就是多个节点的AP以及对应的RM,不一定是同一种类型的数据库。例如,a节点连的mysql数据库,b节点连的oracle数据库,c节点连的sqlserver数据库。那么TM就是与3种类型的数据库在通信协调,总得有一个规范吧,不可能和mysql打交道,是一套通信规范,和oracle打交道,是另一套通信规范吧。XA协议,就是定义了数据库RM与TM之间通信规范的一种协议

2PC与3PC

2PC与上述的DTP模型和XA协议有啥关系呢?在DTP模型中,指定了要使用两阶段提交(2PC),而XA规范(« Distributed Transaction Processing: The XA Specification»)只是定义了两阶段提交协议中需要使用到的接口,也就是上述提到的RM-TM交互的接口,因为两阶段提交过程中的参与方,只有TM和RMs。由此可见,是DTP模型指定了要使用2PC,而XA协议又对2PC做了一些接口规范。就是这么个关系。

具体的2PC流程这里不说了,前面文章讲过,现在只有一个疑问,在2PC第二个阶段,即提交阶段,出现异常了,该如何处理呢?
当协调者在阶段1收到所有准备请求答复时,就是否提交事务要做出明确的决定,并把最后的决定写入磁盘的事务日志中,防止系统崩溃。
在执行第二阶段提交时,假如协调者发生了故障,例如,协调者往A节点发送了提交命令,此时挂了,没来得及给B节点发送提交命令。那么,当TM重启后,因为将决定记录到了日志中,所以会读取日志,继续向B节点发送提交命令。
在执行第二阶段提交时,假如某个RM节点挂了,没有提交成功,那么,等这个RM启动后,也必须执行。
可见,当阶段一结束后,TM做出的提交或者回滚的结论,是不可撤销改变的,一定要执行完。不管是TM宕机还是RM宕机,恢复后也要继续执行。

因此,不管是TM还是RM在第二阶段发生故障时,都会发生阻塞等待,必须等到发生故障的节点恢复,并执行完毕提交或回滚,分布式事务才能结束。所以,2PC模式保证了数据的强一致性,但是,一旦发生故障,就会造成程序的阻塞,可用性很差。

3PC是针对2PC缺陷提出的一种改进方案,仅存在理论层面,没有任何实现,暂时不管这个了。

JTA与atomikos

JTA是XA协议在java中的规范。类似于JDBC规范。atomikos是遵循JTA规范实现了XA协议的一个java程序框架。所以,atomikos也实现了2PC。我们可以直接使用此框架进行2PC分布式事务使用。

TCC模式与AT模式

TCC是应用层面的2PC。XA是数据库层面的2PC。TCC由程序员自己去写代码逻辑控制。
TCC也是一种思想模式,并没有严格规范一定要怎样怎样做,全看程序员如何实现。
在try阶段,是资源预留阶段,预留阶段就是校验本地事务是否能够成功,具体如何校验,程序员自己定义。
Confirm阶段进行提交,Cancel阶段进行回滚。完全可以在try阶段进行本地事务的提交,然后confirm阶段不做任何处理,而在cancel阶段进行事务提交的补偿,类似于undo日志回滚那种形式也完全可以。

TCC模式是程序员自己控制的,所以阻塞与否完全可以自己控制。但是代码侵入性极大,还需要考虑幂等性,重试等问题。

AT模式是SEATA框架实现的一种模式,其本质也是TCC模式,只不过由框架实现,我们直接使用即可。

MQ模式

使用MQ实现分布式事务,需要借助本地消息表。本地事务表中,存储其他节点事务的状态。当A节点发起分布式事务后,通过MQ发送消息,告诉其他节点要执行分布式事务。同时,哪些节点要执行事务,写进本地消息表中。其他节点从MQ中收到消息后,执行本地事务,执行成功后,去A节点本地消息表中修改状态,代表事务执行了。同时,A节点会开启定时任务,去检查本地消息表是否执行成功了,如果没有成功,就再次发送MQ,让其他节点继续执行事务,直到事务成功。

此模式采用了BASE理论,达到了最终一致性,对于强制一致性低的场景,可以考虑此模式。

猜你喜欢

转载自blog.csdn.net/qq1309664161/article/details/127299631