架构系列——分布式事务

简介: 架构系列——分布式事务

前言

系统一旦分布式了之后,通信、缓存、消息、事务、锁、配置、日志、监控、会话等等各种原来单块系统场景下很容易解决的问题,都会变得很复杂,需要引入大量外部的技术。

本文对分布式基础知识点做出一定的总结,适合想要了解分布式或者刚开始接触分布式的程序员阅读。


一、分布式框架

如果要让不同的子系统或者服务之间互相通信,首先必须有一套分布式服务框架。也就是各个服务可以互相感知到对方在哪里,可以发送请求过去,可以通过HTTP或者RPC的方式。

最常见的技术就是dubbo以及spring cloud,当然大厂一般都是自己有服务框架。


二、分布式事务

2.1 事务特性

ACID

A原子性:在事务的执行过程中,要么全部执行成功,要么都不成功。


C一致性:事务在执行前后,不能破坏数据的完整性。一致性更多的说的是通过AID来达到目的,数据应该符合预先的定义和约束,由应用层面来保证,还有的说法是C是强行为了ACID凑出来的。


I隔离性:多个事务之间是互相隔离的,事务之间不能互相干扰,涉及到不同事务的隔离级别的问题。


D持久性:一旦事务提交,数据库中数据的状态就应该是永久性的。


一个数据库的本地事务机制仅仅对落到自己身上的操作起作用,无法干涉对其他数据库的查询操作。所以,数据库自身提供的本地事务机制无法确保业务对多数据源全局操作的可靠性。


基于此,针对多数据源操作提出的分布式事务机制就出现了。


2.2 分布式事务模型

- 事务参与者:例如每个数据库就是一个事务参与者


- 事务协调者:访问多个数据源的服务程序,例如 shopping-service 就是事务协调者


- 资源管理器(Resource Manager, RM):通常与事务参与者同义


- 事务管理器(Transaction Manager, TM):通常与事务协调者同义


2.3 二将军问题和幂等性

一支白军被围困在一个山谷中,山谷的左右两侧是蓝军。困在山谷中的白军人数多于山谷两侧的任意一支蓝军,而少于两支蓝军的之和。若一支蓝军对白军单独发起进攻,则必败无疑;但若两支蓝军同时发起进攻,则可取胜。两只蓝军的总指挥位于山谷左侧,他希望两支蓝军同时发起进攻,这样就要把命令传到山谷右侧的蓝军,以告知发起进攻的具体时间。假设他们只能派遣士兵穿越白军所在的山谷(唯一的通信信道)来传递消息,那么在穿越山谷时,士兵有可能被俘虏。


网络二将军问题的存在使得消息的发送者往往要重复发送消息,直到收到接收者的确认才认为发送成功,但这往往又会导致消息的重复发送。例如电商系统中订单模块调用支付模块扣款的时候,如果网络故障导致二将军问题出现,扣款请求重复发送,产生的重复扣款结果显然是不能被接受的。因此要保证一次事务中的扣款请求无论被发送多少次,接收方有且只执行一次扣款动作,这种保证机制叫做接收方的幂等性。


2.4 CAP 定理

一个系统不可能同时满足一致性(C:Consistency),可用性(A: Availability)和分区容错性(P:Partition tolerance),最多只能同时满足其中的2个。分布式系统必须满足分区容错性,剩下一个是从一致性和可用性之间做权衡,但是最终都要达到一致性。


Eureca:满足AP

Zookeeper:满足CP

2.5 Base 理论

全称:Basically Available(基本可用),Soft state(软状态),和 Eventually consistent(最终一致性)


即使无法做到强一致性(Strong consistency),但每个应用都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性(Eventual consistency)。


2.6 XA

分布式事务处理的规范,是一个规范或者说是协议,定义了事务管理器TM(Transaction Manager),资源管理器RM(Resource Manager)和应用程序。

XA定义了规范,那么2PC和3PC就是它的具体实现方式。

2.7 二阶段提交 2PC

Two-Phase Commit,事务的提交过程分成了两个阶段来进行处理。

投票阶段

TM向所有的参与者发送prepare请求,询问是否可以执行事务,等待各个参与者的响应。


这个阶段可以认为只是执行了事务的SQL语句,但是还没有提交。


如果都执行成功了就返回YES,否则返回NO。


执行阶段


执行阶段就是真正的事务提交的阶段,但是要考虑到失败的情况。


如果所有的参与者都返回YES,那么就执行发送commit命令,参与者收到之后执行提交事务。


反之,只要有任意一个参与者返回的是NO的话,就发送rollback命令,然后执行回滚的操作。


2PC的缺陷


1.同步阻塞,可以看到,在执行事务的过程当中,所有数据库的资源都被锁定,如果这时候有其他人来访问这些资源,将会被阻塞,这是一个很大的性能问题。


2.TM单点故障问题,只要一个TM,一旦TM宕机,那么整个流程无法继续完成。


3.数据不一致,如果在执行阶段,参与者脑裂或者其他故障导致没有收到commit请求,部分提交事务,部分未提交,那么数据不一致的问题就产生了。


2.8 三阶段提交 3PC

既然2PC有这么多问题,所以就衍生出了3PC的概念,也叫做三阶段提交,他把整个流程分成了CanCommit、PreCommit、DoCommit三个步骤,相比2PC,增加的就是CanCommit阶段。


与两阶段提交不同的是,三阶段提交有两个改动点。


1.引入超时机制。同时在协调者和参与者中都引入超时机制。


2.在第一阶段和第二阶段中插入一个准备阶段。保证了在最后提交阶段之前各参与节点的状态是一致的。


也就是说,除了引入超时机制之外,3PC把2PC的准备阶段再次一分为二,这样三阶段提交就有CanCommit、PreCommit、DoCommit三个阶段。


相比2PC的改进


对于2PC的同步阻塞的问题,我们可以看到因为3PC加入了参与者的超时机制,所以原来2PC的如果某个参与者故障导致的同步阻塞的问题时间缩短了,这是一个优化,但是并没有完全避免。


第二个单点故障的问题,同样因为超时机制的引入,一定程度上也算是优化了。


但是数据不一致的问题,这个始终没有得到解决。


2.9 TCC

TCC的模式叫做Try、Confirm、Cancel,实际上也就是2PC的一个变种而已。


实现这个模式,一个事务的接口需要拆分成3个,也就是Try预占、Confirm确认提交、最后Cancel回滚。


几个比较不错的框架,都是国内开源的:ByteTCC,tcc-transaction,himly


2.10 消息队列

以上都是一些理论,生产环境中很少有人用到。而基于消息队列来实现最终一致性的方案,这个相比前面的我个人认为还稍微靠谱一点。基于消息队列的可能真正在应用的还稍微多一点。


这个方案基于MQ来保证消息事务的最终一致性,还算是一个比较合理的解决方案,只要保证MQ的可靠性就可以正常实施应用,业务消费方根据本身的消息重试达到最终一致性。


参考文献:

[1].Java同学找工作最懵圈的问题:到底啥是分布式系统开发经验?

[2].《我想进大厂》之分布式事务篇

[3].搞定分布式,程序员进阶之路

[4].瞅一眼?25张图让你彻底掌握分布式事务原理。

[5].分布式相关面试题

相关文章
|
10月前
|
监控 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注册中心服务 构建商品
1454 3
|
人工智能 安全 Java
智慧工地源码,Java语言开发,微服务架构,支持分布式和集群部署,多端覆盖
智慧工地是“互联网+建筑工地”的创新模式,基于物联网、移动互联网、BIM、大数据、人工智能等技术,实现对施工现场人员、设备、材料、安全等环节的智能化管理。其解决方案涵盖数据大屏、移动APP和PC管理端,采用高性能Java微服务架构,支持分布式与集群部署,结合Redis、消息队列等技术确保系统稳定高效。通过大数据驱动决策、物联网实时监测预警及AI智能视频监控,消除数据孤岛,提升项目可控性与安全性。智慧工地提供专家级远程管理服务,助力施工质量和安全管理升级,同时依托可扩展平台、多端应用和丰富设备接口,满足多样化需求,推动建筑行业数字化转型。
443 5
|
存储 缓存 NoSQL
分布式系统架构8:分布式缓存
本文介绍了分布式缓存的理论知识及Redis集群的应用,探讨了AP与CP的区别,Redis作为AP系统具备高性能和高可用性但不保证强一致性。文章还讲解了透明多级缓存(TMC)的概念及其优缺点,并详细分析了memcached和Redis的分布式实现方案。此外,针对缓存穿透、击穿、雪崩和污染等常见问题提供了应对策略,强调了Cache Aside模式在解决数据一致性方面的作用。最后指出,面试中关于缓存的问题多围绕Redis展开,建议深入学习相关知识点。
900 8
|
9月前
|
消息中间件 缓存 监控
中间件架构设计与实践:构建高性能分布式系统的核心基石
摘要 本文系统探讨了中间件技术及其在分布式系统中的核心价值。作者首先定义了中间件作为连接系统组件的"神经网络",强调其在数据传输、系统稳定性和扩展性中的关键作用。随后详细分类了中间件体系,包括通信中间件(如RabbitMQ/Kafka)、数据中间件(如Redis/MyCAT)等类型。文章重点剖析了消息中间件的实现机制,通过Spring Boot代码示例展示了消息生产者的完整实现,涵盖消息ID生成、持久化、批量发送及重试机制等关键技术点。最后,作者指出中间件架构设计对系统性能的决定性影响,
|
监控 Linux 应用服务中间件
Linux多节点多硬盘部署MinIO:分布式MinIO集群部署指南搭建高可用架构实践
通过以上步骤,已成功基于已有的 MinIO 服务,扩展为一个 MinIO 集群。该集群具有高可用性和容错性,适合生产环境使用。如果有任何问题,请检查日志或参考MinIO 官方文档。作者联系方式vx:2743642415。
4009 57
|
消息中间件 人工智能 监控
文生图架构设计原来如此简单之分布式服务
想象一下,当成千上万的用户同时要求AI画图,如何公平高效地处理这些请求?文生图/图生图大模型的架构设计看似复杂,实则遵循简单而有效的原则:合理排队、分工明确、防患未然。
571 14
文生图架构设计原来如此简单之分布式服务
|
并行计算 PyTorch 算法框架/工具
融合AMD与NVIDIA GPU集群的MLOps:异构计算环境中的分布式训练架构实践
本文探讨了如何通过技术手段混合使用AMD与NVIDIA GPU集群以支持PyTorch分布式训练。面对CUDA与ROCm框架互操作性不足的问题,文章提出利用UCC和UCX等统一通信框架实现高效数据传输,并在异构Kubernetes集群中部署任务。通过解决轻度与强度异构环境下的挑战,如计算能力不平衡、内存容量差异及通信性能优化,文章展示了如何无需重构代码即可充分利用异构硬件资源。尽管存在RDMA验证不足、通信性能次优等局限性,但该方案为最大化GPU资源利用率、降低供应商锁定提供了可行路径。源代码已公开,供读者参考实践。
1421 3
融合AMD与NVIDIA GPU集群的MLOps:异构计算环境中的分布式训练架构实践
|
消息中间件 缓存 算法
分布式开发:数字时代的高性能架构革命-为什么要用分布式?优雅草卓伊凡
分布式开发:数字时代的高性能架构革命-为什么要用分布式?优雅草卓伊凡
1461 0
分布式开发:数字时代的高性能架构革命-为什么要用分布式?优雅草卓伊凡
|
存储 Prometheus Cloud Native
分布式系统架构6:链路追踪
本文深入探讨了分布式系统中的链路追踪理论,涵盖追踪与跨度的概念、追踪系统的模块划分及数据收集的三种方式。链路追踪旨在解决复杂分布式系统中请求流转路径不清晰的问题,帮助快速定位故障和性能瓶颈。文中介绍了基于日志、服务探针和边车代理的数据收集方法,并简述了OpenTracing、OpenCensus和OpenTelemetry等链路追踪协议的发展历程及其特点。通过理解这些概念,可以更好地掌握开源链路追踪框架的使用。
1650 41
|
人工智能 运维 监控
领先AI企业经验谈:探究AI分布式推理网络架构实践
当前,AI行业正处于快速发展的关键时期。继DeepSeek大放异彩之后,又一款备受瞩目的AI智能体产品Manus横空出世。Manus具备独立思考、规划和执行复杂任务的能力,其多智能体架构能够自主调用工具。在GAIA基准测试中,Manus的性能超越了OpenAI同层次的大模型,展现出卓越的技术实力。