设为首页 加入收藏

TOP

即时消息服务框架(iMSF)应用实例之分布式事务三阶段提交协议的实现(一)
2019-09-17 19:05:47 】 浏览:52
Tags:即时 消息 服务 框架 iMSF 应用 实例 分布式 事务 阶段 提交 协议 实现

一,分布式事务简介

在当前互联网,大数据和人工智能的热潮中,传统企业也受到这一潮流的冲击,纷纷响应国家“互联网+”的战略号召,企业开始将越来越多的应用从公司内网迁移到云端和移动端,或者将之前孤立的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):提交或终止阶段

提交分布式

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇谈缓存和Redis 下一篇海量大数据分布式数据库解决方案..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目