mysql分布式事务的缺陷_分布式事务的一致性的解决方案及其优缺点-程序员宅基地

技术标签: mysql分布式事务的缺陷  

背景

分布式事务是企业集成中的一个技术难点,也是每一个分布式系统架构中都会涉及到的一个东西,特别是在微服务架构中,几乎可以说是无法避免。

ACID

指数据库事务正确执行的四个基本要素:

原子性(Atomicity)

一致性(Consistency)

隔离性(Isolation)

持久性(Durability)

CAP

CAP原则又称CAP定理,指的是在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容忍性(Partition tolerance)。CAP 原则指的是,这三个要素最多只能同时实现两点,不可能三者兼顾。

一致性:在分布式系统中的所有数据备份,在同一时刻是否同样的值。

可用性:在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。

分区容忍性:以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在C和A之间做出选择。

BASE理论

BASE理论是对CAP中的一致性和可用性进行一个权衡的结果,理论的核心思想就是:我们无法做到强一致,但每个应用都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性。

Basically Available(基本可用)

Soft state(软状态)

Eventually consistent(最终一致性)

01 两阶段提交(2PC)

两阶段提交2PC是分布式事务中最强大的事务类型之一,两段提交就是分两个阶段提交,第一阶段询问各个事务数据源是否准备好,第二阶段才真正将数据提交给事务数据源。

为了保证该事务可以满足ACID,就要引入一个协调者(Cooradinator)。其他的节点被称为参与者(Participant)。协调者负责调度参与者的行为,并最终决定这些参与者是否要把事务进行提交。处理流程如下:

8c32dc2218134cb061307549b82838bd.png

阶段一

a) 协调者向所有参与者发送事务内容,询问是否可以提交事务,并等待答复。

b) 各参与者执行事务操作,将 undo 和 redo 信息记入事务日志中(但不提交事务)。

c) 如参与者执行成功,给协调者反馈 yes,否则反馈 no。

阶段二

如果协调者收到了参与者的失败消息或者超时,直接给每个参与者发送回滚(rollback)消息;否则,发送提交(commit)消息。两种情况处理如下:

情况1:当所有参与者均反馈 yes,提交事务

a) 协调者向所有参与者发出正式提交事务的请求(即 commit 请求)。

b) 参与者执行 commit 请求,并释放整个事务期间占用的资源。

c) 各参与者向协调者反馈 ack(应答)完成的消息。

d) 协调者收到所有参与者反馈的 ack 消息后,即完成事务提交。

情况2:当有一个参与者反馈 no,回滚事务

a) 协调者向所有参与者发出回滚请求(即 rollback 请求)。

b) 参与者使用阶段 1 中的 undo 信息执行回滚操作,并释放整个事务期间占用的资源。

c) 各参与者向协调者反馈 ack 完成的消息。

d) 协调者收到所有参与者反馈的 ack 消息后,即完成事务。

问题

1) 性能问题:所有参与者在事务提交阶段处于同步阻塞状态,占用系统资源,容易导致性能瓶颈。

2) 可靠性问题:如果协调者存在单点故障问题,或出现故障,提供者将一直处于锁定状态。

3) 数据一致性问题:在阶段 2 中,如果出现协调者和参与者都挂了的情况,有可能导致数据不一致。

优点:尽量保证了数据的强一致,适合对数据强一致要求很高的关键领域。(其实也不能100%保证强一致)。

缺点:实现复杂,牺牲了可用性,对性能影响较大,不适合高并发高性能场景。

02 三阶段提交(3PC)

三阶段提交是在二阶段提交上的改进版本,3PC最关键要解决的就是协调者和参与者同时挂掉的问题,所以3PC把2PC的准备阶段再次一分为二,这样三阶段提交。处理流程如下:

ca6a3208b80fe5efe599df79d7ce55a3.png

阶段一

a) 协调者向所有参与者发出包含事务内容的 canCommit 请求,询问是否可以提交事务,并等待所有参与者答复。

b) 参与者收到 canCommit 请求后,如果认为可以执行事务操作,则反馈 yes 并进入预备状态,否则反馈 no。

阶段二

协调者根据参与者响应情况,有以下两种可能。

情况1:所有参与者均反馈 yes,协调者预执行事务

a) 协调者向所有参与者发出 preCommit 请求,进入准备阶段。

b) 参与者收到 preCommit 请求后,执行事务操作,将 undo 和 redo 信息记入事务日志中(但不提交事务)。

c) 各参与者向协调者反馈 ack 响应或 no 响应,并等待最终指令。

情况2:只要有一个参与者反馈 no,或者等待超时后协调者尚无法收到所有提供者的反馈,即中断事务

a) 协调者向所有参与者发出 abort 请求。

b) 无论收到协调者发出的 abort 请求,或者在等待协调者请求过程中出现超时,参与者均会中断事务。

阶段三

该阶段进行真正的事务提交,也可以分为以下两种情况。

情况 1:所有参与者均反馈 ack 响应,执行真正的事务提交

a) 如果协调者处于工作状态,则向所有参与者发出 do Commit 请求。

b) 参与者收到 do Commit 请求后,会正式执行事务提交,并释放整个事务期间占用的资源。

c) 各参与者向协调者反馈 ack 完成的消息。

d) 协调者收到所有参与者反馈的 ack 消息后,即完成事务提交。

情况2:只要有一个参与者反馈 no,或者等待超时后协调组尚无法收到所有提供者的反馈,即回滚事务。

a) 如果协调者处于工作状态,向所有参与者发出 rollback 请求。

b) 参与者使用阶段 1 中的 undo 信息执行回滚操作,并释放整个事务期间占用的资源。

c) 各参与者向协调组反馈 ack 完成的消息。

d) 协调组收到所有参与者反馈的 ack 消息后,即完成事务回滚。

优点:相比二阶段提交,三阶段提交降低了阻塞范围,在等待超时后协调者或参与者会中断事务。避免了协调者单点问题。阶段 3 中协调者出现问题时,参与者会继续提交事务。

缺点:数据不一致问题依然存在,当在参与者收到 preCommit 请求后等待 do commite 指令时,此时如果协调者请求中断事务,而协调者无法与参与者正常通信,会导致参与者继续提交事务,造成数据不一致。

03 补偿事务(TCC)

TCC 是服务化的二阶段编程模型,采用的补偿机制:

f53889d34e9637f37ff6b5dc9d4d9fbe.png

条件:

需要实现确认和补偿逻辑

需要支持幂等

处理流程:

a) Try 阶段主要是对业务系统做检测及资源预留。

这个阶段主要完成:

完成所有业务检查( 一致性 ) 。

预留必须业务资源( 准隔离性 ) 。

Try 尝试执行业务。

b) Confirm 阶段主要是对业务系统做确认提交。

Try阶段执行成功并开始执行 Confirm阶段时,默认 Confirm阶段是不会出错的。即:只要Try成功,Confirm一定成功。

c) Cancel 阶段主要是在业务执行错误,需要回滚的状态下执行的业务取消,预留资源释放。

优点:

性能提升:具体业务来实现控制资源锁的粒度变小,不会锁定整个资源。

数据最终一致性:基于 Confirm 和 Cancel 的幂等性,保证事务最终完成确认或者取消,保证数据的一致性。

可靠性:解决了 XA 协议的协调者单点故障问题,由主业务方发起并控制整个业务活动,业务活动管理器也变成多点,引入集群。

缺点:TCC 的 Try、Confirm 和 Cancel 操作功能要按具体业务来实现,业务耦合度较高,提高了开发成本。

04 本地消息表(消息队列)

其核心思想是将分布式事务拆分成本地事务进行处理。

方案通过在消费者额外新建事务消息表,消费者处理业务和记录事务消息在本地事务中完成,轮询事务消息表的数据发送事务消息,提供者基于消息中间件消费事务消息表中的事务。

5503864de3f25716d470800d5f6f56cc.png

条件:

服务消费者需要创建一张消息表,用来记录消息状态。

服务消费者和提供者需要支持幂等。

需要补偿逻辑。

每个节点上起定时线程,检查未处理完成或发出失败的消息,重新发出消息,即重试机制和幂等性机制。

处理流程:

1. 服务消费者把业务数据和消息一同提交,发起事务。

2. 消息经过MQ发送到服务提供方,服务消费者等待处理结果。

3. 服务提供方接收消息,完成业务逻辑并通知消费者已处理的消息。

容错处理情况如下:

当步骤1处理出错,事务回滚,相当于什么都没有发生。

当步骤2、3处理出错,由于消息保存在消费者表中,可以重新发送到MQ进行重试。

如果步骤3处理出错,且是业务上的失败,服务提供者发送消息通知消费者事务失败,且此时变为消费者发起回滚事务进行回滚逻辑。

优点:从应用设计开发的角度实现了消息数据的可靠性,消息数据的可靠性不依赖于消息中间件,弱化了对 MQ 中间件特性的依赖。

缺点:与具体的业务场景绑定,耦合性强,不可公用。消息数据与业务数据同库,占用业务系统资源。业务系统在使用关系型数据库的情况下,消息服务性能会受到关系型数据库并发性能的局限。

MQ事务消息(最终一致性)

支持事务消息的MQ,其支持事务消息的方式采用类似于二阶段提交。

基于 MQ 的分布式事务方案其实是对本地消息表的封装,将本地消息表基于 MQ 内部,其他方面的协议基本与本地消息表一致。

1da6767c9c5ed71630d91c88005cd9cc.png

条件:

a) 需要补偿逻辑

b) 业务处理逻辑需要幂等

处理流程:

c) 消费者向MQ发送half消息。

d) MQ Server将消息持久化后,向发送方ack确认消息发送成功。

e) 消费者开始执行事务逻辑。

f) 消费者根据本地事务执行结果向MQ Server提交二次确认或者回滚。

g) MQ Server收到commit状态则将half消息标记可投递状态。

h) 服务提供者收到该消息,执行本地业务逻辑。返回处理结果。

优点:

消息数据独立存储,降低业务系统与消息系统之间的耦合。

吞吐量优于本地消息表方案。

缺点:

一次消息发送需要两次网络请求(half消息 + commit/rollback)。

需要实现消息回查接口。

05 Sagas事务模型(最终一致性)

Saga模式是一种分布式异步事务,一种最终一致性事务,是一种柔性事务,有两种不同的方式来实现saga事务,最流行的两种方式是:

一、 事件/编排Choreography:没有中央协调器(没有单点风险)时,每个服务产生并聆听其他服务的事件,并决定是否应采取行动。

该实现第一个服务执行一个事务,然后发布一个事件。该事件被一个或多个服务进行监听,这些服务再执行本地事务并发布(或不发布)新的事件,当最后一个服务执行本地事务并且不发布任何事件时,意味着分布式事务结束,或者它发布的事件没有被任何Saga参与者听到都意味着事务结束。

07b7a914cfccba2d4ef3e2fc99c69765.png

处理流程:

订单服务保存新订单,将状态设置为pengding挂起状态,并发布名为ORDER_CREATED_EVENT的事件。

支付服务监听ORDER_CREATED_EVENT,并公布事件BILLED_ORDER_EVENT。

库存服务监听BILLED_ORDER_EVENT,更新库存,并发布ORDER_PREPARED_EVENT。

货运服务监听ORDER_PREPARED_EVENT,然后交付产品。最后,它发布ORDER_DELIVERED_EVENT。

最后,订单服务侦听ORDER_DELIVERED_EVENT并设置订单的状态为concluded完成。

假设库存服务在事务过程中失败了。进行回滚:

库存服务产生PRODUCT_OUT_OF_STOCK_EVENT

订购服务和支付服务会监听到上面库存服务的这一事件:

①支付服务会退款给客户。

②订单服务将订单状态设置为失败。

优点:事件/编排是实现Saga模式的自然方式; 它很简单,容易理解,不需要太多的努力来构建,所有参与者都是松散耦合的,因为他们彼此之间没有直接的耦合。如果您的事务涉及2至4个步骤,则可能是非常合适的。

二、 命令/协调orchestrator:中央协调器负责集中处理事件的决策和业务逻辑排序。

saga协调器orchestrator以命令/回复的方式与每项服务进行通信,告诉他们应该执行哪些操作。

c60521302583d44a5908f7a1c2f58b82.png

订单服务保存pending状态,并要求订单Saga协调器(简称OSO)开始启动订单事务。

OSO向收款服务发送执行收款命令,收款服务回复Payment Executed消息。

OSO向库存服务发送准备订单命令,库存服务将回复OrderPrepared消息。

OSO向货运服务发送订单发货命令,货运服务将回复Order Delivered消息。

OSO订单Saga协调器必须事先知道执行“创建订单”事务所需的流程(通过读取BPM业务流程XML配置获得)。如果有任何失败,它还负责通过向每个参与者发送命令来撤销之前的操作来协调分布式的回滚。当你有一个中央协调器协调一切时,回滚要容易得多,因为协调器默认是执行正向流程,回滚时只要执行反向流程即可。

优点:

避免服务之间的循环依赖关系,因为saga协调器会调用saga参与者,但参与者不会调用协调器。

集中分布式事务的编排。

只需要执行命令/回复(其实回复消息也是一种事件消息),降低参与者的复杂性。

在添加新步骤时,事务复杂性保持线性,回滚更容易管理。

如果在第一笔交易还没有执行完,想改变有第二笔事务的目标对象,则可以轻松地将其暂停在协调器上,直到第一笔交易结束。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_31063029/article/details/113206030

智能推荐

ext4 介绍_1.[多选题以下关于ext4的描述,哪些是正确的?a相对于ext3来说,ext4支持更大的-程序员宅基地

文章浏览阅读1.7k次。ext4(第四扩展文件系统)文件系统是Linux系统下的日志文件系统,是ext3文件系统的后继版本。Ext4 可以提供更佳的性能和可靠性,还有更为丰富的功能:1. 与 Ext3 兼容。 执行若干条命令,就能从 Ext3 在线迁移到 Ext4,而无须重新格式化磁盘或重新安装系统。原有 Ext3 数据结构照样保留,Ext4 作用于新数据,当然,整个文件系统因此也就获得了 Ext4 所支_1.[多选题以下关于ext4的描述,哪些是正确的?a相对于ext3来说,ext4支持更大的

程序员的苦中取乐-程序员宅基地

文章浏览阅读90次。

centos7 Golang vim IDE_cscope支持golang-程序员宅基地

文章浏览阅读3.3k次。接触Golang之后使用过许多的编辑器比如lite,sublime3,goland,lite更适合在windows环境使用,对于非destop版本的Linux就不太适用了,在linux下还是直接上神器vim了,为了快速开发自然要安装许多便捷的插件首先vim的插件安装有两种形式,一直直接自己安装到~/.vim/plugin目录下 另外一种是使用插件管理器Vundle(还有其他的插件管理器)开始之前准..._cscope支持golang

VINS-Mono初始化中的坐标转换_vins extrinsicrotation-程序员宅基地

文章浏览阅读533次。0.引言//输出是优化过后的相机位姿//这里得到的是第l帧坐标系到各帧的变换矩阵,应将其转变为各帧在第l帧坐标系上的位姿for (int i = 0; i < frame_num; i++){ q[i].w() = c_rotation[i][0]; q[i].x() = c_rotation[i][1]; q[i].y() = c_rotation[i][2]; q[i].z() = c_rotation[i][3]; q[i] = q[i].inverse();}fo_vins extrinsicrotation

小米air2 pro ota 升级固件_小米air2pro固件包-程序员宅基地

文章浏览阅读4.7k次。本地OTA升级:(从别人文档复制过来的)百度云链接: 提取码: qqyt一:准备安卓手机一台(包括小米手机)二:安装对应小爱同学(安卓版 2.9.21版本)三:将“小米蓝牙耳机Air2Pro固件(3.0.11.0).zip”解压,将其中的EM028。。。。。。.bin文件存入手机的某个目录本地OTA升级具体操作步骤如下(小米手机):在进行以下步骤前,首先到设置-应用设置-应用管理把系统原来的小爱同学卸载更新(没有卸载更新的清楚全部数据),然后安装升级文件中的小爱同学APP(该apk._小米air2pro固件包

如何预防光纤光缆布线中的雷击伤害_光纤收发器容易被雷击-程序员宅基地

文章浏览阅读297次。众所周知,光纤是具有不导电性的,可以免受冲击电流,光缆也具有良好的防护性能,光缆中的金属构件对地绝缘值较高,雷电流不易进入光缆,但因为光缆具有加强芯,特别是直埋光缆具有铠装层,因而在光缆线路遭雷击时,也能发生光缆被烧毁或损坏的情况。那么,我们该如何预防光纤光缆布线中的雷击伤害呢?接下来我们就跟随飞畅科技的小编一起来看看吧!    随着网络的发展,光纤作为综合布线系统中用来传输数据的一种介质,因为去具有传输速率大,距离远等优点,越来越受人们的使用。众所周知,光纤是具有不导电性的,可以免受冲击电流,光缆也具_光纤收发器容易被雷击

随便推点

mysql Errcode: 24 - Too many open files_windows mysql备份数据库提示errno:24 - too many open files-程序员宅基地

文章浏览阅读5.2k次。在对库的每个表进行按天分区过程中出现以下问题Out of resources when opening file './CountersBackup_changzhou/DC_E_ERBS_EUTRANCELLTDD_V_HOUR_ERBS#P#p195.MYD' (Errcode: 24 - Too many open files)原因:生成的文件超出了mysql中的_windows mysql备份数据库提示errno:24 - too many open files

GitLab使用详解_gitlab owner maintainer-程序员宅基地

文章浏览阅读1.4k次。使用GitLab创建项目_gitlab owner maintainer

(10.2.3.4)静电的设计教室:APP设计利器Sketch教程(04)-钢笔与路径(原创)_sketch钢笔工具如何断开-程序员宅基地

文章浏览阅读1.1k次。sketch是一款矢量软件,提起矢量软件,那么大家一定会想到各种路径,想到路径,就有节点,想到节点,就有贝塞尔曲线,然后一定会有的东西就是钢笔。扯到钢笔,对于很多人来说,这一定是个不太愉快的回忆,钢笔是绘图软件中很难掌握的工具之一。相信经过前面三次的教程,再加上大家自己的努力实践,sketch对于每个人都已经是轻车熟路了。剩下的,就是在不断的实践中总结适合自己的技巧,发_sketch钢笔工具如何断开

前端架构设计第十三课 同构渲染和CI/CD_perf-patronus-程序员宅基地

文章浏览阅读331次。27 同构渲染架构:实现一个 SSR 应用从这一讲开始,我们正式进入 Node.js 主题学习。作为 Node.js 技术的重要应用场景,同构渲染 SSR 应用尤其重要。不管是服务端渲染还是服务端渲染衍生出的同构应用,现在来看已经并不新鲜了,实现起来也并不困难。可是有的开发者认为:同构应用不就是调用一个renderToString(React 中)类似的 API 吗?讲道理,确实如此,但同构应用也不只是这么简单。就拿面试来说,同构应用的考察点不是“纸上谈兵”的理论,而是实际实施时的细节。这一讲我们就来_perf-patronus

通关GO语言21 网络编程:Go 语言如何玩转 RESTful API 服务?_go访问restful接口-程序员宅基地

文章浏览阅读435次。RESTful API 是一套规范,它可以规范我们如何对服务器上的资源进行操作。在了解 RESTful API 之前,我先为你介绍下 HTTP Method,因为 RESTful API 和它是密不可分的。说起 HTTP Method,最常见的就是POST和GET,其实最早在 HTTP 0.9 版本中,只有一个GET方法,该方法是一个幂等方法,用于获取服务器上的资源,也就是我们在浏览器中直接输入网址回车请求的方法。在 HTTP 1.0 版本中又增加了HEAD和POST。_go访问restful接口

东华oj-进阶题第15题_“明明,你会用1到9这九个数字组成一个三角形吗?”明明的爸爸问明明。明明被问的很-程序员宅基地

文章浏览阅读451次。15 三角形作者: ZhuKai时间限制: 10S章节: 循环问题描述 :“明明,你会用1到9这九个数字组成一个三角形吗?”明明的爸爸问明明。明明被问的很莫名其妙,不明白他爸爸在说什么,于是就问道:“用1到9组成三角形???”“是的,我的要求很简单,给你2个数,一个数作为这个三角形的开始,另一个数决定这个三角形的大小。例如我给你5和6这两个数,你就要组成如下的一个三角形:5 6 7 8 ..._“明明,你会用1到9这九个数字组成一个三角形吗?”明明的爸爸问明明。明明被问的很

推荐文章

热门文章

相关标签