深度 | 为你解读 SOFA-DTX 分布式事务的设计演进路线下篇

简介: 众所周知,蚂蚁金服在近几年除了支付业务以外,还发展出了很多复杂的金融业务,比如财富、保险、银行等。同时,在2014年蚂蚁金服全面开启了金融云时代,也会对外赋能合作方和客户。

《干货 | 一篇文章带你学习分布式事务》

我们将分为两篇来详细与大家解读,本篇为下篇。

上篇回顾:深度 | 为你解读 SOFA-DTX 分布式事务的设计演进路线上篇。

面对上层业务系统的复杂、业务种类的丰富等等业务需求,对分布式事务解决方案提出了全新的要求,所以我们在 TCC 模型基础上又加入了框架托管(FMT)模型,其简单易用,对业务无侵入的特点,可以较好的解决金融云场景下接入便捷性问题。

并且,我们对数据实时一致性、通用性、性能再思考,与自研数据库 OceanBase 深度定制,推出 XA 模型,共同打造实时数据一致性的整体分布式事务解决方案。

以下是详细内容

一、关键设计考量:无侵入自动化的接入体验

众所周知,蚂蚁金服在近几年除了支付业务以外,还发展出了很多复杂的金融业务,比如财富、保险、银行等。同时,在2014年蚂蚁金服全面开启了金融云时代,也会对外赋能合作方和客户。在这些新的场景下面,分布式事务产品面临新的挑战,客户的性能需求可能不像蚂蚁金服内部要求那么高,而是更关注接入的便利性和通用性,要求简单易用,对业务代码无侵入。因此,分布式事务产品开始全面升级,满足更多客户对云端产品的需求。

1.1 框架托管FMT(Framework-managed transactions)模型
TCC 模型作用于业务层,负责协调从业务服务的最终一致性。所有被纳入到分布式事务的从业务服务,需要为框架提供Try、Confirm、Cancel三个方法,并且需要满足幂等性。由于方法实现和要满足的约束条件都需要业务方提供,这无疑就大大提高了接入门槛。所以我们在TCC 模型上继续往前推进发展,提出了FMT 模型来解决接入便捷性的问题。

FMT 分布式事务模型与 TCC 模型类似,也同样包含主业务服务、从业务服务、业务活动管理器,如下所示:

image.png

不同的是,从业务服务不再需要提供 Try、Confirm、Cancel三个方法,而是直接按照JDBC 标准,通过托管框架与底层数据库交互,就像使用普通数据源一样。托管框架对业务来说是透明的,主要负责解析SQL语义,自动生成两阶段操作。

1.2 FMT 模型实现原理
托管框架的两阶段操作如下图所示:

image.png

FMT 框架要求从业务服务只需要正常执行SQL操作就可以了,框架会把业务的本地事务操作作为第一阶段。在第一阶段,框架会拦截用户SQL,解析SQL语义,然后把业务SQL涉及数据执行前后的状态保存下来,即数据快照,这个就相当于在逻辑上完成了数据库内的undo和redo操作。在第二阶段,如果这个事务要提交,那么框架直接把快照数据删除就可以了,因为第一阶段的正常操作已经执行完成。如果该事务要回滚,那么会先校验脏写,根据第一阶段保存的执行后的快照,检查在本事务执行过程中,数据有没有被其他操作修改,如果没有,则把数据执行前的快照拿出来,完成回滚操作。

1.3 一阶段示例

image.png

举个例子,上图左边这张表有两列,一列是账号,另一列是金额。这时如果要针对该账户执行一条update操作,框架会怎么做呢?

在 update 之前,会先把账户的金额保存下来,执行 update 操作,然后把执行之后的金额保存下来。因为在二阶段有可能会是回滚操作,回滚的时候如果想把执行之前的数据覆盖回去的话,必须要保证在覆盖的那个时刻,这些行上面的数据没有被别人变更过,所以最后会加一个逻辑行锁,这个就是金融系统的特性需求。

1.4 与数据访问代理集成
为了更加简化云上用户接入,我们继续和内部产品数据访问代理DBP合作集成,如下所示:

image.png

分布式事务产品框架可以认为是被集成在数据访问代理里,当进行一个事务时,上层业务方对于底下的分布式事务和本地事务是一视同仁的,通过数据代理看一个事务,并执行SQL。如果是分布式事务,数据访问代理会通知框架去执行前面提到的一系列保证事务的操作,以保证数据的最终一致。

二. 关键设计考量:数据实时一致性、通用性、性能

2.1 XA模型
TCC 和 FMT 两个模型都是在最佳实践上追求数据的最终一致性,而不是实时一致性。

我们分析了金融云上的客户发现,如果把业务模型假定成数据最终一致性,那么依然有很多金融客户不得不做出很大的妥协和变更,尤其是原有的业务组织模型和业务逻辑实现。而且这种妥协和调整的工作量是很大的,门槛也是非常高的。

所以我们基于标准 XA 做了一个 XA 模型来满足客户对数据实时一致性的需求。

image.png

原生 XA 协议提出至今,大概有10-20的时间了,但是在工业界应用的历史和案子都很少。为什么会这样呢?我们认为最重要的一点就是在追求数据实时一致性的同时,性能损失太大了。主要有两个比较方面的性能损失,一个是读和写之间的冲突,另一个是写与写之间的冲突。

2.2 标准XA问题分析
了解数据库内核的人都清楚,数据库内部解决写和非加锁读的冲突是通过MVCC 机制来实现的。假如说最新的数据块在更新的同时,你的读是可以读正在更新的数据块的上一个快照。但是在分布式架构下,单机 MVCC 机制并不能满足数据实时性一致性要求。

依然是转账业务场景,A 账户给 B 账务转账 10 块钱。但是 A 账户和 B账户分别在两个数据库分片 DB1 和 DB2 上。其操作执行过程如下所以:

image.png

如上图所示,DB1 的本地子事务已经提交完毕,但是 DB2 的本地子事务还没提交,这个时候只能读到 DB1 上子事务执行的内容,读不到 DB2 上的子事务。也就是说,虽然在单个DB 上的本地事务是实时一致的,但是从全局来看,一个全局事务执行过程的中间状态被观察到了,全局实时一致性就被破坏了。

但是原生的 XA 协议没有规定快照读这个概念,也就没有定义怎么实现全局实时一致性。最简单的做法就是使用串行化的隔离级别,即使是快照读也需要转换为加锁读,从而来保证分布式事务的实时一致性。

当然,由于串行化隔离级别的性能较差,很多分布式数据库都自己实现了分布式MVCC 机制来提供全局的实时一致性读。一个基本思路是用一个集中式或者逻辑上单调递增的东西来控制生成全局快照(Snapshot),每个事务或者每条 SQL 执行时都去获取一次,从而实现不同隔离级别下的全局一致性,如下图所示:

image.png

在 DB1 的本地子事务已经提交完毕,DB2 的本地子事务还没提交的中间状态,其他并发事务只能看到该事务执行之前的快照。

我们的分布式事务产品同样实现了分布式 MVCC 机制,从而在保证实时一致性的同时,最大程度的保证读写并发性能。

2.3 并发写优化 --- 与 OB 深度定制commit 延迟优化
除了实现分布式 MVCC 保证并发读写性能外,我们还与自研数据库 OceanBase 深度定制优化并发写,进一步提升产品性能,共同打造实时数据一致性的整体解决方案。

传统标准的二阶段提交过程如下:

image.png

其中,绿色方块表示持久化日志,黄色方块表示事务提交。从图中可以看到,单次 Commit 操作需要有3次日志延迟、1次事务延迟以及2次 RPC 延迟。

OceanBase 内部实现XA协议的时候,会在和协调者交互的时候附带一些信息,并且在 Commit 时落盘,减少 Commit 过程中涉及到的 RPC 和落盘的操作,以达到减少用户 Commit 时间的效果。

优化后时序图如下:

image.png

虽然在 Commit 操作之后,还有 Clear 操作,但是在执行 Clear 时,用户的Commit 请求已经返回了,所以并不影响用户感知的 Commit 请求延迟。因此,从用户感知的角度来说,单次 Commit 操作实际上只需要 1次日志延迟、1 次事务延迟 以及 2 次RPC延迟。

通过以上优化,两阶段提交与普通提交的落盘次数和 RPC 次数是相同的,也就是说耗时和普通提交相差无几,写和写之间的冲突所带来的额外性能消耗将被降低很大一部分。

image.png

三. 上下篇总结

上篇回顾:深度 | 为你解读 SOFA-DTX 分布式事务的设计演进路线上篇。

总结关于分布式事务服务的关键设计考量,首先为了保障支付业务的核心需求,保障分布式环境下交易一致性的问题,我们基于BASE思想,在业务层实现了 TCC 模型,并且为了业务发展的需求,优化了其工程实践,实现海量并发处理能力,让它的性能可以达到比业界其它产品高很多的状态。

其次,因为上层业务系统的复杂、业务种类的丰富等等业务需求,对分布式事务解决方案提出了全新的要求,所以我们在 TCC 模型基础上又加入了框架托管(FMT)模型,其简单易用,对业务无侵入的特点,可以较好的解决金融云场景下接入便捷性问题。

最后,我们对数据实时一致性、通用性、性能再思考,与自研数据库 OceanBase 深度定制,推出 XA 模型,共同打造实时数据一致性的整体分布式事务解决方案。

四. 了解更多:金融级云原生架构解决方案 SOFA

通过十多年的探索与实践,我们积累了大量的架构设计原则、最佳实践和产品服务案例,并构建了一整套金融级云原生架构解决方案,这套架构叫做SOFA(Scalable Open Financial Architecture,分布式事务 DTX 亦是其重要的组成部分),源自蚂蚁内部分布式架构实践,是一整套完整的金融级中间件产品技术和演进式架构转型服务体系,已经向国内金融机构开放,提供了完整的金融IT基础架构转型量身打造的技术平台和可落地路径,使业务应用能专注需求作敏捷交付,又能同时原生地拥有金融级的高可用、一致性特性和互联网的海量并发、弹性伸缩等云原生基础架构能力。

蚂蚁金服期望通过逐步向社区(链接如下):

https://github.com/alipay

开源 SOFA 体系内的各个组件,帮助大家更加敏捷稳妥地实现金融级云原生架构。我们也非常欢迎来自技术社区和各行业的伙伴能够参与共同探讨、交流和共建,使其更加完善和稳固,满足更多金融级架构转型升级的需求。

目录
相关文章
|
数据库 存储 Cloud Native
深度 | 为你解读 SOFA-DTX 分布式事务的设计演进路线上篇
我们将分为两篇来详细与大家解读,本篇为上篇。主要讲解 SOFA-DTX 如何满足支付业务的核心需求,保障分布式环境下交易一致性,并且在此之上的严苛的工程优化。
1277 0
|
SQL 存储 Cloud Native
深度| 一篇文章为你解读SOFA-DTX 分布式事务的设计演进路线
小蚂蚁说: 本文介绍了蚂蚁金服在分布式事务上,经过多年发展,服务于内外部大量不同业务,沉淀出的一整套包含TCC、FMT、XA模型的分布式事务解决方案。并且在持续对外输出的过程中,进一步打磨产品体验,适应各种严苛的金融级场景和机构需求,比如跨机房跨地域的容灾业务连续性保障能力等。
5787 0
|
3月前
|
NoSQL Java Redis
太惨痛: Redis 分布式锁 5个大坑,又大又深, 如何才能 避开 ?
Redis分布式锁在高并发场景下是重要的技术手段,但其实现过程中常遇到五大深坑:**原子性问题**、**连接耗尽问题**、**锁过期问题**、**锁失效问题**以及**锁分段问题**。这些问题不仅影响系统的稳定性和性能,还可能导致数据不一致。尼恩在实际项目中总结了这些坑,并提供了详细的解决方案,包括使用Lua脚本保证原子性、设置合理的锁过期时间和使用看门狗机制、以及通过锁分段提升性能。这些经验和技巧对面试和实际开发都有很大帮助,值得深入学习和实践。
太惨痛: Redis 分布式锁 5个大坑,又大又深, 如何才能 避开 ?
|
5月前
|
NoSQL Redis
基于Redis的高可用分布式锁——RedLock
这篇文章介绍了基于Redis的高可用分布式锁RedLock的概念、工作流程、获取和释放锁的方法,以及RedLock相比单机锁在高可用性上的优势,同时指出了其在某些特殊场景下的不足,并提到了ZooKeeper作为另一种实现分布式锁的方案。
135 2
基于Redis的高可用分布式锁——RedLock
|
5月前
|
缓存 NoSQL Java
SpringBoot整合Redis、以及缓存穿透、缓存雪崩、缓存击穿的理解分布式情况下如何添加分布式锁 【续篇】
这篇文章是关于如何在SpringBoot应用中整合Redis并处理分布式场景下的缓存问题,包括缓存穿透、缓存雪崩和缓存击穿。文章详细讨论了在分布式情况下如何添加分布式锁来解决缓存击穿问题,提供了加锁和解锁的实现过程,并展示了使用JMeter进行压力测试来验证锁机制有效性的方法。
SpringBoot整合Redis、以及缓存穿透、缓存雪崩、缓存击穿的理解分布式情况下如何添加分布式锁 【续篇】
|
28天前
|
存储 NoSQL Java
使用lock4j-redis-template-spring-boot-starter实现redis分布式锁
通过使用 `lock4j-redis-template-spring-boot-starter`,我们可以轻松实现 Redis 分布式锁,从而解决分布式系统中多个实例并发访问共享资源的问题。合理配置和使用分布式锁,可以有效提高系统的稳定性和数据的一致性。希望本文对你在实际项目中使用 Redis 分布式锁有所帮助。
87 5
|
2月前
|
NoSQL Java 数据处理
基于Redis海量数据场景分布式ID架构实践
【11月更文挑战第30天】在现代分布式系统中,生成全局唯一的ID是一个常见且重要的需求。在微服务架构中,各个服务可能需要生成唯一标识符,如用户ID、订单ID等。传统的自增ID已经无法满足在集群环境下保持唯一性的要求,而分布式ID解决方案能够确保即使在多个实例间也能生成全局唯一的标识符。本文将深入探讨如何利用Redis实现分布式ID生成,并通过Java语言展示多个示例,同时分析每个实践方案的优缺点。
65 8
|
2月前
|
NoSQL Redis
Redis分布式锁如何实现 ?
Redis分布式锁通过SETNX指令实现,确保仅在键不存在时设置值。此机制用于控制多个线程对共享资源的访问,避免并发冲突。然而,实际应用中需解决死锁、锁超时、归一化、可重入及阻塞等问题,以确保系统的稳定性和可靠性。解决方案包括设置锁超时、引入Watch Dog机制、使用ThreadLocal绑定加解锁操作、实现计数器支持可重入锁以及采用自旋锁思想处理阻塞请求。
61 16
|
2月前
|
缓存 NoSQL PHP
Redis作为PHP缓存解决方案的优势、实现方式及注意事项。Redis凭借其高性能、丰富的数据结构、数据持久化和分布式支持等特点,在提升应用响应速度和处理能力方面表现突出
本文深入探讨了Redis作为PHP缓存解决方案的优势、实现方式及注意事项。Redis凭借其高性能、丰富的数据结构、数据持久化和分布式支持等特点,在提升应用响应速度和处理能力方面表现突出。文章还介绍了Redis在页面缓存、数据缓存和会话缓存等应用场景中的使用,并强调了缓存数据一致性、过期时间设置、容量控制和安全问题的重要性。
44 5
|
3月前
|
缓存 NoSQL Java
大数据-50 Redis 分布式锁 乐观锁 Watch SETNX Lua Redisson分布式锁 Java实现分布式锁
大数据-50 Redis 分布式锁 乐观锁 Watch SETNX Lua Redisson分布式锁 Java实现分布式锁
76 3
大数据-50 Redis 分布式锁 乐观锁 Watch SETNX Lua Redisson分布式锁 Java实现分布式锁