消息服务框架(MSF)应用实例之分布式事务三阶段提交协议的实现

简介:

一,分布式事务简介

在当前互联网,大数据和人工智能的热潮中,传统企业也受到这一潮流的冲击,纷纷响应国家“互联网+”的战略号召,企业开始将越来越多的应用从公司内网迁移到云端和移动端,或者将之前孤立的IT系统联网整合,或者将原来厚重的企业应用拆分重组,独立成一个个轻量级的应用对外提供服务,这对传统的业务处理的数据一致性,带来了严重的挑战,我们已经身处一个分布式的计算环境,分布式事务的需求越来越普遍。

举一个例子,某行业电商网站经过几年的发展,业务数据累积越来越多,查询越来越慢。经过内部评审分析,认为系统的瓶颈就是数据库压力过大,如果要解决这问题,必须分表分库,比如将订单,商品,用户分布到不同的数据库去,但这样随之带来一个问题,原来处理业务的时候使用的是本地事务,分库后就需要使用分布式事务了。

那么应该如何实现分布式事务呢?

这里我们需要明确一点,并非数据库天然就是分布式的在执行操作的,事务都是在一个数据库实例上进行的,如果要执行一个分布式事务的操作,那么就需要协调多个分散的数据库上执行的事务操作。所以在分布式事务中,有2个概念:

l  Distributed Transaction Resource Owner (简称DTR):

n  --分布式事务资源服务器,拥有事务资源的服务器,如绝大部分关系数据库,一些消息队列,或者一些能够执行类似事务操作的应用。

l  Distributed Transaction Coordinate Controller (简称DTC):

n  --分布式事务协调控制器,它协调控制分布式事务环境中的事务资源服务器,发送指令给它们并且处理事务资源服务器返回的结果。

 

二,分布式事务的实现层面

 

在分布式事务的具体实现层面,可以在数据库层直接实现,也可以在应用服务层面实现。如果是在应用服务层面实现,本质上它也可能是调用本地的数据库事务。

下面是DTR与DTC的拓扑关系图:

基于关系数据库层面接口实现的分布式事务

基于数据库的分布式事务,一般在应用程序的数据层调用系统的分布式事务组件,应用程序执行本地事务的时候,先选举出一个分布式事务协调器,然后协调器来协调各个本地事务的执行。由于是在应用程序的数据层进行的调用,所以它对远程数据库的操作是在本地进程内的。如果你的应用部署在多台服务器上,那么在每一台操作数据库的应用服务器上都要安装运行分布式事务协调器服务。

基于应用服务层面实现的分布式事务

 

基于应用服务层面的分布式事务,是在应用服务层面进行的事务控制,它同样会有分布式事务协调控制器,和事务资源服务器。与基于数据库层面的分布式事务不同,事务的类型支持更广泛,比如消息队列访问,文件写入或者具有补偿操作的业务应用程序,都可以成为事务资源,并且不要求这些事务资源本身支持分布式事务。举个例子,事务资源A是Windows上的SQLSERVER数据库,事务B是Linux上的MySQL数据库,这时候事务B就没法使用Windows上的事务协调控制器MSDTC了。而基于服务层面的分布式事务,可以解决这个问题。

三,分布式事务的2阶段提交协议(2PC)

第一阶段(1PC):提交投票阶段

协调器向事务资源服务器发出 CanCommit 的是否可以提交事务的询问指令,事务资源服务器收到此指令后,准备好要提交的事务资源,再向协调器回复 YES;如果没有准备好,比如执行事务中的操作出现了错误,应该回复 NO.如果某DTR无法回复,DTC也认为该DTR的结果是NO.

第一阶段,全部回复为YES,代表各个事务资源服务器均已经准备好了提交。

 

第一阶段,事务资源服务器DTR-2回复为NO,如果DTC等待DTR-2超过设定时间都没有得到回复,或者DTR-2与DTC断开了连接,也认为DTR-2的结果是NO

 

第二阶段(2 PC):提交或终止阶段

协调器统计所有事物资源服务器的回复数量,如果全部回复为YES,则向所有事物资源服务器发出Commit指令,否则,发出Abort指令。资源服务器收到指令后,执行相应的操作。

二阶段提交事务的数据不一致问题

在第二阶段(2PC),如果DTR没有收到DTC的指令改怎么办呢?

如果等到超时都没有收到DTC的指令,DTR处于“可以提交”或者“不可以提交”的双重状态,也就是提交状态不可知。假设DTR1没有收到DTC的提交指令或者撤销指令,DTR1可以假设DTR2也不会收到指令,因为此时大概率是DTC宕机或者网络整体不良,那么DTR1最佳的做法是回滚事务。

但是,如果仅仅是DTR1受网络影响没有收到提交指令,而DTR2收到了提交指令,那么DTR1回滚事务,DTR2提交了事务,整个分布式事务就是失败的,数据发生了不一致。

因此,2阶段提交的分布式事务不是高可靠的分布式事务控制模型,需要在事务资源的提交环节做更多的验证,这便是3阶段提交的分布式事务。

 

不过,对于大部分系统,2阶段提交的分布式事务已经能够满足应用了,因为通常情况下,都是基于数据库应用层实现的分布式事务,并且各个事务资源节点都在同一个局域网内,发生网络不稳定的概率非常小,并且现在不少数据库都会做高可靠性的数据库集群,发生宕机的可能性也非常小,最终出现数据不一致的概率也就非常小了。

 

如果系统的应用环境不能满足上面说的任何一个条件,即分布式事务的控制不是在数据库应用层,子系统不在一个局域网,或者数据库没有做高可靠的集群,并且对于系统的事务一致性要求非常高,那么应该使用3阶段提交协议来实现分布式事务。

四,分布式事务的3阶段提交协议(3PC)

对2阶段提交协议的分析我们发现,2PC的事务提交阶段状态是不确定的,整个事务容易出现不一致的情况。所以,我们队2PC的提交阶段,进一步拆分成“预提交”阶段和提交阶段,增加事务提交状态的确认过程。

第一阶段(1PC):提交投票阶段

协调器向事务资源服务器发出 CanCommit 的是否可以提交事务的询问指令,事务资源服务器收到此指令后,准备好要提交的事务资源,再向协调器回复 YES;如果没有准备好,比如执行事务中的操作出现了错误,应该回复 NO.如果某DTR无法回复,DTC也认为该DTR的结果是NO.

该阶段的处理过程跟2阶段提交协议的第一阶段是一样的,处理流程图参考前面,此略。

 

第二阶段(2 PC):预提交或终止阶段

预提交事务

协调器(DTC)统计所有事务资源服务器(DTR)的回复数量,如果全部回复为YES,则向所有事物资源服务器发出PreCommit指令,否则,发出Abort指令。资源服务器收到指令后,执行相应的操作。

在第二阶段,如果DTR收到PreCommit指令,则向DTC回复ACK消息,表示收到了指令,准备提交,接着,进入第三阶段,等待最终的提交指令。

 

终止事务

在第二阶段,如果在第一阶段有节点异常,DTC发出撤销指令,DTR收到了撤销指令,那么它执行回滚本地事务的操作。如果由于网络原因,某个DTR一直等到超时都没有收到PreCommit指令,那么它执行Abort撤销指令,回滚本地事务。

 

第三阶段(3 PC):提交或终止阶段

提交分布式事务

协调器(DTC)统计所有事务资源服务器(DTR)在第二阶段的回复数量,如果全部回复为ACK,则向所有DTR发出Commit指令。DTR收到指令后,执行事务提交操作,并返回Commit Done消息,DTC收到此消息,结束整个分布式事务过程。

 

 

回滚分布式事务

协调器(DTC)统计所有事务资源服务器(DTR)在第二阶段的回复数量,如果未收到全部回复为ACK,则它认为有节点可能出现了网络故障,此节点没有收到PreCommit指令或者虽然收到了却没有回复ACK,测试DTC应该向所有DTR节点发出撤销指令。各DTR收到撤销指令后,回滚本地事务,然后回复消息,DTC完成本次事务过程。

 

三阶段提交事务也并不完美

考察第3阶段的提交分布式事务的情况,DTR1收到了Commit指令,但是由于网络原因,DTR2没有收到此指令,那么DTR2是提交本地事务还是回滚本地事务?

站在DTR2的角度,它在本阶段可能收到Commit指令,也可能收到Abort指令,那么它既可以提交本地事务也可以回滚本地事务,两种操作是不确定的,所以,3阶段提交协议,仍然不是完美的,不能百分之百保证数据的最终一致性。

既然3阶段提交协议仍然有不确定性,那么相比2阶段提交协议有什么意义呢?

 

仔细想下,DTR2已经进入第3阶段了,那么肯定其它DTR都进入了第3阶段,而进入第3阶段的前提是各DTR节点都收到过PreCommit指令,都是已经准备好提交只等最后的提交指令了,否则各节点在第二阶段应该收到撤销指令,不会再进入第三阶段。既然各DTR节点都进入了第三阶段,它们都准备好提交事务了,那么即使没有收到最终的Commit指令,DTC发出Commit指令也是大概率的。所以,从概率上讲,如果在第三阶段,DTR没有收到Abort撤销指令,也没收到Commit提交指令,那么它默认应该指向Commit指令,提交本地事务。相比第二阶段某DTR节点没有收到指令而认为应该收到PreCommit指令的概率,要大得多。

 

关于第三阶段没有收到指令而应该大概率执行Commit指令的问题,理解起来可能有点困难,我给同事讲的时候大部分同事也难以理解,可能是我表述的问题,大家有更好的解释方式,欢迎交流,不胜感激!

 

5,实现 3阶段提交的分布式事务

本文将介绍一个基于服务层面而不是数据库层面的,3阶段提交的分布式事务中间件的设计开发过程。这个中间件必须解决下面几个问题:

l  通信组件—分布式事务控制器(DTC),分布式事务资源服务器(DTR)都是独立的服务,这些服务部署在不同的通信节点,它们之间需要进行可靠的网络通信,因此通信组件是基础;

l  数据访问组件—提供基础的数据读写操作,并且能够操作本地事务。

l  服务组件—将DTC,DTR的功能代码编写为相应的SOA服务组件

l  关系数据库—具有事务功能的关系数据库,可以是嵌入式的本地数据库,比如SQLite,也可以是服务器客户机模式的网络数据库,比如SQLSERVER。

 

各组件的关系图如下:

 

PDF.NET的消息服务框架(MSF)具有开发服务组件基础的接口和一套消息通信组件,同时还有一个服务容器,可以承载本篇文章说的分布式事务控制器DTC,分布式事务资源服务DTR这些服务应用,同时PDF.NET还有一个强大的数据访问组件 PDF.NET SOD,下一篇文章,我们将来具体讨论基于MSF和SOD的3阶段分布式事务应用的实现过程,它的源码已经发布在 https://github.com/bluedoctor/MSF-DistTransExample ,大家可以先睹为快。

 


    本文转自深蓝医生博客园博客,原文链接:http://www.cnblogs.com/bluedoctor/p/8146604.html,如需转载请自行联系原作者




相关实践学习
消息队列+Serverless+Tablestore:实现高弹性的电商订单系统
基于消息队列以及函数计算,快速部署一个高弹性的商品订单系统,能够应对抢购场景下的高并发情况。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
相关文章
|
2月前
|
Java 数据库
在Java中使用Seata框架实现分布式事务的详细步骤
通过以上步骤,利用 Seata 框架可以实现较为简单的分布式事务处理。在实际应用中,还需要根据具体业务需求进行更详细的配置和处理。同时,要注意处理各种异常情况,以确保分布式事务的正确执行。
|
2月前
|
消息中间件 Java Kafka
在Java中实现分布式事务的常用框架和方法
总之,选择合适的分布式事务框架和方法需要综合考虑业务需求、性能、复杂度等因素。不同的框架和方法都有其特点和适用场景,需要根据具体情况进行评估和选择。同时,随着技术的不断发展,分布式事务的解决方案也在不断更新和完善,以更好地满足业务的需求。你还可以进一步深入研究和了解这些框架和方法,以便在实际应用中更好地实现分布式事务管理。
|
21天前
|
存储 监控 数据可视化
常见的分布式定时任务调度框架
分布式定时任务调度框架用于在分布式系统中管理和调度定时任务,确保任务按预定时间和频率执行。其核心概念包括Job(任务)、Trigger(触发器)、Executor(执行器)和Scheduler(调度器)。这类框架应具备任务管理、任务监控、良好的可扩展性和高可用性等功能。常用的Java生态中的分布式任务调度框架有Quartz Scheduler、ElasticJob和XXL-JOB。
314 66
|
14天前
|
数据采集 人工智能 分布式计算
MaxFrame:链接大数据与AI的高效分布式计算框架深度评测与实践!
阿里云推出的MaxFrame是链接大数据与AI的分布式Python计算框架,提供类似Pandas的操作接口和分布式处理能力。本文从部署、功能验证到实际场景全面评测MaxFrame,涵盖分布式Pandas操作、大语言模型数据预处理及企业级应用。结果显示,MaxFrame在处理大规模数据时性能显著提升,代码兼容性强,适合从数据清洗到训练数据生成的全链路场景...
47 5
MaxFrame:链接大数据与AI的高效分布式计算框架深度评测与实践!
|
3天前
|
人工智能 分布式计算 大数据
MaxFrame 产品评测:大数据与AI融合的Python分布式计算框架
MaxFrame是阿里云MaxCompute推出的自研Python分布式计算框架,支持大规模数据处理与AI应用。它提供类似Pandas的API,简化开发流程,并兼容多种机器学习库,加速模型训练前的数据准备。MaxFrame融合大数据和AI,提升效率、促进协作、增强创新能力。尽管初次配置稍显复杂,但其强大的功能集、性能优化及开放性使其成为现代企业与研究机构的理想选择。未来有望进一步简化使用门槛并加强社区建设。
31 7
|
28天前
|
分布式计算 大数据 数据处理
技术评测:MaxCompute MaxFrame——阿里云自研分布式计算框架的Python编程接口
随着大数据和人工智能技术的发展,数据处理的需求日益增长。阿里云推出的MaxCompute MaxFrame(简称“MaxFrame”)是一个专为Python开发者设计的分布式计算框架,它不仅支持Python编程接口,还能直接利用MaxCompute的云原生大数据计算资源和服务。本文将通过一系列最佳实践测评,探讨MaxFrame在分布式Pandas处理以及大语言模型数据处理场景中的表现,并分析其在实际工作中的应用潜力。
71 2
|
2月前
|
存储 Java 关系型数据库
在Spring Boot中整合Seata框架实现分布式事务
可以在 Spring Boot 中成功整合 Seata 框架,实现分布式事务的管理和处理。在实际应用中,还需要根据具体的业务需求和技术架构进行进一步的优化和调整。同时,要注意处理各种可能出现的问题,以保障分布式事务的顺利执行。
121 6
|
2月前
|
数据库
如何在Seata框架中配置分布式事务的隔离级别?
总的来说,配置分布式事务的隔离级别是实现分布式事务管理的重要环节之一,需要认真对待和仔细调整,以满足业务的需求和性能要求。你还可以进一步深入研究和实践 Seata 框架的配置和使用,以更好地应对各种分布式事务场景的挑战。
60 6
|
2月前
|
消息中间件 运维 数据库
Seata框架和其他分布式事务框架有什么区别
Seata框架和其他分布式事务框架有什么区别
42 1
|
2月前
|
缓存 NoSQL PHP
Redis作为PHP缓存解决方案的优势、实现方式及注意事项。Redis凭借其高性能、丰富的数据结构、数据持久化和分布式支持等特点,在提升应用响应速度和处理能力方面表现突出
本文深入探讨了Redis作为PHP缓存解决方案的优势、实现方式及注意事项。Redis凭借其高性能、丰富的数据结构、数据持久化和分布式支持等特点,在提升应用响应速度和处理能力方面表现突出。文章还介绍了Redis在页面缓存、数据缓存和会话缓存等应用场景中的使用,并强调了缓存数据一致性、过期时间设置、容量控制和安全问题的重要性。
53 5