分布式事务-01:分布式事务产生原因及相关概念
图片来源:pixabay.com
摘要:本文主要介绍应用的架构演进,分布式事务产生的原因,以及分布式事务相关的概念。
本文目录:
架构演进
分布式事务产生的原因
分布式事务的概念
XA规范
1.架构演进
随着互联网的发展,用户基数变得越来越大,网站应用的规模也不断扩大, 常规的单体应用和垂直应用架构已无法应对, 分布式服务架构以及流动计算架构正在成为一种趋势。这里借用dubbo官网的一张图来介绍下架构演进之路。
图片来源:dubbo
1.1单一应用架构
当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本。此时,用于简化增删改查工作量的数据访问框架(ORM)是关键。
1.2垂直应用架构
当访问量逐渐增大,单一应用增加机器带来的加速度越来越小,将应用拆成互不相干的几个应用,以提升效率。此时,用于加速前端页面开发的Web框架(MVC)是关键。
1.3分布式服务架构
当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。此时,用于提高业务复用及整合的分布式服务框架(RPC)是关键。
1.4流动计算架构
当服务越来越多,容量的评估,小服务资源的浪费等问题逐渐显现,此时需增加一个调度中心基于访问压力实时管理集群容量,提高集群利用率。此时,用于提高机器利用率的资源调度和治理中心(SOA)是关键。
2.分布式事务产生原因
当架构由单体向多服务演进时,整个系统的可靠性变得难以控制,在单体服务中,一个请求的整个周期,从请求到响应结果,都是在一台服务器上,本地事务就可以保证一组数据操作的一致性。
在微服务中,从请求到响应,之间可能跨越多台服务器,多个数据库,如下图,假设有个金融系统,拆分为了多个微服务,每个微服务有自己的数据库,我们现在发起借款这个操作,需要用到以下几个微服务:
这个借款操作,可以抽象概括为以下几个步骤:
1.用户发起借款,调用借款服务的借款接口;
2.借款同时,在授信服务里 减少授信额度;
3.借款同时,在资金服务里 增加账户余额;
4.借款同时,在日志服务里 增加流水记录;
......
这里只是假设,实际金融项目中的借款这个动作发生的事情远比上图复杂。
由于每个服务都是单独部署的,在理想状态下,上述的操作,可以顺利得以执行。
如果中间有服务发生故障了呢?
假设一个常见的场景,资金服务由于没有合理使用线程池和连接池,现在内存爆掉,无法正常处理请求,那么,这个链路成为了如下的样子:
1.用户发起借款,调用借款服务的借款接口;
2.借款同时,在授信服务里 减少授信额度;
3.借款同时,在资金服务里 增加账户余额;x
4.借款同时,在日志服务里 增加流水记录;
......
此时,由于是在多个服务中,本地的Transaction已经无法应对这个情况了,现在系列操作导致了上述的情况,用户的授信额度减少了,流水也记录了,但是用户没有收到钱。
为什么会这样呢?带着问题,我们看下,如果是在单体服务中,会怎么样呢?
还是上面的场景,但是我们现在是单体服务,我们把上面的每个服务看成是同一个数据库不同的表,那么这个借款操作,等于就是在一个接口的实现方法中,操作了不同的表,然后添加Spring的事务。在操作每个表都成功时,如下图所示,整个操作成功,数据一致性得到了保障。
如果其中一个表操作失败,会怎么样呢?
由于有本地事务的控制,当其中一张表操作失败时,整个操作都会回滚。这样,整个借款就会失败,减少授信额度,增加账户流水,增加流水记录,这几个步骤都会回滚。
上述问题,就是一个典型的分布式事务问题。接下来,了解一下分布式事务的一些概念。
3.分布式事务的概念
分布式事务:是指会涉及到操作多个数据库的事务,可以理解为将对同一库事务的概念扩大到了对多个库的事务,目的是为了保证分布式系统中的数据一致性。
通俗来讲,就是一次大的操作由不同的小操作组成,这些小的操作分布在不同的服务器上,且属于不同的应用,分布式事务需要保证这些小操作要么全部成功,要么全部失败。本质上来说,分布式事务就是为了保证不同数据库的数据一致性。
在分布式系统中,各个节点之间在物理上相互独立,通过网络进行沟通和协调。由于存在事务机制,可以保证每个独立节点上的数据操作可以满足ACID,但是,相互独立的节点之间无法准确的知道其他节点中的事务执行情况。所以从理论上讲,两台机器理论上无法达到一致的状态。如果想让分布式部署的多台机器中的数据保持一致性,那么就要保证在所有节点的数据写操作,要不全部都执行,要么全部的都不执行。但是,一台机器在执行本地事务的时候无法知道其他机器中的本地事务的执行结果,所以他也就不知道本次事务到底应该commit还是 roolback,所以,常规的解决办法就是引入一个“协调者”的组件来统一调度所有分布式节点的执行。
分布式事务处理的关键是:必须有一种方法可以知道事务在任何地方所做的所有动作,提交或回滚事务的决定必须产生统一的结果:全部提交或全部回滚 。
4.XA规范
X/Open 组织(即现在的 Open Group )定义了分布式事务处理模型。包括三个组件:AP,TM,RM 和两个协议:XA,TX。
AP(Application Program):也就是应用程序,可以理解为使用DTP的程序。
RM(Resource Manager):资源管理器,这里可以理解为一个DBMS系统,或者消息服务器管理系统,应用程序通过资源管理器对资源进行控制。
TM(Transaction Manager):事务管理器,负责协调和管理事务,提供给AP应用程序编程接口以及管理资源管理器。
XA协议:应用或应用服务器与事务管理之间通信的接口。
TX协议:全局事务管理器与资源管理器之间通信的接口。
一般,常见的事务管理器( TM )是交易中间件,常见的资源管理器( RM )是数据库,常见的通信资源管理器( CRM )是消息中间件。
通常把一个数据库内部的事务处理,如对多个表的操作,作为本地事务看待,数据库的事务处理对象是本地事务,而分布式事务处理的对象是全局事务。
全局事务,是指分布式事务处理环境中,多个数据库可能需要共同完成一个工作,这个工作即是一个全局事务,例如,一个事务中可能更新几个不同的数据库,对数据库的操作发生在系统的各处但必须全部被提交或回滚。此时一个数据库对自己内部所做操作的提交不仅依赖本身操作是否成功,还要依赖与全局事务相关的其它数据库的操作是否成功,如果任一数据库的任一操作失败,则参与此事务的所有数据库所做的所有操作都必须回滚。
一般情况下,某一数据库无法知道其它数据库在做什么,因此,在一个 DTP (Distributed Transaction Processing )环境中,事务管理器(TM)是必需的,由它通知和协调相关数据库的提交或回滚。而一个数据库只将其自己所做的操作(可恢复)映射到全局事务中。
XA 就是 X/Open DTP 定义的事务管理器(TM)与数据库(RM)之间的接口规范(即接口函数),事务管理器用它来通知数据库事务的开始、结束以及提交、回滚等。XA 接口函数由数据库厂商提供。
与其相忘江湖,不如点赞关注