一致性协议之三阶段提交

原文地址:《一致性协议之三阶段提交》

在上一篇文章《一致性协议之二阶段提交》中介绍了二阶段提交协议的设计和原理,也了解了在实际运行过程中可能存在的一些问题,因此研究者在二阶段提交协议的基础上进行了改进,提出了三阶段提交协议。

协议说明

3PC,是Three-Phase Commit的缩写,即三阶段提交,是2PC的改进版,将二阶段提交协议的“提交事务请求”过程分为二步,形成了CanCommit、PreCommit和doCommit三个阶段组成的事务下得协议,协议设计如下图:

协议调用图

下面我们来看一下协议的详细说明。

阶段一:CanCommit

  1. 事务询问

    协调者向所有参与者发送一个包含事务内容的canCommit请求,询问是否可以执行事务提交操作,并进入等待各参与者响应状态。

  2. 参与者响应

    参与者接收到协调者的canCommit请求后,如果认为可以顺利执行事务则反馈Yes响应,并进入预备状态,否则反馈No响应。

阶段二:PreCommit

在阶段二中,协调者会根据各参与者的响应来决定是否进行事务的PreCommit操作,阶段二中会包含以下两种可能。

执行事务预提交

如果协调者从所有参与者获得的反馈都是Yes响应,那么会执行预提交。

  1. 发送预提交请求

    协调者向所有参与者发送preCommit请求,并进入Prepared阶段。

  2. 事务预提交

    参与者收到preCommit请求后,会执行事务操作,并将Undo和Redo信息记录到事务日志中。

  3. 向协调者反馈事务执行响应

    如果参与者成功执行了事务操作,反馈给协调者Ack响应,并进入等待最终指令状态中,最终指令包括提交(commit)或终止(abort)。

中断事务

如果任何一个参与者反馈了No响应,或在协调者等待所有参与者反馈时发生了超时,那么就会中断事务。

  1. 发送中断请求

    协调者向所有参与者发送abort请求。

  2. 中断事务

    参与者如果接收到了协调者的abort请求,或者在等待协调者请求过程中出现超时,参与者都会中断事务。

阶段三:doCommit

该阶段会对事务进行真正的提交,也会存在下面两种情况。

执行提交

如果在第二阶段协调者接收到了所有参与者的Ack响应,那么协调者就从预提交状态转换到提交状态,并向所有参与者发出doCommit请求。

  1. 发送提交请求

    向所有参与者发送commit请求。

  2. 事务提交

    参与者接收到doCommit请求后,会正式执行事务提交操作,并在提交成功后释放事务执行期间占用的事务资源。向协调者发送Ack消息。

  3. 完成事务

    协调者接收到所有参与者反馈的Ack消息后,完成事务。

中断事务

如果在阶段二中,协调者接收到了参与者的No响应,或者在等待参与者响应时发生了超时,就会中断事务。

  1. 发送中断请求

    协调者向所有参与者发送abort请求。

  2. 事务回滚

    参与者接收到abort请求后,会利用阶段二中记录的Undo信息来执行事务回滚操作,并在回滚成功后释放所有事务执行期间占用的事务资源。向协调者发送Ack消息。

  3. 中断事务

    协调者接收到所有参与者反馈的Ack消息后,中断事务。

这里有一点需要注意,当进入阶段三后,如果协调者出现问题或协调者与参与者通信出现问题。这两种情况都会导致参与者无法及时收到协调者的commit或abort请求,针对这种问题参与者会在等待超时后自动进行事务的提交。

三阶段提交协议的设计描述比较多,为了便于理解,将上述的描述内容整理了一个表格和流程图可以方便大家的理解。

image
image

优缺点

  • 优点:相比于二阶段提交协议,三阶段提交协议最大的优点就是降低了参与者的阻塞范围,并且能够在出现单点故障后继续达成一致。

  • 缺点:数据的不一致,在阶段三中,如果参与者接收到了preCommit消息后,出现了不能与协调者正常通信的问题,在这种情况下,参与者依然会进行事务的提交,这就出现了数据的不一致性。

你可能感兴趣的:(一致性协议之三阶段提交)