分布式事务
-
事务的概念,我们第一想到的应该是数据库的事务。所谓数据库事务就是只作为单个逻辑工作单元执行多个数据库操作的时候,数据库需要保证要么都成功,要么都失败,它必须满足ACID特性,即:
- 原子性(Atomicity):事务必须是原子工作单元,不可继续分割,要么全部成功,要么全部是吧
- 一致性(Consistency):事务完成时候,所有数据都必须保持一致
- 隔离性(Isolation):由并发事务所做的修改必须与任何其他并发事务所做的修改隔离
- 持久性(Durability):事务执行完成后,他对于系统的影响必须是永久代
-
上面几点是针对单个数据库需要满足的特性。在微服务架构下,随着业务服务的拆分以及数据库的拆分,会存在以下这种场景,订单表与库存是在两个微服务下独立的数据库,当客户端发起一个订单的时候,需要在的那个的服务对数据库进行创建订单,同时库存也需要修改,这两个修改都是通过RPC通信调用。如下图:
-
在以上场景中,原本单库的操作变成多个数据库结合的事务操作,由于每个数据库事务执行情况只有本数据库知道,这样会导致订单库存数据与订单数据不一致的问题,比如创建订单成功但是扣减库存失败,会导致超卖商品的问题,这就是所谓的分布式事务问题 。
分布式事务理论模型
- 分布式事务问题也就是保证分布式数据库数据一致性问题,简单说我们应该如何在分布式的场景下保证多个节点的数据一致性。分布式事务产生的核心原因在于存储资源的分布性,比如我们微服务情况下的分库分表,或者多存储媒介mySql,Redis等数据库的数据一致性,实际应用中,但是应该尽可能从设计层面避免分布式事务问题,因为任何一种解决方案都会增加系统复杂性。
X/Open分布式事务模型
- X/Open DTP(X/Open Distributed Transaction Processing Reference Model)是X/Open这个组织定义的一套分布式事务的标准。这个标准提出了使用两阶段提交(2PC,Two-Phase-Commit)来保证分布式事务的完整性。如下图X/Open包含如下几个角色:
- AP:application 表应用程序
- RM:Resource Manager 资源管理器,比如数据库
- TM:Transaction Manager 表示事务管理器,一般指事务协调者,负责协调和管理事务,提供AP编程接口或管理RM,可以理解为Spring中提供的Transaction Manager。
-
如上的角色与关系与本地事务的原理基本一样,唯一的不同在于,如果RM代表数据库,那么TM需要能够管理多个数据库的事务,如下:
- 配置TM,将多个RM注册到TM上,相当于TM注册RM作为数据源。
- AP从TM管理的RM中获取连接,如果RM是数据库则获取JDBC连接
- AP向TM发起一个全局事务,生成全局事务ID(XID),XID会通知各个RM
- AP通过第二步获得的连接直接操作RM完成数据库操作。这时候,AP的每次操作会吧XID传递给RM
- AP结束全局事务,TM会通知各个RM全局事务结束
- 根据各个RM的事务执行结果,执行提交或者回滚操作。
-
我们用如下流程图来解释,实际上这里涉及全局事务概念。也就是说在原本单机事务下,会存在跨数据库事务的可见性问题,导致无法实现多借点事务的全局可控。而TM就是一个全局事务管理器,他可以管理多个资源管理器的事务。TM最终会根据各个分支事务的执行结果进行提交或者回滚。
- 如上图所示,我们需要注意的是,TM和多个RM之间的事务控制,是基于XA协议(XA Speification)来完成的,XA协议是X/Open踢出的分布式事务处理规范,也是分布式事务处理的工业标准,定义了xa_ 和 ax_系列的函数原型以及功能描述,约束等。现在的主流数据库Oracle,MySql,DB2都实现了XA接口,所以他们都可以作为RM。
两阶段提交协议
- 我们上面实现中RM实现了多个RM的事务管理,实际上会涉及到两个阶段的提交,第一节点,事务的准备阶段,第二阶段是事务的提交或者回滚阶段。这两个阶段都是由事务管理器发起的。两个阶段提交协议的流程如下。
- 准备阶段:事务管理器(TM)通知资源管理器(RM)准备分支事务,记录事务日志,并告知事务管理器的准备结果。
- 提交/回滚阶段:如果所有资源管理器(RM)在准备阶段都明确返回成功,则事务管理器(TM)向所有资源管理器(RM)发起事务提交指令完成数据变更。反之,如果任何一个资源管理器(RM)明确返回失败,则事务管理器(TM)会向所有资源管理器(RM)发送事务回滚指令。完整的执行流程如下图。
- 两阶段提交将一个事务的处理过程分离两个过程,优点在于充分考虑到分布式系统的不可靠因素,并且采用非常简单的方式(两阶段提交)就把由于系统不可靠而导致的事务提交失败的概率降低到最小。当然也并不是完美,有如下缺陷:
- 同步阻塞:从上图流程,所有参与者RM都必须是事务阻断类型的,对应任何一次指令都必须有明确的响应才可以进行下一步,期间其他的请求都会被阻塞,占用的资源会被锁定。
- 过于保守:任何节点失败都会导致数据回滚。
- 事务协调者的单点故障:如果协调者在第二阶段出现故障,那么其他的参与者RM,会一直处于锁定状态。
- 脑裂,导致数据不一致问题:在第二阶段中,事务协调者向所有参与者RM发送commit请求后,发送局部网络异常导致只有一部分参与者RM接受到了commit请求,这部分参与者会发起commit,但是没有收到commit请求的节点由于事务无法提交,导致数据出现不一致问题。
三阶段提交
- 三阶段提交协议是两阶段提交协议的改进版本,他利用超时机制解决了同步阻塞问题。三阶段提交协议的具体描述如下。
- CanCommit(询问阶段):事务协调者向参与者发送事务执行请求,询问是否可以完成指令,参与者只需要回答是或者否,不需要真正做事务的操作,这个阶段会有超时终止机制。
- PreCommit(准备阶段):事务协调者根据参与者的反馈结果决定是否继续执行,如果在询问阶段所有参与者都放回可以执行操作,则事务协调者会向所有参与者发送PreCommit请求,参与者收到请求后写redo和undo日志,执行事务操作,但是不提交事务,然后返回ACK响应等待事务协调者下一步通知,如果在询问阶段任意参与者返回不能执行操作的结果,那么事务协调者会向所有参与者发送事务中断请求。
- DoCommit(提交或回滚阶段):这个阶段也会存在两种结果,任然根据上一步的执行结果来决定DoCommit执行方式。如果每个参与者在PreCommit都返回成功,那么事务协调者会向所有参与者发起事务提交指令,反正,如果参与者中任意参与者返回失败,那么事务协调者会发起终止指令来回滚事务。
- 用如下图说明:
- 三阶段提交与两阶段提交不同点:
- 增加了一个CanCommit阶段,用于询问所有参与者是否可以执行事务操作并响应,他的好处是,可以尽早发现无法执行操作而中止后续的行为。
- 在准备阶段后,事务协调者和参与者都引入超时机制,一旦超时,事务协调者和参与者都会继续提交事务,并且认为处于成功状态,因为这种情况下事务默认为成功的可能性较大。
- 实际上一旦超时,在三阶段提交协议下仍然可能出现数据不一致的情况,当然概率比较小的。另外,比两阶段提交好的地方是基于超时机制来避免资源永久锁定。
CAP理论和BASE理论
- 前面提到的两阶段提交和三阶段提交是XA协议解决分布式数据一致性问题的基本原理,但是这这两种方案为了保证数据的强一致性,降低了可用性,因为需要多数据库进行加锁,期间其他事务需要等待,也就是其他请求会被阻塞。实际上这里涉及分布式事务的两个理论模型。
CAP定理
-
CAP理论,又叫布尔理论,简单说他是指在分布式系统中不可能同时满足一致性(C:Consistency),可用性(A:Availability),分区容错性(P:Parition Tolerance)这三个基本需求,做多满足两个。
- C:数据在多个副本中要保持强一致性,比如签名说的分布式数据一致性问题
- A:系统对外提供的服务必须一致处于可用状态,在任何故障下,客户端都可能在合理的时间内获得服务端的非错误响应。
- P:在分布式系统中遇到任何网络分区故障,系统仍然能够对外提供服务。
-
网络分区概念:不同节点分布在不同子网络中时候,在内部网络正常的情况下,由于某些原因导致这些子节点之间出现网络不同的情况,导致整个系统切分成若干独立的区域,这就是网络分区。
-
CAP定理证明,在分布式系统中,要么满足CP,要么满足AP,不可能CAP,或者CA。
- 原因在于网络通信不是绝对可靠,比如网络延迟,网络异常都会导致系统故障。而分布式系统技术出现网络故障也需要保证系统仍然能够正常多外服务,所以在分布式系统中,Parition Tolerance(分区容错)是必然的,也就是需要满足分区容错性,就没有强一致性了。
- 如果是CA或者CAP这种情况,相当于网络100%可靠,否则出现网络分区情况时候,为保证数据一致性,必须拒绝客户请求,但是如果拒绝客户请求,就不满足A,所以,分布式系统更不可能选择CA,因此,只有AP或者CP两种。
- AP:放弃强一致性,实现最终一致性,很多互联网公司解决分布式数据一致性问题的主要选择
- CP,放弃高可用,实现强一致性,签名提到的两阶段提交,三阶段提交,可能导致的问题是用户完成一个操作会等待较长时间。
Base理论
-
Base理论是有CAp中一致性和可用性不可兼得衍生出来的一种新思想。
-
Base理论核心思想是通过牺牲数据强一致性获得高可用。他有如下三个特性
- Basically Availiable(基本可用):分布式系统出现故障,允许损失一部分可用性保证核心功能
- Soft State(软状态):允许系统中数据存在中间状态。这个状态不影响系统可用性,也就是允许系统中不同阶段数据副本之间同步存在延迟
- Eventually Consistent(最终一致性):中介状态的数据进过一段时间后,会达到一个最终的数据一致性。
-
Base理论并没有要求数据强一致性,而是允许数据在一段时间内不一致,但是数据最终会在某个点实现一致,互联网产品中可用性相对来说重要一点,数据都是可以补充的,不会错就行。
-
案例:在支付流程中,用户发起一个订单支付,不需要同步等待执行结果,系统会返回一个支付处理中的中间状态,对于用户来说,可以从订单列表中看到支付的处理结果。而对系统来说,第三方支付处理成功,在回调我们系统修改订单状态即可。这个场景中,虽然订单的支付状态与第三方支付状态不一致,当体验更好。
上一篇:SpringCloud Alibaba 框架下公司架构图
下一篇:分布式事务解决方案