基于Saga的分布式事务调度落地

2022年05月15日 阅读数:9
这篇文章主要向大家介绍基于Saga的分布式事务调度落地,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

图片

全文4104字,预计阅读时间12分钟。前端

1、背景

随着微服务架构的兴起,愈来愈多的公司都对自身的业务架构进行了微服务化。在微服务架构中,随着服务的逐渐拆分,数据库的私有化已成为业界不成文的规定。所以伴随着微服务拆分所带来的数据一致性的问题也愈发严重,如何解决该问题成为微服务架构落地过程当中一个很是重要的问题。由此咱们引出分布式事务这一律念,用来解决上述背景带来的问题。在介绍分布式事务以前先让咱们回顾一下什么是事务。数据库

2、事务

事务是数据库操做的最小工做单元,是做为单个逻辑工做单元执行的一系列操做;这些操做做为一个总体一块儿向系统提交,要么都执行、要么都不执行;事务具备ACID四大属性。小程序

A(Atomic):原子性,构成事务的全部操做,要么都执行完成,要么所有不执行,不可能出现部分红功部分失败的状况。前端工程化

C(Consistency):一致性,在事务执行先后,数据库的一致性约束没有被破坏。好比:数据库约束帐户余额必须大于0,因此设置为无符号数,在此约束下,A只有100元,但要转出200元,此时数据库会保持对约束的一致性,触发执行回滚。网络

I(Isolation):隔离性,数据库中的事务通常都是并发的,隔离性是指并发的两个事务的执行互不干扰,一个事务不能看到其余事务的运行过程的中间状态。经过配置事务隔离级别能够比避免脏读、重复读问题。架构

D(Durability):持久性,事务完成以后,该事务对数据的更改会持久到数据库,且不会被回滚。并发

了解完了事务的基本概念,接着让咱们看看什么是分布式事务。异步

3、分布式事务

在分布式系统中,一个应用系统拆分为独立部署的多个服务,所以须要服务与服务之间远程协做才能完成事务操做,这种分布式系统环境下由不一样的服务之间经过网络远程协做完成的事务称为分布式事务。分布式

从架构角度出发,分布式事务基本涉及到两大类。微服务

第一类:一个事务请求只涉及单体服务,可是会操做多张数据库表,多个数据库表操做完成才表示最终完成。

第二类:一个事务涉及多个服务,同时每一个服务可能链接着一个或者多个数据库,须要协同多个独立的服务访问多个数据存储最终才能完成。

咱们常见的分布式事务来保证数据的一致性的方法分为两类:强一致性、最终一致性。

采用强一致性的分布式事务的方案:一般采用两段式提交协议2PC、三段式提交协议3PC。在微服务架构中,该种方式不太适合,缘由以下:

因为微服务间没法直接进行数据访问,微服务间互相调用一般经过RPC或Http API进行,因此已经没法使用TM统一管理微服务的RM

不一样的微服务使用的数据源类型可能彻底不一样,若是微服务使用了NoSQL之类不原生支持事务的数据库,业务的事务很难实现

即便微服务使用的数据源都支持事务,那么若是使用一个大事务将许多微服务的事务管理起来,这个大事务维持的时间,将比本地事务长几个数量级。如此长时间的事务及跨服务的事务,将为产生不少锁及数据不可用,严重影响系统性能

所以咱们通常采用最终一致性来保证分布式系统的一致性。

常见的最终一致性的分布式事务解决方案有:事件通知模式(本地异步事件服务模式、外部事件服务模式、MQ事务消息模式、最大努力通知模式)、事务补偿模式(Saga、TCC)。咱们经过调研上述解决方案总结出了如下特性:

图片

下面咱们经过一个业务场景来了解一下什么是分布式事务,而且咱们创新行业是用什么方案来解决数据一致性问题的。

4、业务场景

假设有一个积分签到系统,里面有一个签到兑换积分从而兑换物品的功能场景。

图片

咱们要作的事情以下:

  • 用户签到成功、增长用户积分

  • 用户建立兑换物品订单,订单状态为已支付

  • 扣除用户积分

  • 扣减物品库存

  • 建立物流出库单

针对以上的业务场景,咱们应该如何实现分布式事务来知足业务须要。下面主要讲事务补偿模式来实现分布式事务。

4.1 TCC 模式

TCC是将总体业务逻辑的每个事务提交分红了Try,Confirm,Cancel三个操做。

  • Try:完成业务的准备工做

  • Confirm:完成业务的提交工做

  • Cancel:完成业务的回滚工做

针对上述业务场景,按照业务背景要作的事情,实现一个TCC的分布式事务。

若是要实现一个TCC的分布式事务,首先要作的是了解业务的主流程以及各个接口提供的业务含义,不直接完成这个业务操做,而是完成一个Try(预处理)操做。

例如:给用户添加积分,咱们不直接添加积分,先预处理添加积分。扣物品库存咱们也不直接扣库存,先冻结将扣掉的库存。具体以下图

图片

若是Try的逻辑都成功,TCC开始执行业务的Confirm操做,完成整个事务流程。添加用户积分扣库存等操做。若是Try的逻辑部分红功,有部分有问题,那么开始执行Cancel操做,撤销以前执行的全部操做。

整体对于TCC模式来讲,要作一个分布式事务,业务中的一个接口须要完成3个逻辑的改造,Try-Confirm-Cancel。

  • 服务调用链路依次执行Try逻辑

  • 若是都正常的话,执行Confirm逻辑,完成整个业务流程

  • 若是部分服务的Try逻辑有问题,会执行Cancel逻辑,撤销以前执行的全部操做

TCC模式对于业务的侵入性比较强,流程比较繁琐。各个业务侧都须要支持升级。对于咱们创新行业来讲,成本有点大,咱们选择了另外一种模式来实现分布式事务——Saga模式。

4.2 Saga模式

Saga是一种纯业务补偿模式,其设计理念为,业务在调用的时候正常提交,当一个服务失败的时候,全部其依赖的上游服务都进行业务补偿操做。

Saga的基本概念:

  • saga:长事务,long live transaction

  • 每一个本地事务有对应的补偿事务

  • 执行状况

  • 正常:T1 -> T2 -> T3 -> … -> Tn

  • 异常:T1 -> T2 -> T3(异常)-> C3 -> C2 -> C1

Saga两种恢复策略:

  • backward recovery,向后恢复,补偿全部已完成的事务(回滚操做)

  • forward recovery,向前恢复,重试失败的事务,假设每一个子事务最终都会成功(重试操做)

Saga事务的优缺点:

  • 优势:模型比TCC更简单,只需业务方提供事务执行接口transaction、事务取消补偿接口cancel

  • 缺点:直接执行事务执行接口transaction,可能有反作用(不管是否回滚,都会执行事务接口的逻辑,举例:A帐号向B帐号转帐,T1事务对A用户扣款,T2事务对B用户加款,T1执行成功,同时产生了一条扣款记录,T2执行失败须要回滚T2和T1,在这个过程当中的反作用是A帐号能感知到金额变化和扣款记录)

针对上述业务背景,咱们对于业务侧只须要支持事务提交的接口( T )和失败补偿的接口( C )便可。具体流程以下图:

图片

对于Saga事务来讲只有完成跟未完成两种状态。不管是事务所有执行成功,仍是所有补偿成功都视为完成状态。出现异常致使流程中断为未完成状态。咱们针对于业务提交的流程的Http Code状态来区分是执行向前恢复(重试),仍是向后补偿(回滚)。对于没有补偿 C 的业务,咱们将采起向前恢复,直到成功。对于异常状况,使用离线补偿的方式对未完成的Saga事务进行重作,如长时间没法完成将触发报警,人工处理。

咱们行创基于上述saga模型研发了Saga的事务协调器,具体执行流程以下:

图片

业务方使用须要实现对应事务的执行方法和补偿方法,采用上报分布式事务的方式进行操做,事务上报的数据属性简介:

  • Name:本次流程的名称

  • OID:请求流程ID,必须惟一

  • Process:每一个子流程的属性简介(类型为list,按照顺序执行)

  • Transaction:执行事务的流程

  • Call:服务调用的方式,HTTP调用时传GET、POST等

  • ServiceName:服务名称

  • ServiceMethod:调用服务的方法名称,HTTP传请求的URL

  • Body:POST body,string类型

  • Query:Get Query,map[string]interfase{}

  • oid:订单ID, 必传,必须惟一,用于幂等性校验等

  • Compensate:执行失败的补偿流程

  • Call:服务调用的方式,HTTP调用时传GET、POST等

  • ServiceName:服务名称

  • ServiceMethod:调用服务的方法名称,HTTP传请求的URL

  • Body:POST body,string类型

  • Query:Get Query,map[string]interfase{}

  • oid:订单ID, 必传,必须惟一,用于幂等性校验等

业务方按上述规则上报数据,该事务会最终保证数据一致性,要么所有成功,要么都失败回滚。

咱们创新行业采用Saga模型来实现分布式事务,来解决平常微服务拆分带来的数据一致性的问题,知足了咱们平常的产品功能的须要,解决了棘手的问题。

5、总结

针对分布式事务的解决方案都有各自的特色,没有一个最优的方案,须要结合实际的应用场景选择合适的模式。

  • 2PC 和 3PC 是一种强一致性事务,不过仍是有数据不一致,阻塞等风险,并且只能用在数据库层面。

  • Saga、TCC是一种补偿性事务的思想,对业务入侵较大,须要业务方实现对应的方法。

  • 本地消息、事务消息和最大努力通知其实都是最终一致性事务,所以适用于一些对时间不敏感的业务。

推荐阅读:

云原生时代的搜索服务算力管理

浅谈小程序开源业务架构建设之路

百度小程序包流式下载安装优化

前端工程化之FaaS SSR方案

日志中台不重不丢实现浅谈

百度ToB垂类帐号权限平台的设计与实践