分布式事务五种方案及两个流行框架

分布式事务五种方案及两个流行框架CAP理论CAP定理(CAPtheorem),又被称作布鲁尔定理(Brewer'stheorem),是分布式系统中的一个基本定理。它指出任何分布式系统(DistributedSystem)中,最多具有一致性、可用性、分区容错这三个特性中的两个。也就是说,三个特性无法兼顾,必须有所

大家好,欢迎来到IT知识分享网。

CAP理论

CAP定理(CAP theorem),又被称作布鲁尔定理(Brewer’s theorem),是分布式系统中的一个基本定理。
它指出任何分布式系统(Distributed System)中,最多具有一致性、可用性、分区容错这三个特性中的两个。
也就是说,三个特性无法兼顾,必须有所取舍。

一致性(C)

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

可用性(A)

保证每个请求不管成功或者失败都有响应。

分区容错性(P)

系统中任意信息的丢失或失败不会影响系统的继续运作。

BASE理论

CAP 不可能同时满足,而分区容错是对于分布式系统而言又是必须的。
Base 理论是对 CAP 中一致性和可用性权衡的结果,是基于 CAP 定理逐步演化而来的。其核心思想是:既是无法做到强一致性(Strong consistency),但每个应用都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性(Eventual consistency)

基本可用

什么是基本可用呢?假设系统,出现了不可预知的故障,但还是能用,相比较正常的系统而言:

响应时间上的损失:正常情况下的一个请求 0.5 秒即返回给用户结果,而基本可用的请求可以在 1 秒作用返回结果。

功能上的损失:在一个电商网站上,正常情况下,用户可以顺利完成每一笔订单,但是到了大促期间,为了保护购物系统的稳定性,可以关闭一些不重要的功能或者部分消费者可能会被引导到一个降级页面。

软状态

什么是软状态呢?相对于原子性而言,要求多个节点的数据副本都是一致的,这是一种 “硬状态”。

软状态指的是:允许系统中的数据存在中间状态,并认为该状态不影响系统的整体可用性,即允许系统在多个不同节点的数据副本存在数据延时。

最终一致性

系统能够保证在没有其他新的更新操作的情况下,数据最终一定能够达到一致的状态,因此所有客户端对系统的数据访问最终都能够获取到最新的值。
   上面说软状态,然后不可能一直是软状态,必须有个时间期限。在期限过后,应当保证所有副本保持数据一致性。从而达到数据的最终一致性。这个时间期限取决于网络延时,系统负载,数据复制方案设计等等因素。
   最终一致性分为 5 种:
   1. 因果一致性(Causal consistency)如果节点 A 在更新完某个数据后通知了节点 B,那么节点 B 之后对该数据的访问和修改都是基于 A 更新后的值。于此同时,和节点 A 无因果关系的节点 C 的数据访问则没有这样的限制。
   2. 读己之所写(Read your writes)节点 A 更新一个数据后,它自身总是能访问到自身更新过的最新值,而不会看到旧值。其实也算一种因果一致性。
   3. 会话一致性(Session consistency)会话一致性将对系统数据的访问过程框定在了一个会话当中:系统能保证在同一个有效的会话中实现 “读己之所写” 的一致性,也就是说,执行更新操作之后,客户端能够在同一个会话中始终读取到该数据项的最新值。
   4. 单调读一致性(Monotonic read consistency)如果一个节点从系统中读取出一个数据项的某个值后,那么系统对于该节点后续的任何数据访问都不应该返回更旧的值。
   5. 单调写一致性(Monotonic write consistency)指一个系统要能够保证来自同一个节点的写操作被顺序的执行。

分布式事务5种解决方案

2PC

2PC(Two-phase commit protocol),中文叫二阶段提交。二阶段提交是一种强一致性设计,2PC 引入一个事务协调者的角色来协调管理各参与者(也可称之为各本地资源)的提交和回滚,二阶段分别指的是准备(投票)和提交两个阶段。

分布式事务五种方案及两个流行框架

当第一阶段参与者都准备成功了,协调者就会发送提交事务的请求。反之如果有一个参与者准备失败则发送回滚事物的请求。
分布式事务五种方案及两个流行框架

2PC是一个同步阻塞协议,只有第一阶段所有参与者都响应了,才会执行第二阶段。在第一阶段中,协调者有超时机制,当因为网络问题或者参与者执行超时和参与者不在线的情况,协调者会向所有参与者发送回滚命令。但是第二阶段是没有超时的,只能不断地重试提交或回滚

2PC 是一种尽量保证强一致性的分布式事务,因此它是同步阻塞的,而同步阻塞就导致长久的资源锁定问题,总体而言效率低,并且存在单点故障问题,在极端条件下存在数据不一致的风险

3PC

3PC相比于2PC多了一个预提交阶段的步骤,准备阶段预提交阶段提交阶段

预提交是把2PC的提交阶段拆成两次去做,相应的性能会差一点,而且绝大部分情况下资源应该都是可用的,等同于明知故问。2PC有的问题3PC也有存在,所以3PC应用的很少,不展开讨论了。

TCC

TCC 指的是Try - Confirm - Cancel

  • Try 指的是预留,即资源的预留和锁定。
  • Confirm 指的是确认操作,这一步其实就是真正的执行了。
  • Cancel 指的是撤销操作,可以理解为把预留阶段的动作撤销了。

一个分布式的全局事务,整体是 两阶段提交 的模型。TCC也是一样的,单相对应2PC和3PC来说,把事务管理从数据库层面,提取到了业务层面

TCC第一阶段:try行为,试探性操作

TCC第二阶段:confirm或cancel操作,第一阶段成功就会调用confirm,失败就会cancel操作

TCC还需要一个全局事务管理者的角色,用来记录TCC全局事务状态并提交或回滚事务

分布式事务五种方案及两个流行框架

由于TCC每一步操作都需要业务上的定义,对于一个操作都要写三个方法对应try、confirm、cancel。

因此TCC对业务的侵入性比较大和业务是紧耦合的关系。

但是因为TCC是业务上的实现,所以他的适用范围更广,可以跨数据库、跨不同的业务系统来实现事务。

事务控制代码都需要开发去写,所以需要做好异常控制:

  1. 空回滚允许

    现象是try没有被执行,就调用了cancel。

    出现原因:

    • Try超时(丢包)
    • 分布式事务回滚,触发cancel
    • 未收到try,收到cancel

    解决办法:让cancel能够识别出这是一个空回滚,可以记录事务执行状态,cancel中判断try是否执行了。

  2. 幂等控制

    事务协调着会重复调用,try、confirm、cancel三个方法都需要实现幂等控制

    解决办法:记录事务执行状态,如果执行过了,就不再执行。

  3. 防悬挂控制

    Cancel比Try先执行

    出现原因:

    • Try超时(拥堵)
    • 分布式事务回滚,出发cancel
    • 拥堵的Try到达

    解决办法:记录事务执行状态,try执行时判断cancel是否执行了。

  4. 并发控制

优点

  1. 可靠性高
  2. 实时性高

缺点

  1. 开发复杂度高
  2. 因为事务状态管理,需要多次DB操作,性能有一定损耗

本地消息表

此方案的核心是将需要分布式处理的任务通过消息日志的方式来异步执行。消息日志可以存储到本地文本、数据库或消息队列,再通过业务规则自动或人工发起重试。人工重试更多的是应用于支付场景,通过对账系统对事后问题的处理。

分布式事务五种方案及两个流行框架

举例

分布式事务五种方案及两个流行框架

总的来说就是消息的可靠性投递方案,加上本地事务,并通过消息重试来处理异常情况。

异常也分为两种情况,一种是业务异常,比如转账用户余额不足导致业务走不下去这种异常其实应该通知事务发起方进行回滚,但已经做了消息异步处理,怎么回滚?可以通过TCC的try预检进行资源预留;另一种是外部异常,系统挂了,网络波动等情况,通过本地消息表进行重试发送消息。

本地消息表方案也是一种最终一致性方案

优点:

建设成本比较低,例:数据库+mq

缺点

本地消息表和业务耦合,难于做成通用性,不可独立伸缩。

需要设计DB消息表,同时还需要一个后台任务,不断扫描本地消息。

本地消息表是基于数据库来做的,而数据库是要读写磁盘IO的,因此在高并发下是有性能瓶颈的

消息事务

如果说本地消息表方案是消息+本地表实现的消息的可靠性和事务的,那消息事务方案就是通过消息中间件本身的事务体系,解决了本地事务表对业务的耦合和定时任务扫描的痛点。

  • 事务消息:消息队列RocketMQ版提供类似XA或Open XA的分布式事务功能,通过消息队列RocketMQ版事务消息能达到分布式事务的最终一致。
  • 半事务消息:暂不能投递的消息,发送方已经成功地将消息发送到了消息队列RocketMQ版服务端,但是服务端未收到生产者对该消息的二次确认,此时该消息被标记成“暂不能投递”状态,处于该种状态下的消息即半事务消息。
  • 消息回查:由于网络闪断、生产者应用重启等原因,导致某条事务消息的二次确认丢失,消息队列RocketMQ版服务端通过扫描发现某条消息长期处于“半事务消息”时,需要主动向消息生产者询问该消息的最终状态(Commit或是Rollback),该询问过程即消息回查。

分布式事务五种方案及两个流行框架

交互流程

分布式事务五种方案及两个流行框架

事务消息发送步骤如下:

  1. 发送方将半事务消息发送至消息队列RocketMQ。
  2. 消息队列RocketMQ将消息持久化成功之后,向发送方返回Ack确认消息已经发送成功,此时消息为半事务消息。
  3. 发送方开始执行本地事务逻辑。
  4. 发送方根据本地事务执行结果向服务端提交二次确认(Commit或是Rollback),服务端收到Commit状态则将半事务消息标记为可投递,订阅方最终将收到该消息;服务端收到Rollback状态则删除半事务消息,订阅方将不会接受该消息。

事务消息回查步骤如下:

  1. 在断网或者是应用重启的特殊情况下,上述步骤4提交的二次确认最终未到达服务端,经过固定时间后服务端将对该消息发起消息回查。
  2. 发送方收到消息回查后,需要检查对应消息的本地事务执行的最终结果。
  3. 发送方根据检查得到的本地事务的最终状态再次提交二次确认,服务端仍按照步骤4对半事务消息进行操作。

优势

业务之间的解耦

缺点

需要定义事务反查接口

几种常见的分布式事务总结

2PC3PC是一种强一致性事务,不过还是有数据不一致,阻塞等风险,且依赖于关系型数据库。

TCC是一种补偿性事务思想,在业务层面实现,适用的范围更广,因此对业务侵入性较大,每一个操作都需要实现对应的三个方法。

本地消息事务消息都是最终一致性事务

LCN-TXC事务模式

一、原理介绍:

TXC模式命名来源于淘宝,实现原理是在执行SQL之前,先查询SQL的影响数据,然后保存执行的SQL快走信息和创建锁。当需要回滚的时候就采用这些记录数据回滚数据库,目前锁实现依赖redis分布式锁控制。类似于Seata的AT

二、模式特点:

  • 该模式同样对代码的嵌入性低。
  • 该模式仅限于对支持SQL方式的模块支持。
  • 该模式由于每次执行SQL之前需要先查询影响数据,因此相比LCN模式消耗资源与时间要多。
  • 该模式不会占用数据库的连接资源。

Seata分布式事务框架

Seata-AT

Seata 的 AT 模式建立在关系型数据库的本地事务特性的基础之上,通过数据源代理类拦截并解析数据库执行的 SQL,记录自定义的回滚日志,如需回滚,则重放这些自定义的回滚日志即可。AT 模式虽然是根据 XA 事务模型(2PC)演进而来的,但是 AT 打破了 XA 协议的阻塞性制约,在一致性和性能上取得了平衡。AT模式也是Seata主推的事务模式。

AT 模式是基于 XA 事务模型演进而来的,它的整体机制也是一个改进版本的两阶段提交协议。AT 模式的两个基本阶段是:

1)第一阶段:首先获取本地锁,执行本地事务,业务数据操作和记录回滚日志在同一个本地事务中提交,最后释放本地锁;

2)第二阶段:如需全局提交,异步删除回滚日志即可,这个过程很快就能完成。如需要回滚,则通过第一阶段的回滚日志进行反向补偿。

AT和XA 事务模型(2PC)不同的地方:

  1. AT在第一阶段业务处理完就提交事务了;XA是在第二阶段做完才提交事务,释放资源。
  2. AT模式第二阶段提交事务只需要清楚undo_log表数据就行;XA需通知各个事务参与者进行事务提交。
  3. AT模式第二阶段回滚事务比较麻烦,需要根据undo_log表的镜像数据生成回滚sql进行回滚;XA由于事务未提交则通知事务参与者进行回滚就可以了。
  4. AT模式第一阶段就提交了事务,但是整体分布式事务还没有提交。其他事务操作是可以看到提交之后的数据且可以操作,这时AT模式引入了全局锁的概念,就是说两个事务同时操作同一条数据时,只有一个事务会持有全局锁进行本地事务提交,拿不到全局锁的事务无法提交本地事务。XA无需考虑这点,因为已经通过本地事务进行隔离了。
  5. 在数据库本地事务隔离级别 读已提交(Read Committed) 或以上的基础上,Seata(AT 模式)的默认全局隔离级别读未提交(Read Uncommitted),这个可以通过SELECT FOR UPDATE 语句进行代理读已提交。

Seata-TCC

回顾总览中的描述:一个分布式的全局事务,整体是 两阶段提交 的模型。全局事务是由若干分支事务组成的,分支事务要满足 两阶段提交 的模型要求,即需要每个分支事务都具备自己的:

  • 一阶段 prepare 行为
  • 二阶段 commit 或 rollback 行为

根据两阶段行为模式的不同,我们将分支事务划分为 Automatic (Branch) Transaction Mode 和 Manual (Branch) Transaction Mode.

AT 模式(参考链接 TBD)基于 支持本地 ACID 事务 的 关系型数据库

  • 一阶段 prepare 行为:在本地事务中,一并提交业务数据更新和相应回滚日志记录。
  • 二阶段 commit 行为:马上成功结束,自动 异步批量清理回滚日志。
  • 二阶段 rollback 行为:通过回滚日志,自动 生成补偿操作,完成数据回滚。

相应的,TCC 模式,不依赖于底层数据资源的事务支持:

  • 一阶段 prepare 行为:调用 自定义 的 prepare 逻辑。
  • 二阶段 commit 行为:调用 自定义 的 commit 逻辑。
  • 二阶段 rollback 行为:调用 自定义 的 rollback 逻辑。

所谓 TCC 模式,是指支持把 自定义 的分支事务纳入到全局事务的管理中。

Seata-SAGA

Saga模式是SEATA提供的长事务解决方案,在Saga模式中,业务流程中每个参与者都提交本地事务,当出现某一个参与者失败则补偿前面已经成功的参与者,一阶段正向服务和二阶段补偿服务都由业务开发实现

分布式事务五种方案及两个流行框架

适用场景:

  • 业务流程长、业务流程多
  • 参与者包含其它公司或遗留系统服务,无法提供 TCC 模式要求的三个接口

优势:

  • 一阶段提交本地事务,无锁,高性能
  • 事件驱动架构,参与者可异步执行,高吞吐
  • 补偿服务易于实现

缺点:

  • 不保证隔离性

基于状态机引擎的 Saga 实现:

目前SEATA提供的Saga模式是基于状态机引擎来实现的,机制是:

  1. 通过状态图来定义服务调用的流程并生成 json 状态语言定义文件
  2. 状态图中一个节点可以是调用一个服务,节点可以配置它的补偿节点
  3. 状态图 json 由状态机引擎驱动执行,当出现异常时状态引擎反向执行已成功节点对应的补偿节点将事务回滚

注意: 异常发生时是否进行补偿也可由用户自定义决定

  1. 可以实现服务编排需求,支持单项选择、并发、子流程、参数转换、参数映射、服务执行状态判断、异常捕获等功能

事务框架总结

LCN

官网:https://www.codingapi.com/

GitHub:https://github.com/codingapi/tx-lcn stars: 4k

5.0以后由于框架兼容了LCN、TCC、TXC三种事务模式

TX-LCN定位于一款事务协调性框架,框架其本身并不操作事务,而是基于对事务的协调从而达到事务一致性的效果。

SEATA

官网:https://seata.io/zh-cn/

GitHub:https://github.com/seata/seata stars: 20.6k

Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/30193.html

(0)

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

关注微信