分布式事务协议
引言
在单机环境中事务具有ACID四个特性,分别是:原子性、一致性、隔离性和持久性。A、I、D这三个特性是为了保证C的实现。但是在分布式系统中,不同系统之间的事务并不知道其他事务的状态,所以在分布式系统中事务的ACID特性就无法得到很好的保证。在分布式系统中如果想要实现ACID四个特性,需要在一致性和可用性之间做取舍。针对分布式事务的理论支撑,目前广为流传的则是CAP和BASE。下文详细介绍一下这两个分布式系统的经典理论。
CAP和BASE
任何实践都离不开理论的指导,在设计和实现分布式系统的过程中也需要尊许特定的科学规范,CAP和BASE理论就是对分布式系统实现过程的抽象,从而提炼出的理论依据。
CAP理论
CAP理论是基于Eric Brewer教授提出的CAP猜想为基础构建的一个分布式定理。CAP理论简单来说表明了一个意思:一个分布式系统无法同时满足一致性(C:Consistency)、可用性(A:Availability)和分区容错性(P:Partition tolerance),这个三个基本需求,最多只能满足其中两项。
一致性
在分布式环境中,一致性是指数据在多个副本之间是否能保持一致的特性。如果一个副本更新后,另一个副本更新失败,则用户可能会读取到老数据,这就是典型的数据不一致情况。如果在分布式系统中能做到一个数据更新后,所有用户都可以读到最新的数据,则这个系统具有强制一致性。
可用性
可用性并不是聚焦于某一个副本,而是针对整个系统。用户无论何时访问一个分布式系统,该系统都可以在规定时间内返回正确结果。这个规定时间是系统设计之初设定的一个时间范围,如果在这个时间范围内有没有数据返回,则认为当前系统不可用。正确结果则是一个可以让非专业用户也能够理解的结果。
分区容错性
分区容错中的分区指的是分布式系统中不同节点应为网络故障等原因被分隔成不同的子网络(脑裂);其中的容错指的是发生这种情况分布式系统仍然能够对外提供保证一致性和可用性的服务。
以上是对CAP理论中一致性、可用性和分区容错性的解释。CAP理论既然已经说了最多只能满足其中2个特性。那看一下最多满足2个特性的三种情况下,分布式系统的表现是什么。
- 放弃分区容错
- 放弃分区容错,即表示如果出现脑裂的情况,则整个系统无法正常对外提供服务。如果要避免系统出现分区容错性问题,则可以将所有的数据都放在一个分布式节点上。放弃分区容错代表着牺牲了系统的可扩展性。
- 放弃可用性
- 放弃可用性即表示系统出现故障的时候,整个系统不可用。
- 放弃一致性
- 放弃一致性并不是说完全放弃数据的一致性,而是放弃数据的强一致性。在一个可控的时间范围内,数据最终会保持一致。放弃一致性表示的是追求最终一致性。
- 放弃一致性并不是说完全放弃数据的一致性,而是放弃数据的强一致性。在一个可控的时间范围内,数据最终会保持一致。放弃一致性表示的是追求最终一致性。
BASE理论
BASE理论是Dan Pritchett在CAP理论的基础上提出的一个分布式理论。其中的BASE表示基本可用(Basically Availiable)、软状态(Soft state)和最终一致性(Eventually consistent),这三个特性。其核心思想是及时无法做到强一致性,但是每个应用应该都可以根据自身业务特点,采用适当的方法使系统达到最终一致性。针对这三个特性,在下文详细介绍。
基本可用
基本可用是指分布式系统在遇到未知故障时,允许损失部分可用性。部分可用性可以分为两部分:响应时间上的损失和功能上的损失。响应时间上的损失指允许服务的执行时间超过规定时间范围,但是最终需要返回结果;功能上的损失指允许服务通过降级等策略,确保大多数请求是正常的。
软状态
软状态指数据在分布式系统各节点之间同步的过程中,允许存在一定的延迟。
最终一致性
最终一致性指系统中各节点在一定的同步时间后,所有节点的数据状态保持一致,对实时性没有那么严格的要求。实际情况下最终一致性分为以下五种情况。
- 因果一致性
进程B依赖进程A的处理结果,进程B对数据的访问应该都可以获得进程A更新后的值,且进程B对数据的更新需要在进程A更新数据的基础上进行。 - 读已之所写
对于单个进程来说,其更新数据后的读取操作,总是能读取到新值,而不是旧值。这算是一种特殊的因果一致性。 - 会话一致性
在同一个会话中,对于分布式系统的访问能够满足读已之所写的一致性。 - 单调读一致性
同一个进程读取系统中的某个数据后,在后续的读取操作中不会再返回更新之前的旧数据。 - 单调写一致性
系统需要保证对同一个进程写操作的顺序性。
以上是常见的五种最终一致性情况。BASE理论和传统ACID的区别则是可以接受牺牲强一致性来获得系统的可用性。这是大型高可用可扩展分布式系统应该满足的一个特点。
一致性协议
分布式系统的核心是确保数据一致性。为了满足这个条件,诞生了一系列一致性协议。下面介绍两个比较有代表性的一致性协议:2PC和3PC。
2PC
2PC,即二阶段提交。对于二阶段提交这个名词,很多人都不陌生。在MySql中因为redo log和bin log中写入时机的不同,可能会导致主从数据不一致,设计了二阶段提交。在分布式系统中的两阶段提交有一些不同,涉及到监管者和参与者。监管者统一负责各个节点的事务操作,通过获取各节点事务执行的状态,选择提交事务还是会滚事务;参与者则是事务的执行者,并将事务的执行状态上报给监管者。2PC可以分为两部分:提交事务请求和执行事务提交。
提交事务请求
- 事务询问
监管者向所有参与者发送事务内容,询问是否可以执行事务提交操作,并开始等待各参与者的响应。 - 执行事务
参与者开始执行事务,并记录undo和redo信息。 - 响应事务执行结果
参与者执行完事务后向监管者上报事务的执行结果,执行成功返回yes,执行失败返回no。
执行事务提交
如果所有的参与者都返回了yes,则监管者向各参与者发送提交事务的请求。参与者提交事务后返回确认信息。当所有的参与者都返回了确认信息,监管者认为当前事务提交完成。
如果有任意一个参与者返回了no,则监管者向各参与者发送回滚事务的请求,参与者回滚事务后返回确认消息。当所有的参与者都返回了确认信息,监管者任务事务回滚完成。
2PC的优缺点
- 优点
- 原理简单,实现方便。
- 缺点
- 同步阻塞:所有的参与者都需要等待其他参与者执行事务完成前都处于阻塞状态,无法响应其他请求。
- 单点问题:监管者权重太高,如果监管者发生故障,则整个二阶段提交都将出现问题。并且如果监管者在二阶段出现问题的话,所有的参与者都将保持阻塞状态。
- 数据不一致:如果在二阶段,发送部分commit请求后监管者宕机了。则只有部分参与者会提交事务,部分参与者无法提交事务。导致系统中存在数据不一致的情况。
以上是对2PC的一个简单介绍,可以看出2PC虽然实现简单,但是存在的缺点过于明显。针对2PC存在的问题,又有一种新的一致性协议诞生,即3PC(三阶段提交)。
3PC
三阶段提交是对二阶段提交的改进,仍然存在监管者和参与者。提交状态依次分为三种:CanCommit、PreCommit和DoCommit。下面详细介绍一下各个阶段的详情情况。
CanCommit
这个阶段监管者只做两件事:事物询问和处理响应。监管者会先向各个参与者发送请求,要求参与者返回当前是否可以执行事务的状态。当所有的参与者都返回可以执行,才会进入下一阶段。否则不执行事务。
PreCommit
监管者会提醒所有的参与者开始处理事务,并根据参与者返回的信息进行不同的处理,分为两种情况:执行事务预提交和中断事务。
执行事务预提交:监管者向参与者发送处理事务的指令;参与者收到指令后,开始执行事务操作,并记录redo和undo数据;参与者执行完后向监管者返回当前事务的执行状态。
中断事务:如果有任何一个参与者反馈了执行失败,或者监管者等待参与者反馈事务状态超时,则会执行中断事务的流程。参与者收到监管者发送的中断请求,或者等待监管者请求超时,都会开始执行事务中断。
DoCommit
这个阶段是事务提交阶段,同样是分为两种情况:执行提交和中断事务。监管者向各个参与者发送提交事务的请求,参与者收到请求后开始执行提交事务,并在事务提交完成后返回提交状态给监管者。当监管者收到所有的参与者都返回了成功状态,则认为当前事务已经提交。如果有任意一个参与者返回了no,则向各个参与者节点发送中断请求。参与者收到中断请求后执行任务的回滚,并将回滚状态返回给监管者。
三阶段提交的优缺点
- 优点
- 相较于二阶段提交,三阶段提交可以降低参与者的阻塞范围。三阶段提交需要提前确认参与者是否可以正常处理事务,如果存在参与者节点无法处理事务,则不会让其他节点执行事务。
- 缺点:
- 三阶段提交的整个流程更加复杂。
- 如果在PreCommit阶段出现网络分区,监管者和参与者不在同一个子网内,则参与者节点依然会进行事务提交,导致出现数据不一致的情况。
小结
分布式系统的理论基础是CAP和BASE等理论,而分布式事务的实现又基于2PC或3PC协议得以实现。学习分布式的相关知识,一定要先了解以上的一些基础理论或协议。

浙公网安备 33010602011771号