分布式事务

什么是分布式事务?

事务提供了一种机制,将包含一系列操作的工作序列纳入到一个不可分割的执行单元,只有所有操作都被正确执行才能提交事务,任意一个操作失败都会导致整个事务回滚到之前状态。

简单的说,事务提供了一种机制,使得工作要么全部都不做,要么全部被执行,即all or nothing。

分布式事务,就是在分布式系统中运行的事务,由多个本地事务组合而成,在分布式场景下,对事务的处理操作可能来自不同的机器,甚至是来自不同的操作系统。

什么是ACID?

ACID是事务具有的四大基本特征:

  • A:原子性(Atomicity),即事物最终的状态只有两种,全部执行成功或全部不执行,不会停留在中间某个环节。
  • C:一致性(Consistency),指事务操作前和操作后,数据满足完整性约束,数据库保持一致性状态。
  • I:隔离性(Isolation),指当系统内有多个事务并发执行时,多个事务同时使用相同的数据时,不会相互干扰,每个事务都有一个完整的数据空间,对其他事务时隔离的。
  • D:持久性(Durability),指一个事物被执行后,那么它对数据库所做的更新就永久地保存下来了。

什么是BASE理论?

ACID中的C是强一致性,也就是说所有操作都执行成功才能提交最终结果,以保证数据一致性或完整性。随着分布式系统规模不断扩大,复杂度急剧上升,达成强一致所需时间周期较长,限定了复杂业务的处理。

为了解决这一挑战,提出了BASE理论,关键点在于采用最终一致性来取代强一致性:

  • 基本可用(Basically Available):分布式系统出现故障时,允许损失一部分功能的可用性,保证核心功能可用。
  • 柔性状态(Soft State):在柔性事务中,允许系统存在中间状态,且这个中间状态不影响系统整体可用性。
  • 最终一致性(Eventually Consistency):事务在操作过程中可能会由于同步延迟等问题导致不一致,但最终状态下,所有的数据都是一致的。

ACID和BASE是对一致性和可用性的不同权衡所产生的不同结果,但二者都保证了数据的持久性。ACID选择了强一致性而放弃了系统的可用性,BASE理论则保证了系统的可用性,允许数据在一段时间内可以不一致,最终达到一致状态即可。

什么是刚性事务和柔性事务?

  • 刚性事务:遵循ACID原则,具有强一致性。
  • 柔性事务:根据不同的业务场景使用不同的方法实现最终一致性,它允许数据在一定时间内不一致,但要求最终一致。

如何实现分布式事务?

常用的分布式事务有3种基本方法:

  • 基于XA协议的二阶段提交协议方法
  • 三阶段提交协议方法
  • 基于消息的最终一致性方法

基于XA协议的二阶段提交方法

基于XA协议的二阶段提交方法中,二阶段提交协议(Two-phase Commit Protocol,2PC)是用于保证分布式系统中事务提交时的数据一致性,是XA在全局事务中用于协调多个资源的机制。

它引入了一个协调者来管理所有的节点,并确保这些节点正确提交操作结果,如果提交失败则放弃事务。

二阶段提交协议的执行过程分为投票(Voting)和提交(Commit)两个阶段:

  • 投票阶段:协调者(Coordinator)向事务参与者(Cohort)发起执行操作的CanCommit请求,并等待参与者的响应。参与者收到请求后,会执行请求中的事务操作,将操作信息记录到事务日志中但不提交(不会修改数据库中的数据),待参与者执行成功,则向协调者发送“Yes”消息,表示同意操作,若不成功,则发送“No”消息,表示终止操作。
  • 提交阶段:协调者受到所有参与者的消息后,根据受到的消息,向所有参与者发送DoCommit或者DoAbort消息,规则如下:
    • 如果协调者受到的都是“Yes”,那么它会向所有参与者发送“DoCommit”消息,参与者收到消息后,完成剩余操作(比如修改数据库中的数据)并释放资源,然后向协调者发送“HaveCommitted”消息。
    • 如果协调者收到的消息中包含“No”,那么它会向所有参与者发送“DoAbort”消息,此时在投票阶段发送“Yes”消息的参与者,会根据之前执行操作时的事务日志对操作进行回滚,之后所有参与者会向协调者发送“HaveCommitted”消息。
    • 协调者接收到所有参与者的“HaveCommitted”消息后,就意味着整个事务结束了。

二阶段提交的算法思路可以概括为:协调者向参与者下发请求事务操作,参与者接收到请求后,进行相关操作并将操作结果通知协同者,协同者根据所有参与者的反馈结果决定各参与者是要提交操作还是撤销操作。

基于XA的二阶段提交算法存在的问题:

  • 同步阻塞问题,二阶段提交算法在执行过程中,所有参与者都是事务阻塞型的,这样它不支持高并发场景。
  • 单点故障问题,算法类似于集中式算法,一旦事务管理器发生故障,整个系统都处于停滞状态。尤其是在提交阶段一旦事务管理器发生故障,资源管理器会由于等待管理器的消息,而一直锁定事务资源,导致整个系统被阻塞。
  • 数据不一致问题,在提交阶段,当协调者向所有参与者发送“DoCommit”请求时,如果发生了局部网络异常,或者在发送提交请求的过程中协调者发生了故障,就会导致只有一部分参与者接收到了提交请求并执行提交操作,但其他未接收到提交请求的那部分参与者则无法执行事务提交,这样会造成数据不一致。

三阶段提交方法

三阶段提交协议(Three-phase Commit Protocol,3PC)是对二阶段提交(2PC)的改进,它引入了超时机制和准备阶段。

  • 3PC引入了超时机制,如果协调者或参与者在规定时间内没有收到来自其他节点的消息,就会根据当前的状态选择提交或者终止整个事务,从而减少整个集群的阻塞时间。
  • 3PC在2PC的第一阶段和第二阶段中间引入了一个准备阶段,或者说把2PC的投票阶段一分为二,在提交阶段之前,加入了一个预提交阶段。

三阶段提交协议有CanCommit、PreCommit和DoCommit三个阶段:

  • CanCommit阶段:协调者向参与者发送请求操作(CanCommit请求),询问参与者是否可以执行事务提交操作,然后等待参与者响应,参与者收到CanCommit请求后,回复Yes表示可以顺利执行事务,否则回复No。需要注意这时参与者不会将操作信息记录到事务日志中。
  • PreCommit阶段:协调者根据参与者的回复消息,决定是否可以进行PreCommit操作:
    • 如果所有参与者回复的都是Yes,那么协调者就会执行事务的预执行。
    • 协调者向参与者发送PreCommit请求,进入预提交阶段。
    • 参与者收到PreCommit请求后执行事务操作,并将Undo和Redo信息记录到事务日志中。
    • 如果参与者成功执行了事务操作,则返回ACK响应,同时开始等待最终指令。
    • 假如任何一个参与者向协调者发送了“No”消息,或者等待超时后,协调者都没有收到参与者的响应,就执行中断事务的操作。
    • 协调者向所有参与者发送“Abort”消息。
    • 参与者收到“Abort”消息后,或超时后仍未收到协调者的消息,执行中断事务操作。
  • DoCommit阶段:执行真正的事务提交,根据PreCommit阶段协调者发送的消息,进入执行提交阶段或者中断事务阶段。
    • 执行提交阶段:
      • 如果协调者接收到所有参与者的ACK响应,则向所有参与者发送DoCommit消息,开始执行阶段。
      • 参与者接收到DoCommit消息后,正式提交事务,完成事务提交后,释放所有锁住的资源,并向协调者发送ACK响应。
      • 协调者接收到所有参与者的ACK响应后,完成事务。
    • 中断事务阶段:
      • 协调者向所有参与者发送Abort请求。
      • 参与者接收到Abort消息后,利用其在PreCommit阶段记录的Undo信息执行事务的回滚操作,释放所有锁住的资源,并向协调者发送ACK消息。
      • 协调者接收到所有参与者发送的ACK响应,执行事务中断操作,并结束事务。

3PC协议在协调者和参与者都引入了超时机制,当参与者在预提交阶段向协调者发送ACK消息后,如果长时间没有得到协调者的响应,在默认情况下,参与者会自动降超时事务进行提交,从而减少整个集群的阻塞时间。

三阶段提交仍然会存在数据不一致的情况。

基于分布式消息的最终一致性方案

2PC和3PC的核心思想都是以集中式的方式实现分布式事务,它有两个缺点:

  • 同步执行,性能差
  • 数据不一致问题

我们解决一致性问题的核心思想:将需要分布式处理的事务通过消息或者日志的方式异步执行,消息或日志可以存到本地文件、数据库或者消息队列中,再通过业务规则进行失败重试。

基于分布式消息的最终一致性方案的事务处理,引入了一个消息中间件,用于在多个应用之间进行消息传递。

这种方案采用消息传递机制,并使用异步通信的方式,避免了通信阻塞,从而增加系统的吞吐量,同时它还可以屏蔽不同系统的协议规范,使其可以直接交互。

在不需要请求立即返回结果的场景下,这些特性就带来了明显的通信优势,并且通过引入消息中间件,实现了消息生成方本地事务和消息发送的原子性,采用最终一致性方式,只需保证数据最终一致即可,一定程度上解决了2PC和3PC因为强一致性而在某些情况下导致数据不一致的问题。

针对上述三种不同的分布式事务方法,详细的比较如下表所示。
《分布式技术原理与算法解析》学习笔记Day06

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。