微服务架构中分布式事务实现方案怎样何取舍

在线体验各类最新模型,更有模型 免费Token 额度领取!
立即体验
简介:

提起微服务架构,不可避免的两个话题就是服务治理和分布式事务。数据库和业务模块的垂直拆分为我们带来了系统性能、稳定性和开发效率的提升的同时也引入了一些更复杂的问题,例如在数据一致性问题上,我们不再能够依赖数据库的本地事务,对于一系列的跨库写入操作,如何保证其原子性,是微服务架构下不得不面对的问题。

1 分布式事务解决方案

针对分布式系统的特点,基于不同的一致性需求产生了不同的分布式事务解决方案,追求强一致的两阶段提交、追求最终一致性的柔性事务和事务消息等等。各种方案没有绝对的好坏,抛开具体场景我们无法评价,更无法能做出合理选择。在选择分布式事务方案时,需要我们充分了解各种解决方案的原理和设计初衷,再结合实际的业务场景,从而做出科学合理的选择。

2 强一致解决方案

2.1 两阶段提交

两阶段提交算法中有两种角色:事务协调者和事务参与者,一个事务一般会涉及多个事务参与者,具体的两阶段过程如下图所示:

第一阶段:写库操作完成后协调者向所有参与者发送Prepare消息,询问各参与者的本地事务是否可以提交,参与者根据自身情况向协调者返回可以或不可以;

第二阶段:协调者收到所有参与者的反馈后,如果全部返回的是可以提交则向所有参与者发送提交事务命令。只要有一个参与者返回的是不能提交,则向所有参与者发送回滚命令。如下图所示:
_1_
图1 两阶段提交

在上述的两阶段模型中,事务提交过程中有可能出现协调者或个别参与者宕机的情况,但多数情况下参与事务的节点可以通过询问其他节点得知事务状态,做出正确的操作。但在极端情况下事务有可能处于未知状态。我们分析下下面这个场景:当协调者发送提交指令后宕机,而唯一收到提交指令的参与者完成提交后也宕机了,此时没有节点知道事务应该提交还是回滚,事务处于未知状态,所以在这种极端情况下可能造成数据的不一致。针对两阶段的缺陷,又提出了三阶段提交协议。

2.2 三阶段提交

三阶段提交是将第二阶段拆分成预提交和确认提交两个阶段。这样在事务提交过程中,无论哪个节点宕机,只要有一个存活节点处于预提交或是提交状态我们都可以确定事务是可以提交的(第一阶段已经确认事务可以提交),反之如果没有处于这两种状态的节点,则回滚事务。

_2_
图2 三阶段提交

从上面的分析可以看到,无论是两阶段还是三阶段最后的“提交”都是一个耗时极短的操作,即使在分布式系统中失败的概率也是非常小的,所以我们可以认为两阶段提交基本能够保证分布式事务原子性。

3 落地方案

上面介绍的只是理论基础,XA规范就是基于两阶段提交的理论模型提出的分布式事务规范,规范中的资源管理器相当于事务参与者;事务管理器相当于事务协调者,目前很多主流的关系数据库都实现了XA接口。

落地到实际应用中我们会发现两阶段提交存在的一些问题:

  1. 数据库产品要保证数据完成性,写入需要加锁,所以在整个分布式事务协调过程中可能造成数据库资源锁定时间过长,不适合并发高以及子事务生命周期较长的业务场景;
  2. XA规范要求事务管理器本地记录事务执行状态,所以事务管理器作为有状态服务不支持事务异地恢复;

XA能够最大程度保证数据的一致性,但在高并发场景下性能衰减非常严重,所以在数据一致性需求上如果不是“强一致”,不建议使用。

3.1 最终一致性解决方案

在我们大多数的业务场景中,追求的都是数据的最终一致性,业界也提出了很多柔性事务的解决方案,可以很大程度上保证数据的一致性,我们可以根据实际场景来权衡使用。具体的解决方案有很多,总结其设计思路可以分为下面3种模型:

3.1.1 TCC(Try-Confirm-Cancel)

TCC将事务分为Try,Confirm,Cancel三个阶段。

  1. Try阶段:尝试执行业务,预留资源;
  2. Confirm阶段:确认执行业务,使用Try阶段资源;
  3. Cancel阶段:取消执行业务,释放Try阶段预留的资源;

我们用一个转账汇款的业务场景,说明下TCC的具体过程。例如:张三给李四转账100元,一次转账业务由两个本地事务组成:1、张三账户扣减100元;2、李四账户增加100元。

事务成功处理流程如图3:

_3_Try_Confirm_
图3 Try-Confirm事务成功处理流程

事务失败处理流程如图4:

_4_Try_Cancel_
图4 Try-Cancel事务成功处理流程

Try阶段:

1、检查张三账户,满足要求账户扣减100元,记录扣减事件(预留资源);

2、检查李四账户有效性;

Confirm:

如果Try成功,李四账户增加100元,事务完成;

Cancel:

如果Try失败,张三账户增加100元,删除扣减事件记录(释放预留资源),事务取消。

从性能角度分析,TCC过程没有对资源加锁,对系统并发性能几乎没有影响,只是会有些额外辅助操作。需要注意,在这个模型中要保证数据一致性有两个技术难点需要解决:

  1. 需要有类似事务管理器的角色保证TCC过程的完整性;
  2. Confirm和Cancel方法需要保证幂等(由于不可避免的重试操作必须要保证幂等);

TCC对业务侵入非常大,对RD同学十分不友好,业务改造成本相当高。

3.1.2 SAGA模型

SAGA模型把一个分布式事务拆分为多个本地事务,每个本地事务都有相应的执行模块和补偿模块,当事务中任意一个本地事务出错时,可以通过调用对应的补偿方法恢复之前的事务,从而达到数据的最终的一致性。SAGA的事务管理器负责在事务失败时执行补偿逻辑,可以通过调用执行模块的逆向操作(例如执行子事务时同时生成逆向SQL)或调用业务开发人员提供的补偿方法(需要保证补偿的幂等性)来实现。

可以看到,SAGA虽然对业务造成一定的侵入,但当相对TCC已经有好很多了,而且,事务管理器理论上可以做到向后补偿(撤销所有已完成操作,恢复到事务开始状态)或向前补偿(继续完成未完成事务,使业务请求得到成功处理,更符合业务预期)。

3.1.3 MQ事务消息

MQ事务消息对分布式事务模型进行了简化,重点不再是保证所有子事务的原子性,而是保证本地事务和发送MQ消息的原子性,我们可以利用这一特点,将分布式事务转化成本地事务和若干发送MQ消息的操作,然后要求消费方确保消费成功。利用MQ事务消息,在系统中去掉了TCC和SAGA方案中的事务管理器角色,简化了分布式事务模型,同时这也是对业务侵入最低最友好的方案(不用提供补偿接口)。

当然这里也有两个基本前提:

  1. MQ系统保证消息能不丢失;
  2. 消费方确保消费幂等(保证不丢失,就很难避免重复消费)。

需要注意的是,MQ事务消息简化了事务模型、降低了业务侵入,所以对数据一致性的保证保障也就相对比较低了。

  1. 总结

柔性事务解决方案中,虽然SAGA和TCC看上去可以保证数据的最终一致性,但分布式系统的成产环境复杂多变,某些情况是可以导致柔性事务机制失效的,所以无论使用那种方案,都需要最终的兜底策略,人工校验,修复数据。

我们综合对比下几种分布式事务解决方案:

一致性保证:XA > TCC = SAGA > 事务消息

业务友好性:XA > 事务消息 > SAGA > TCC

性 能 损 耗:XA > TCC > SAGA = 事务消息

最后,在设计系统时我们一定要结合业务自身的一致性需求,选择恰当的方案。可以看到对数据一致性保障越高的方案其开发成本、维护难度和系统性能损耗就越大,一定不要一味的追求高大上的方案,对系统过度设计。

相关实践学习
快速体验阿里云云消息队列RocketMQ版
本实验将带您快速体验使用云消息队列RocketMQ版Serverless系列实例进行获取接入点、创建Topic、创建订阅组、收发消息、查看消息轨迹和仪表盘。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
相关文章
|
11月前
|
监控 Java API
Spring Boot 3.2 结合 Spring Cloud 微服务架构实操指南 现代分布式应用系统构建实战教程
Spring Boot 3.2 + Spring Cloud 2023.0 微服务架构实践摘要 本文基于Spring Boot 3.2.5和Spring Cloud 2023.0.1最新稳定版本,演示现代微服务架构的构建过程。主要内容包括: 技术栈选择:采用Spring Cloud Netflix Eureka 4.1.0作为服务注册中心,Resilience4j 2.1.0替代Hystrix实现熔断机制,配合OpenFeign和Gateway等组件。 核心实操步骤: 搭建Eureka注册中心服务 构建商品
1483 3
|
人工智能 安全 Java
智慧工地源码,Java语言开发,微服务架构,支持分布式和集群部署,多端覆盖
智慧工地是“互联网+建筑工地”的创新模式,基于物联网、移动互联网、BIM、大数据、人工智能等技术,实现对施工现场人员、设备、材料、安全等环节的智能化管理。其解决方案涵盖数据大屏、移动APP和PC管理端,采用高性能Java微服务架构,支持分布式与集群部署,结合Redis、消息队列等技术确保系统稳定高效。通过大数据驱动决策、物联网实时监测预警及AI智能视频监控,消除数据孤岛,提升项目可控性与安全性。智慧工地提供专家级远程管理服务,助力施工质量和安全管理升级,同时依托可扩展平台、多端应用和丰富设备接口,满足多样化需求,推动建筑行业数字化转型。
457 5
|
9月前
|
Cloud Native Serverless API
微服务架构实战指南:从单体应用到云原生的蜕变之路
🌟蒋星熠Jaxonic,代码为舟的星际旅人。深耕微服务架构,擅以DDD拆分服务、构建高可用通信与治理体系。分享从单体到云原生的实战经验,探索技术演进的无限可能。
微服务架构实战指南:从单体应用到云原生的蜕变之路
|
存储 缓存 NoSQL
分布式系统架构8:分布式缓存
本文介绍了分布式缓存的理论知识及Redis集群的应用,探讨了AP与CP的区别,Redis作为AP系统具备高性能和高可用性但不保证强一致性。文章还讲解了透明多级缓存(TMC)的概念及其优缺点,并详细分析了memcached和Redis的分布式实现方案。此外,针对缓存穿透、击穿、雪崩和污染等常见问题提供了应对策略,强调了Cache Aside模式在解决数据一致性方面的作用。最后指出,面试中关于缓存的问题多围绕Redis展开,建议深入学习相关知识点。
912 8
|
10月前
|
消息中间件 缓存 监控
中间件架构设计与实践:构建高性能分布式系统的核心基石
摘要 本文系统探讨了中间件技术及其在分布式系统中的核心价值。作者首先定义了中间件作为连接系统组件的"神经网络",强调其在数据传输、系统稳定性和扩展性中的关键作用。随后详细分类了中间件体系,包括通信中间件(如RabbitMQ/Kafka)、数据中间件(如Redis/MyCAT)等类型。文章重点剖析了消息中间件的实现机制,通过Spring Boot代码示例展示了消息生产者的完整实现,涵盖消息ID生成、持久化、批量发送及重试机制等关键技术点。最后,作者指出中间件架构设计对系统性能的决定性影响,
|
监控 Linux 应用服务中间件
Linux多节点多硬盘部署MinIO:分布式MinIO集群部署指南搭建高可用架构实践
通过以上步骤,已成功基于已有的 MinIO 服务,扩展为一个 MinIO 集群。该集群具有高可用性和容错性,适合生产环境使用。如果有任何问题,请检查日志或参考MinIO 官方文档。作者联系方式vx:2743642415。
4077 57
|
12月前
|
缓存 Cloud Native Java
Java 面试微服务架构与云原生技术实操内容及核心考点梳理 Java 面试
本内容涵盖Java面试核心技术实操,包括微服务架构(Spring Cloud Alibaba)、响应式编程(WebFlux)、容器化(Docker+K8s)、函数式编程、多级缓存、分库分表、链路追踪(Skywalking)等大厂高频考点,助你系统提升面试能力。
1575 0
|
消息中间件 人工智能 监控
文生图架构设计原来如此简单之分布式服务
想象一下,当成千上万的用户同时要求AI画图,如何公平高效地处理这些请求?文生图/图生图大模型的架构设计看似复杂,实则遵循简单而有效的原则:合理排队、分工明确、防患未然。
588 14
文生图架构设计原来如此简单之分布式服务
|
并行计算 PyTorch 算法框架/工具
融合AMD与NVIDIA GPU集群的MLOps:异构计算环境中的分布式训练架构实践
本文探讨了如何通过技术手段混合使用AMD与NVIDIA GPU集群以支持PyTorch分布式训练。面对CUDA与ROCm框架互操作性不足的问题,文章提出利用UCC和UCX等统一通信框架实现高效数据传输,并在异构Kubernetes集群中部署任务。通过解决轻度与强度异构环境下的挑战,如计算能力不平衡、内存容量差异及通信性能优化,文章展示了如何无需重构代码即可充分利用异构硬件资源。尽管存在RDMA验证不足、通信性能次优等局限性,但该方案为最大化GPU资源利用率、降低供应商锁定提供了可行路径。源代码已公开,供读者参考实践。
1468 3
融合AMD与NVIDIA GPU集群的MLOps:异构计算环境中的分布式训练架构实践

热门文章

最新文章