当前位置: 首页 > 科技观察

再问你,你真的了解分布式事务吗?

时间:2023-03-16 20:04:12 科技观察

对于分布式事务的概念,可能还有很多小伙伴不理解或者理解的不是很深。本文将带你在一篇文章中了解“分布式事务”。图片来自Pexels本地事务Transaction由一组SQL组成,它有四个ACID特性:Atomicity:原子性,一组SQL构成一个事务,要么全部生效,要么都不生效,会有不会有偏影响。Consistency:一致性,数据库在一次事务操作后从一种状态变为另一种状态。可以说原子性是用行为来描述的,而一致性是用结果来描述的。Isolation:隔离,事务操作的数据对象与其他事务操作的数据对象隔离,互不影响。Durability:持久性,事务提交后,结果是永久的,即使出现宕机(非磁盘损坏)。事务实现对于MySQL数据库(InnoDB存储引擎)来说,隔离就是通过不同粒度的锁机制实现事务之间的隔离。redologredolog和undolog回滚日志保证了原子性、一致性和持久性。重做日志:当数据库修改数据时,需要从磁盘中读取数据页到缓冲池中,然后在缓冲池中进行修改。那么此时缓冲池中的数据页与磁盘上的数据页不一致,缓冲池中的数据页称为脏页脏数据。如果此时DB服务异常重启,数据还不在内存中,还没有同步到磁盘文件(注意同步到磁盘文件是随机IO),即会发生数据丢失。如果此时有文件,当缓冲池中的数据页发生变化时,将相应的修改记录记录到这个文件中(注意日志是顺序IO)。那么当DB服务崩溃时,当DB恢复时,也可以根据这个文件的记录内容,重新应用到磁盘文件中,数据保持一致。Undolog:undolog用于存储数据被修改前的值。如果修改异常,可以通过undolog实现回滚操作,保证事务的一致性。此外,InnoDBMVCC事务特性也是基于undolog实现的。undolog分为insertundolog(insert语句产生的日志,事务提交后直接删除)和updateundolog(delete和update语句产生的日志。由于undolog可能会用到通过MVVC机制,事务提交时无法删除。)。问题介绍CAP理论CAP原理,又称CAP定理,是指分布式系统中的一致性(Consistency)、可用性(Availability)和分区容错性(Partitiontolerance)。CAP原则就是这三个要素最多只能同时达到两个点,不可能三者兼顾。但是,由于分区容错必须存在于分布式系统中,它只能在一致性和可用性上做出妥协。传统的DBMS,比如MySQL,其实是在主从架构下使用CA的组合来实现读写分离,牺牲了一定的一致性(主从延迟)。basetheory:baseavailable,基本可用,当一个分布式系统出现故障时,允许失去部分可用功能,以保证核心功能可用。softstate,软状态,允许系统中存在中间状态,这个状态不影响系统的可用性。eventuallyconsistent,最终一致性,系统的中间状态经过很短的时间后达到一致状态。场景如何解决以这样一个业务场景为例。系统A调用系统B的退款服务进行退款,系统A更改内部退款状态,然后调用系统C的短信服务通知用户。在这样的场景下,由于不可避免地存在不可靠的网络,A、B、C三个系统存在一致性问题,本地表针对以上场景设计了两张表:退款记录表、短信发??送表记录表和相应的薪酬工作。具体实现过程:添加退款记录表,状态为处理中。调用系统B的退款服务进行退款。更新退款记录状态为对应状态(成功/失败)。如果退款成功,则新增一条短信发送记录,记录状态为待发送。调用系统C的短信服务发送短信。更新短信发送记录为已发送。RefundCompensationJob,查询退款记录表中的处理记录,调用系统B的退款服务,退款处理成功:新增一条短信发送记录,记录状态为等待发送。调用系统C的短信服务发送短信。更新短信发送记录为已发送。SMSnotificationcompensationJob,在短信发送记录中查询需要发送的记录,调用系统C的短信服务:调用系统C的短信服务,发送短信。更新短信发送记录为已发送。注意:系统B和系统C需要根据调用者传递的uuid支持幂等。系统A、B和C会暂时不一致,但最终会一致。事务消息可以被认为是两阶段提交消息实现,以确保分布式系统中的最终一致性。事务性消息确保可以原子地执行本地事务的执行和消息的发送。但是由于事务消息的异步性,调用方无法获取到消费者的处理结果,适用于不关心对方返回结果/对方负责保证成功的情况的处理。针对上述场景,增加了两条事务消息来解决一致性问题。系统A通过发送交易消息与系统B和系统C进行交互。具体实现过程:发送退款交易消息。添加退款记录,状态为:处理中。提交退款交易消息。提供MQ交易回调:退款回调查询:如果有退款记录并且正在进行中则提交;否则,回滚。发送短信回调查询:如果有退款记录则提交,成功;否则,回滚。退款同步作业,查询退款记录表中的处理记录,调用系统B的退款查询接口同步状态,退款处理成功:发送短信交易消息更新退款记录成功提交短信交易消息相关理论两阶段提交两阶段提交是解决分布式事务问题的重要理论基础,但也存在明显的问题:阻塞问题,参与者向协调者发送协议消息后,会一直阻塞,直到收到提交或rollback,只能依赖coordinator的超时机制。协调器是单点问题。如果协调器失败,一些参与者将永远不会收到提交或回滚消息。为了解决两阶段提交的问题,出现了三阶段提交(Three-phasecommit):解决阻塞问题:将2PC中的第一阶段一分为二,提供一个CanCommit阶段,不锁定资源,可以大大降低阻塞概率。解决单点问题:在参与者端也引入了超时机制。DTPModelX/OpenDistributedTransactionProcessingDTP(DistributedTransactionProcessing)模型是一种软件架构,已经成为事务模型组件的事实行为标准。它允许多个应用程序共享多个资源管理器提供的资源,并允许它们的工作作为一个全局事务来协调:ApplicationProgram(AP),应用程序定义事务边界并指定构成事务的操作。ResourceManager(RM),资源管理器用来管理我们需要访问的共享资源,我们可以把它理解为关系数据库、文件存储系统、消息队列、打印机等。TransactionManager(TM),事务管理器是一个为事务分配标识符并监视事务执行的独立组件,负责事务完成和故障恢复。CommunicationResourceManager(CRM),通信资源管理器控制着一个或多个TM域之间的分布式应用程序的通信。XA规范:XA规范是X/Open的分布式事务处理(DTP)规范。该规范描述了全局事务管理器和本地资源管理器之间的接口。XA规范的目的是允许在同一个事务中访问多个资源(如数据库、应用服务器、消息队列等),从而可以跨应用程序维护ACID属性。XA使用两阶段提交来保证所有资源同时提交或回滚任何特定事务。XA规范描述了资源管理器必须做什么来支持事务访问。在TCCSaga的Saga模式中,分布式事务有多个参与者,每个参与者都是一个反向补偿服务,需要用户根据业务场景实现自己的正向操作和反向回滚操作。在分布式事务的执行过程中,各个参与者的前向操作是依次执行的。如果所有转发操作都执行成功,则分布式事务被提交。如果任何一个正向操作失败,分布式事务将返回执行之前参与者的反向回滚操作,回滚已提交的参与者,使分布式事务回到初始状态。Saga模式下的分布式事务通常由事件驱动,在参与者之间异步执行。Saga模式是一种长期的事务解决方案。Saga模式的优点是:一阶段提交本地数据库事务,无锁,高性能。参与者可以使用具有高吞吐量的事务驱动的异步执行。补偿服务是正向服务的“逆向”,易于理解和实施。缺点:Saga模式不能保证隔离,因为第一阶段已经提交了本地数据库事务,没有进行“reserve”动作。开源项目SeataSeata是一个开源的分布式事务解决方案,致力于在微服务架构下提供高性能易用的分布式事务服务。支持AT、TCC、Saga、XA四种模式,对微服务框架友好。如下图所示,Seata中共有三大模块,分别是TM、RM和TC。其中,TM和RM作为Seata的客户端与业务系统集成,TC作为Seata的服务器独立部署:TC:事务协调器,维护全局事务和分支事务状态,驱动全局事务提交或回滚.TM:TransactionManager,定义了全局事务的范围:启动全局事务,提交或回滚全局事务。RM:ResourceManager,为分支事务管理资源,与TC对话注册分支事务并报告分支事务的状态,驱动分支事务提交或回滚。在Seata中,分布式事务的执行流程:TM启动分布式事务(TM向TC注册全局事务记录)。根据业务场景安排数据库、服务等事务性资源(RM向TC报告资源准备情况)。TM结束分布式事务,事务阶段结束(TM通知TC提交/回滚分布式事务)。TC汇总事务信息并决定是提交还是回滚分布式事务。TC通知所有RM提交/回滚资源,第二阶段事务结束。①AT模式AT模式是一种非侵入式的分布式事务解决方案。AT模式下,用户只需要关注自己的“业务SQL”,用户的“业务SQL”作为第一阶段,Seata框架会自动生成事务的第二阶段提交和回滚操作.第一阶段:业务数据和回滚日志记录在同一个本地事务中提交,释放本地锁和连接资源。阶段2:提交是异步的并且完成得非常快。回滚通过单阶段回滚日志进行反向补偿。第一阶段,Seata会拦截“业务SQL”,首先解析SQL语义,找到“业务SQL”需要更新的业务数据,保存为业务数据更新前的“前像”,并然后执行“业务SQL”更新业务数据。业务数据更新后,保存为“残影”,最后生成行锁。以上操作均在一个数据库事务内完成,保证了第一阶段操作的原子性。②TCC模式是分布式全局事务,整体是两阶段提交模型。一个全局事务由多个分支事务组成。分支事务必须满足两阶段提交模型的要求,即每个分支事务需要有自己的:一阶段准备行为。两阶段提交或回滚行为。TCC模式,不依赖底层数据资源的事务支持:单阶段准备行为:调用自定义准备逻辑。两阶段提交行为:调用自定义提交逻辑。两阶段回滚行为:调用自定义回滚逻辑。所谓TCC模式,是指支持将自定义分支事务纳入全局事务管理。③Saga模式目前Seata提供的Saga模式是基于状态机引擎实现的。其机制是:使用状态图来定义服务调用的过程,生成一个json状态语言定义文件。状态图中的节点可以是服务调用,节点可以配置其补偿节点。状态图json由状态机引擎驱动执行。当异常发生时,状态引擎反向执行成功节点对应的补偿节点,回滚交易(异常发生时是否补偿也可由用户自行决定)。可实现服务编排需求,支持单选、并发、分流程、参数转换、参数映射、服务执行状态判断、异常捕获等功能。状态机引擎原理:图中的状态图是先执行stateA,再执行stateB,再执行stateC。“状态”的执行基于事件驱动模型。stateA执行完成后,会产生一条路由消息,放入EventQueue中。事件消费者将从EventQueue中获取消息并执行stateB。当整个状态机启动时,会调用SeataServer启动分布式事务,生成xid,然后将“状态机实例”启动事件记录到本地数据库。当执行到一个“状态”时,会调用SeataServer注册分支事务,生成branchId,然后将“状态实例”开始执行事件记录到本地数据库。当一个“状态”执行完成后,会记录“状态实例”执行结束事件到本地数据库,然后调用SeataServer上报该分支事务的状态。当整个状态机执行完成后,它会将“状态机实例”执行完成事件记录到本地数据库,然后调用SeataServer提交或回滚分布式事务。