两阶段提交算法为什么满足线性一致性?
保留所有版权,请引用而不是转载本文(原文地址 https://yeecode.top/blog/116/ )。
两阶段提交(Two-phase Commit,简称2PC)算法我们都熟悉,我们也知道两阶段提交是一个常用的满足线性一致性的算法。
那它为什么满足线性一致性呢?我们今天就来证明这一点。
提前说明一下,阅读本文需要大家对下面的两点有详细的了解:
- 线性一致性的定义及约束
- 两阶段提交算法的实现逻辑
对这块概念不清晰的同学,可以阅读我们之前的文章。
在证明之前,我们首先确认两点:
- 考虑到网络延迟、节点处理速度等的不同,各个节点收到“Prepare”消息并创建事务是有先后的。
- 考虑到网络延迟、节点处理速度等的不同,各个节点收到“Commit”消息并提交事务是有先后的。
在一次成功的二阶段提交操作中一定存在一个全局锁时段。这一时段从准备阶段的最后一个“Yes”消息发出开始,到提交阶段的第一个“Commit”消息被接收结束。在这一时段中,所有的节点都已经创建事务但未提交事务。
在全局锁时段之后,是提交时段。这一时段从提交阶段的第一个“Commit”消息被接收开始,到提交阶段的最后一个“Done”消息发出为止。在这一时段中,各个节点陆续完成事务提交,如下图所示。
这里我们假设参与者开启事务和发出Yes消息是同时进行的,参与者收到Commit消息和提交事务是同时进行的。这两个假设都不会影响最终的结论。
在全局锁时段和提交时段之间存在一个同步时刻。同步时刻在全局历史中是唯一确定的,且这一时刻具有以下特点:
- 除当前的2PC操作外,没有其他操作正在集群中开展。全局锁时段中在各个节点创建的锁可以共同保证这一点。
- 对于任何一个节点而言,该时刻之后进行的第一个操作都是当前2PC的提交操作。
那我们可以等价地认为2PC操作引发的变更就是在同步时刻发生的。这样,2PC提交操作在全局历史中的位置就被确定了下来。因此,任何通过2PC操作开展的事件都可以唯一地映射到全局历史中,就像是在全局历史中开展的事件一样,那这样的操作自然可以保证线性一致性。
接下来,我们再用一个更为宏观视角的示例来理解这一过程。
在下图中,节点A作为协调者发起了一次两阶段提交操作A2,并触发了参与者节点B和节点C的B2和C1操作。
可以看出,两阶段提交事件A2和另外的B1、B3事件是并发的。我们可以给出线性一致性要求的全局历史:
- A1-A2、B1、B3并发- C2
根据线性一致性的约束,A1事件发生在A2事件之前,读到的变量x必须为旧值;C2事件发生在A2事件之后,读到的变量x必须为新值。显然在二阶段提交中这两者都是满足的。
线性一致性要求单个节点的事件历史在全局历史上符合程序的先后顺序,但是对于并发事件没有约束。因此,关于B1、B2读取变量x的操作存在以下几种情况,且都满足线性一致性的所有约束。
- B1和B3都读取到A2变更前的旧值
- B1读取到A2变更前的旧值、B3读取到A2变更后的新值
- B1和B3都读取到A2变更后的新值
进一步地,我们可以把A2操作的两阶段提交细节步骤标注出来,如下图所示。
这时我们可以得出结论:
- 在同步时刻,一定不会发生读取变量x的操作
- 在同步时刻之前,读变量x一定会读取到旧值
- 在同步时刻之后,读变量x一定会读取到新值
上述A2操作的两阶段提交细节步骤是我们臆想绘制出来的。在实际的2PC操作中,同步时刻在2PC中的具体位置是难以确定。
可见,两阶段提交不对并发事件给出保证。但我们知道,一定存在一个同步时刻,将两阶段提交映射到全局历史上。这个时刻可能在B1之前,可能在B1和B3之间,可能在B3之后,如图所示。
本质上,两阶段提交是通过给各个节点同时加锁来实现了一个全局同步的时钟,这个时钟并不能够用来记录时间的长短,但足以标定出两阶段提交在全局历史中的位置,借此实现了线性一致性。
到这里,我们就论证了两阶段提交满足线性一致性。
当然,实现这一全局同步的时钟的代价也是很高的,它直接导致了所有节点的阻塞,影响了分布式系统的并发性能。
好,本文就介绍到这里。如果想对分布式系统的一致性有更全面系统的认识,可以参考下面的书籍。

书籍对各种一致性算法都进行了介绍,包括两阶段提交算法、三阶段提交算法等,并进行了详细分析。对大家体系化地掌握这些知识很有帮助。
另外这本书对分布式系统相关的理论、实践、工程知识均进行了详细的介绍,层层递进,有助于大家建立完整的分布式系统知识体系。涉及一致性、共识、Paxos、分布式事务、服务治理、微服务、幂等、消息系统、Zookeeper等。并且还发行了繁体版。
再次提醒大家,在学习分布式系统时,因为涉及到的理论、框架很多。所以大家一定要理清知识脉络,否则容易学得越多越混乱。
好了,我是程序员易哥。
别忘了点赞……
这回就说这么多!
可以关注我!等我下回接着说!
可以访问个人知乎阅读更多文章:易哥(https://www.zhihu.com/people/yeecode),欢迎关注。