分布式事务原理及落地方案

分布式事务主要解决的问题就是数据一致性的问题。有两种处理方式,一种是通过强一致性来保证的,一种是通过最终一致性来保证。他们典型的方案有:

  1. 强一致性
  2. 最终一致性

什么是分布式事务

百度百科:分布式事务是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。这是多系统尤其是微服务框架系统中一定会面临的问题。毫不吹牛逼的讲,如果你的微服务系统中没有使用我讲的分布式事务方法,那你的系统设计一定会存在问题。

一致性理论

分布式事务的目的是解决应用垂直拆分(就是根据功能模块建立多个库)后的分库数据的一致性的,因为数据表建在多个数据库中,如果某个节点宕机,就无法像单机一样保证事务的ACID。所以,业界CAP理论告诉我们,为了满足分布式环境下事务的一致性,需要将数据一致性(Consistency)、系统可靠性(Availability)和分区容忍性(Partition Tolerance)放一起考虑。并且这3个要素只能同时满足两个。需要聪明的你根据实际的业务场景选择其中的两者。

CAP理论

  • 一致性:分布式环境下多个数据表的数据状态一定要在秒级内达到一致(强一致性)。如客户支付后,订单状态为支付成功,同时商品数减少。
  • 可用性:分布式服务能一直保证可用状态。当用户发出一个请求后,服务能在有限时间内返回结果。
  • 分区容忍性:特指对网络分区的容忍性。即分布式系统在遇到某节点或网络分区故障的时候,仍然能够对外提供可用性的服务。

常见中间件的CAP

中间件APCP说明
Cassandra1
Dynamo1
HBase1
MongoDB1MongoDB 为了保证可用性和分区容错性,采用的是副本集的方式,这种模式就必须要解决的一个问题就是怎样快速在系统启动和 Primary 发生异常时选取一个合适的主节点。MongoDB 的选举算法是基于 Raft 协议的改进
Eureka1Eureka各个节点都是平等的,几个节点挂掉不会影响正常节点的工作,剩余的节点依然可以提供注册和查询服务。而Eureka的客户端在向某个Eureka注册或时如果发现连接失败,则会自动切换至其它节点,只要有一台Eureka还在,就能保证注册服务可用(保证可用性),只不过查到的信息可能不是最新的(不保证强一致性),其中说明了,eureka是不满足强一致性,但还是会保证最终一致性
ZK1zookeeper在选举leader时,会停止服务,直到选举成功之后才会再次对外提供服务,这个时候就说明了服务不可用,但是在选举成功之后,因为一主多从的结构,zookeeper在这时还是一个高可用注册中心,只是在优先保证一致性的前提下,zookeeper才会顾及到可用性

在这里插入图片描述

分布式事务分析方法

分布式事务是指会涉及到操作多个数据库的事务,在分布式系统中,各个节点之间在物理上相互独立,通过网络进行沟通和协调。在任意时刻,任意进程(应用、数据库、中间件)或进程间网络通信发生临时故障时,分布式事务能否整体恢复或回滚,保持事务的 ACID 特性。

CAP理论告诉我们,我们很多时候需要保证系统的AP特性,可能需要舍弃C。故出现了BASE理论。
BASE理论是基本可用、柔性状态和最终一致性。通常所说的柔性事务分为:两阶段型、补偿型、异步确保型、最大努力通知型几种。BASE模型反ACID模型,完全不同ACID模型,牺牲高一致性,获得可用性或可靠性。

强一致性包括两阶段提交协议、三阶段提交协议。市面上具体的中间件有LCN框架从5.0开始兼容了LCN、TCC、TXC三种事务模式,阿里的seata。
弱一致性包括

两阶段提交协议

XA(eXtended Architecture)就是X/Open DTP定义的交易中间件与数据库之间的接口规范(即接口函数),交易中间件用它来通知数据库事务的开始、结束以及提交、回滚等。XA接口函数由数据库厂商提供,目前几乎所有收费的商业数据库都支持XA协议。

二阶段提交(Two-phaseCommit)是指,在计算机网络以及数据库领域内, 为了使基于分布式系统架构下的所有节点在进行事务提交时保持一致性而设计的一种算法(Algorithm)。在分布式系统中,每个节点虽然可以知晓自己的操作时成功或者失败,却无法知道其他节点的操作的成功或失败。当一个事务跨越多个节点时,为了保持事务的 ACID 特性, 需要引入一个作为协调者的组件来统一掌控所有节点(称作参与者)的操作结果并最终指示这些节点是否要把操作结果进行真正的提交(比如将更新后的数据写入磁盘等等)。 因此,二阶段提交的算法思路可以概括为:参与者将操作成败通知协调者,再由协调者根据所有参与者的反馈情报决定各参与者是否要提交操作还是中止操作。
在这里插入图片描述

准备阶段

事务协调者(事务管理器)给每个参与者(资源管理器)发送 Prepare 消息,每个参与者要么直接返回失败(如权限验证失败),要么在本地执行事务, 写本地的 redo 和 undo 日志,但不提交,到达一种“万事俱备,只欠东风”的状态。

提交阶段

如果协调者收到了参与者的失败消息或者超时,直接给每个参与者发送回滚(Rollback)消息;否则,发送提交(Commit)消息;参与者根据协调者的指令执行提交或者回滚操作,释放所有事务处理过程中使用的锁资源。 (注意:必须在最后阶段释放锁资源)。

缺点

  1. 正常-同步阻塞问题
    执行过程中,所有参与节点都是事务阻塞型的,参与者占用线程排队阻塞等待。
  2. 节点本身异常-单点故障
    由于协调者的重要性,一旦协调者发生故障。参与者会一直阻塞下去。可能引起长事务问题。
  3. 异常-数据状态不确定
    协调者再发出commit消息之后宕机,而唯一接收到这条消息的参与者同时也宕机了。那么即使协调者通过选举协议产生了新的协调者,这时事务的状态也是不确定的,没人知道事务是否被已经提交。
  4. 网络异常-数据不一致(脑裂问题)
    在二阶段提交的阶段中,当协调者向参与者发送commit请求后,发生了局部网络异常或者在发生commit请求过程中协调者发生了故障,导致只有一部分参与者接受到了commit请求,于是整个分布式系统便出现了数据一致性的现象(脑裂现象)。

三阶段提交协议

三阶段提交协议是两阶段提交协议有两个改动点。

  1. 细分为三阶段,在第一阶段和第二阶段中插入一个准备阶段。保证了在最后提交阶段之前各参与节点的状态是一致的。也就是说,除了引入超时机制之外, 3PC 把 2PC 的准备阶段再次一分为二,这样三阶段提交就有 CanCommit、 PreCommit、 DoCommit 三个阶段。PreCommit是一个缓冲,保证了在最后提交阶段之前各参与节点的状态是一致的。所以仍然存在数据不一致问题,在第三阶段如果只有一个参与者收到了abort操作指令,协调者和其他的参与者都会超时,协调者和参与者都继续提交事务,默认为成功,导致数据不一致。
  2. 引入超时机制。同时在协调者和参与者中都引入了超时机制,减少了阻塞问题。

CanCommit阶段

协调者向参与者发送commit请求,参与者如果可以提交就返回Yes响应,否则就返回No响应。

PreCommit阶段

协调者根据参与者的反应情况来决定是否可以继续进行,有以下两种可能。假如协调者从所有的参与者获得的反馈都是 Yes 响应,那么就会执行事务的预执行,假如有任何一个参与者向协调者发送了 No 响应,或者等待超时之后,协调者都没有接到参与者的响应,那么就执行事务的中断。

doCommit阶段

该阶段进行真正的事务提交, 主要包含 1.协调这发送提交请求 2.参与者提交事务 3.参与者响应反馈( 事务提交完之后,向协调者发送 Ack 响应。) 4.协调者确定完成事务。

无论是二阶段提交还是三阶段提交都无法彻底解决分布式的一致性问题。Google Chubby的作者Mike Burrows说过, there is only one consensus protocol, and that’s Paxos” – all other approaches are just broken versions of Paxos. 意即世上只有一种一致性算法,那就是Paxos,所有其他一致性算法都是Paxos算法的不完整版。

柔性事务

两阶段型

就是分布式事务两阶段提交,对应技术上的XA、JTA/JTS。这是分布式环境下事务处理的典型模型。

补偿型

TCC(Try/Confirm/Cancel)型事务可归为补偿型。

SAGA事务模型

WS-BusinessActivity 提供了一种基于补偿的 long-running 的事务处理模型。 服务器 A 发起事务,服务器 B 参与事务, 服务器 A 的事务如果执行顺利,那么事务 A 就先行提交,如果事务 B 也执行顺利,则事务 B 也提交,整个事务就算完成。但是如果事务 B 执行失败,事务 B 本身回滚,这时事务 A 已经被提交,所以需要执行一个补偿操作,将已经提交的事务 A 执行的操作作反操作,恢复到未执行前事务 A 的状态。这样的 SAGA 事务模型,是牺牲了一定的隔离性和一致性的,但是提高了 long-running 事务的可用性。
在这里插入图片描述

异步确保型

通过将一系列同步的事务操作变为基于消息执行的异步操作, 避免了分布式事务中的同步阻塞操作的影响。
在这里插入图片描述

最大努力通知型(多次尝试)

与前面异步确保型操作不同的一点是, 在消息由 MQ Server 投递到消费者之后, 允许在达到最大重试次数之后正常结束事务。

本地事务

紧密依赖于底层资源管理器(例如数据库连接 ),事务处理局限在当前事务资源内。此种事务处理方式不存在对应用服务器的依赖,因而部署灵活却无法支持多数据源的分布式事务。在数据库连接中使用本地事务示例如下:


鸣谢

1、 常见分布式理论(CAP、BASE)和一致性协议(Gosssip协议、Raft一致性算法):https://blog.youkuaiyun.com/a745233700/article/details/122401700

2、 七种常见分布式事务详解(2PC、3PC、TCC、Saga、本地事务表、MQ事务消息、最大努力通知)
https://blog.youkuaiyun.com/a745233700/article/details/122402303

3、CAP数据库https://www.ibm.com/topics/cap-theorem

4、CAP Theorem for Databases: Consistency, Availability & Partition Tolerance https://www.bmc.com/blogs/cap-theorem/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值