5.3 三阶段提交加缓冲


5.3 三阶段提交(3PC):给 2PC 加个"预提交"缓冲

3PC 的改进很朴素:在"准备投票"和"提交"之间,再插一轮"预提交"表态,让参与者在协调者失联时也能按多数意志自行决断,从而把 2PC 的阻塞窗口从"整个准备期"压缩到更短。但天下没有白减的阻塞——3PC 换来的是更苛刻的前提:必须保证"所有节点要么停在预提交、要么直接提交",否则会踩出更糟的结果。

学习目标

阅读完本节,你应当能够:

  1. 画出 3PC 的 CanCommit、PreCommit、DoCommit 三阶段。
  2. 解释"预提交"是如何缩短阻塞窗口、又凭什么让参与者在协调者失联时能自行决断。
  3. 说明 3PC 要成立所依赖的苛刻前提,以及为何现实中它不如 2PC 普及。

2PC 的病根在"憋住不能动"

上一节我们说了 2PC 的软肋,最痛的是这一条:一旦参与者完成了准备、锁也占住了,协调者却意外失联,所有参与者就进入"既不敢提交、也不敢回滚"的卡死状态——它们失去的不仅是时间,还有整段被占用的资源。3PC 想救的就是这个场景。它的思路是让参与者在没有协调者指挥时,也能根据"大多数已经到达哪一步"来自主决定下一步。要做到这点,就得在最终提交前,让所有人多一次"统一意见"。

一、三个阶段逐一拆开

CanCommit(可提交?):协调者先试探问一圈:"各位能不能进入提交流程?" 参与者只回答能或不能,不为表态占用资源。如果有谁说不,事务直接中止,这一轮结束得非常便宜。

PreCommit(预提交):上一轮全员点头后,协调者下令"准备"。参与者真正执行写入、占用资源、写日志,然后答应"已准备就绪"。这轮的表现很像 2PC 的准备阶段。

DoCommit(提交):协调者再问一次"确认提交?" 如果大家一致,就正式提交并释放资源。区别在于——因为有一轮先决的预提交做底,即便此时协调者失联,参与者也可以根据"多数是否已进入预提交"自行决定往前走还是回退,而不至于被永远憋住。

三阶段的推进

二、它凭什么缓解阻塞

对比一下阻塞窗口就清楚了:2PC 里从"开始准备"到"提交指令"之间,一旦协调者失联就是死胡同;3PC 因为有"预提交"这步的多数决信息,参与者可以在失联时相互对表——如果有人已经进入预提交,就说明之前多数已经同意进入流程,于是大家干脆继续向提交走;否则就安全地回滚。所以它把"只能干等"变成了"可依据多数意志自行决断",阻塞从"肯定死"降级为"大概率能走通"。

三、代价:三个苛刻前提

偏偏这个方案想要的"自行决断",是要用更苛刻的前提去换的:

前提一:网络延迟必须可控且有界。免得超时时机后还误判"多数已同意"。前提二:节点失联要能被判定为"崩溃"而非"纯粹的网络抖动",否则会做出错误的补偿决定。前提三:它没能解决协调者完全挂死的纯单点,只是把风险窗口缩短、托底能力提高。教室里丢可以,现实里这三个前提很难全满足,这也是 3PC 在工程实战里远不如 2PC 普及的原因之一。

四、一张三方案对比表

把 2PC、3PC 和后面要讲的 Saga 摆在一起看,你会更清楚 3PC 的位置:

方案 核心机制 主要软肋 适用
2PC 准备+提交两轮 协调者单点、阻塞久 短事务强一致
3PC 加一轮预提交 前提苛刻、工程落地难 理论价值大于实战
Saga 走走补补 最终一致、补偿复杂 长事务、高并发

五、用一个"协调者中途消失"实验把差异讲透

与其背两段文字,不如做一次心算实验。假设三个节点 A、B、C 一起跑一个事务,协调者在不同时点突然消失:

  • 要是 2PC:协调者在"准备"后消失,A、B、C 都处于"已准备、锁着资源"状态,谁都不敢提交也不敢回滚,只能干等协调者复活——这就是 2PC 最扎心的卡死。
  • 要是 3PC,且此时大家已进入 PreCommit:B 和 C 发现大多数(自己 + 邻居)都已经进入预提交,于是按规则继续朝提交走,被憋住的时间大大缩短。
  • 要是 3PC,但只到 CanCommit 还没到 PreCommit:多数尚未统一"可进流程",大家可以安全回滚,也就避免了"锁住等死"。

看出差别在哪了吗?3PC 的本质,是把"能不能自行决断"的决定权,从"协调者一人"还给"多数参与者"。代价是三个前提都得满足——其中"网络延迟必须有界"在跨机房、跨广域的真实环境里尤其难保证。这就是它理论上漂亮、实践上却处处掣肘的根源:教室的黑板上它赢,生产机房里它输面更大。所以你在真机房里见到的绝大多数分布式事务,要么是 2PC 的工程变体(加协调者主备、加超时传闻),要么是干脆不碰阻塞的 Saga——3PC 更多是帮你串起"阻塞问题到底怎么被一步步料理"的一条思想线索。顺带一提,"预提交"这个思想本身并没有白费:不少系统把它的精髓单独借走——"先广播一段绝大多数认可的中间状态、再决定执行",让协调者失联时不至于全盘卡死,这套思路至今仍活在很多实现里。可见即便 3PC 整体不普及,它对分布式事务演化史上的贡献依然实在。

本节要点回顾

  • 三阶段:CanCommit → PreCommit → DoCommit,多一轮多数决信息。
  • 缓解阻塞:参与者能在协调者失联时按多数意志自行决断。
  • 苛刻前提:延迟有界、失联可判崩溃、单点仍没根除。
  • 实战有限:3PC 理论价值大,工程里 2PC 仍是主流、Saga 担高并发就行。

2PC、3PC 都还在跟"阻塞"较劲,可互联网的高并发长事务偏偏最怕阻塞。于是有人干脆走了第三条路:不锁死、直接放行,出问题再补。下一节 5.4 看补偿事务与 Saga 怎么用"先执行+错误补偿"绕开阻塞的。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U