概述
说到事务,大家一定会想到数据库的事务,那数据库事务是什么呢
就是指作为单个逻辑工作单元执行的多个数据库操作,要么全部成功,要么全部失败,同时必须满足ACID特性
- 原子性(A):事务必须是原子工作单位,不能继续分割,要么全部成功,要么全部失败
- 一致性(C):事务完成之后,所有的数据必须保持一致(或者说数据必须要和预期一样)
- 隔离性(I):由并发事务所做的修改必须与任何其他并发事务所做的修改隔离,互补影响
- 持久性(D):事务执行完成之后,对系统的影响是永久性的
ACID其实是针对单库多表的,那在微服架构下,可能会有多个数据库,比如订单和库存,假如订单和库存是两个数据库,当客户端创建订单时,就需要在订单数据库中创建订单信息,同时还要通知库存那边的数据减少对应商品的库存
这样存在一个问题就是:两个表的动态互不感知,如果创建订单成功了,但是扣减库存失败了,就会出现超卖现象,因为订单已经生成了,要对用户负责,除非公司出面解释,反过来,如果订单是失败的,库存减少了,同时也是有问题的, 库存一直在少,但是不见订单,你们说是不是问题呢
以上举例其实就是分布式事务的场景,准确来说,分布式事务是指事务的参与者(RM)、支持事务的服务器、资源服务器及事务管理器(TM)分别位于分布式系统的不同节点上
分布式事务问题的理论模型
分布式事务问题其实也叫分布式数据一致性问题,简单来说就是怎么做才能保证多个节点数据的一致性,分布式事务产生的核心原因在于存储资源的分布性,比如缓存数据的一致性,如何保证Mysql和Redis两者之间的数据保持一致呢?这就是问题,在平常开发中,在技术设计上,就得尽力的避免分布式事务的问题,因为不管什么解决方案,都会增加系统的负担
那说到这里,就提一下常见的解决方案:
1、X/Open分布式事务模型
是X/Open这个组织定义的一个针对分布式事务的标准,并且其中提出了两阶段提交(2PC)来保证了分布式事务的完整可靠性,如图:
①AP:表示应用程序
②RM:表示资源管理器,比如MySQL数据库
③TM:表示事务管理器,一般是说事务协调者,负责协调和管理事务,提供API接口或管理RM,可以理解为Spring中的Transaction Manager
看图知,角色和关系与本地事务的原理基本相同,唯一不同的在于,如果此时RM表示数据库,那么TM需要能够管理多个数据库事务,基本的逻辑是这样的:
①配置TM,把多个RM注册到TM中,相当于TM注册了RM作为一个数据源
②AP从TM管理的RM中获取连接,如果RM是数据库则获取JDBC连接信息
③AP向TM发起一个全局事务,生成全局事务ID(XID),它会通知所有的RM
④AP通过图中的第二步获得连接直接操作RM完成数据的CURD,此时,AP在每次操作是会把XID传递给RM
⑤AP结束全局事务,TM会通知所有RM全局事务已结束
⑥根据各个RM的事务执行结果,执行提交或者回滚操作
上面提到了一个全局事务的概念,意思是说在原本单机事务下,会存在跨库事务的可见性问题,导致无法实现多个节点的全局控制,而TM就是一个全局事务管理器,可以管理多个资源管理器的事务,TM最终会根据各个事务的执行结果进行提交或回滚,如果注册的所有分支事务中任何一个节点的事务执行失败了,为了保证数据的一致性,TM会触发各个RM事务的回滚事件
但是需要注意的是:TM个多个RM之间的事务控制,是基于XA协议来完成的,XA协议是啥呢,他是X/Open提出的分布式事务处理的一个规范,也就是分布式事务处理的工业标准,他定义了xa_和ax_系列的函数原型及功能描述、约束等,现在啊,很多数据库都实现了XA接口,比如Oracle、MySQL等等,总体的来意看一下下图:
2、两阶段提交协议
在上面的图中,其实能够发现一个现象:多个RM的事务管理都是TM实现的,那实现逻辑里会涉及到两个阶段的提交,第一阶段是事务的准备阶段,第二个是事务的提交或回滚阶段,这两个阶段都是由事务管理器发起的,基本执行流程是这样的:
- 准备阶段:TM通知RM准备分支事务,记录事务日志,并告知事务管理器的准备结果
- 提交/回滚阶段:如果所有的RM在准备阶段都返回成功了,那TM会向所有的RM发起事务提交,完成数据的CURD,反之但凡有一个RM出现失败,TM就会执行回滚
这种提交方式,将一个事务的处理过程分为投票和执行两个阶段,优点在于全面而充分的考虑到了分布式环境下的不可靠因素,并且过程还采用了非常简单的提交方式就把原本系统环境不可靠导致食物提交失败的概率降到最低,而不是完全避免哦,当然了程序总是有缺点的,两阶段提交也是,存在一下几个缺点:
- 同步阻塞:图中的,所有RM都是事务阻塞的,对于任何一次指令都必须要有明确的响应才能进入下一步,这个时候资源会被锁定占用,处于一个阻塞状态
- 过于保守:任何一个节点失败都会导致数据回滚
- TM单点故障:如果TM在第二阶段出现故障,那么其他的RM就会处于锁定状态,状态是一直的
- 脑裂导致数据不一致:在第二阶段中,TM想RM发送调请求后,发生了网络问题导致部分RM接收到了提交指令,拿到提交指令的RM会继续执行事务提交,那没有接收到提交指令的RM就没有下文了,这个时候就会出现数据不一致的问题
3、三阶段提交协议
三阶段是两阶段的改进版本,他利用超时机制很巧妙的解决了两阶段中同步阻塞的问题,具体的流程是:
- CanCommit(询问阶段): TM向RM发送事务执行请求,询问是否可以完成指令,RM只需要回答是或不是就可以了,不需要做真正的事务操作,这个阶段会有超时终止机制,询问之后,在规定时间内没有响应,就终止
- PreCommit(准备阶段):TM会根据RM返回的结果,来判断是否提交,只有当所有参与者都返回成功,TM才会向所有RM发送提交请求,RM收到请求后写redo和undo日志,执行事务操作但不提交事务,然后返回ACK相应等待TM下一次通知,如果询问阶段RM返回的是失败的结果,TM就会向所有的RM发送中断请求
- DoCommit(提交或回滚阶段):这个阶段一般会存在两种结果,是根据上面的准备阶段的执行结果来决定当前阶段的执行方式,如果每个RM在准备阶段都返回成功了,那么TM会向所有RM发起事务提交指令,反之,只要有一个RM失败,那么TM就会终止指令,执行回滚操作
流程如图:
对比两阶段提交的有点:
- 增加了一层CanCommit阶段,用于询问所有RM是否可以执行事务操作并响应结果,好处是可以尽早发现无法执行操作而终止后续的行为
- 在准备阶段之后,TM和RM都引入了超时机制,只要一超时,TM和RM会继续提交事务,并且认为处于成功状态,因为在这种情况下事务默认为成功的可能性相对比较大
其实只要出现超时,还会有一定几率出现数据不一致的情况,只是这种几率会很小,当然三阶段最大的好处就是用超时机制来避免资源的永久锁定
不管是两阶段还是三阶段提交协议,都是为了解决分布式环境下数据一致性的问题,其实我们也可以利用中间件来灵活调整,比如使用ZK集群,它里面保证数据一致性就用到了优化版的两阶段协议,优化的地方在于:他不需要所有RM在第一阶段返回成功才提交事务,而是利用少数服从多数的投票机制来完成数据的提交和回滚
3、CAP和BASE理论
上面提到的两阶段和三阶段是XA协议解决分布式数据一致性问题的基本原理,但有个缺点就是这两个方案保证了数据的一致性,但可用性无法保证,所以,保证可用性的理论模型也就出现了
1、CAP定理
又叫布鲁尔定理,简单来说就是分布式系统中不可能同时满足CAP这仨个基本需求,最多只能同时满足俩
- C:数据在多个副本中要保持强一致
- A:系统对外提供的服务必须一致处于可用状态,否则出现任何故障,客户端都有可能会崩溃。必须要在任何故障下,客户端都在合理的时间内获得服务器的非错误响应
- P:在分布式系统中遇到任何网络分区故障,系统仍然能够正常对外提供服务
CAP必须要保证分区容错性,又同时不能满足三个只能满足两个,所以就只能是CP或AP,原因是网络通信也有不靠谱的时候,如果不满足P这个条件,可能在出现网络故障时就无法保证系统能不能够对外正常提供服务,所以P是必须存在的
- AP:相当于放弃了强一致性,实现了最终一致,市面上很多互联网公司的首选
- CP:放弃了高可用,实现了强一致性,前面说的两阶段和三阶段就是采用这个方案,可能会导致的问题就是用户完成一个操作之后会等待比较长的一段时间
2、BASE理论
是与CAP定理相反的一种思想,BASE核心就是通过放弃强一致性来获得高可用,它主要有三个特性:
- Basically Available(基本可用):分布式系统出现故障时,允许损失一部分功能的可用性,以此来保证核心功能的可用
- Soft State(软状态):允许系统中的数据存在中间状态,这个状态不影响系统的可用性,也就是允许系统中不同节点的数据副本之间的同步存在延时
- Eventually Consistent(最终一致性):中间状态的数据在经过一段时间之后,会达到一个最终的数据一致性
BASE理论没有要求数据的强一致性,而是运行数据一段时间内不一致,然后数据会在某个时间点自动实现一致,所以大部分都会采用这个理论来实现数据的一致
举个典型的例子:比如在某宝发起一个支付,这个理论就是用不需要等待支付的结果,系统会先返回一个支付处理中的状态给到用户,对于用户来说,他可以从订单列表查看支付结果,对于系统来说,支付处理完成之后,再更新订单的支付状态就好了,这个场景下,订单的支付状态和第三方的支付状态存在短期的数据不一致,但是对于用户来说却是一个很好的产品体验
最后
以上就是开放钻石为你收集整理的分布式事务系列之入门分布式事务问题的理论模型的全部内容,希望文章能够帮你解决分布式事务系列之入门分布式事务问题的理论模型所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复