分布式3PC理论

目录

为什么需要 3PC?

核心结论

3PC的优缺点

3PC与 Paxos / Raft 对比


本篇文章内容的前置知识为 分布式2PC理论,如果不了解,可点击链接学习

分布式2PC理论-CSDN博客

为什么需要 3PC?

1) 2PC 的根本问题:阻塞 + 不确定
2PC 两阶段:投票(prepare)→提交(commit)
一旦协调者在关键窗口宕机或网络分区,参与者会进入不确定状态——既不能提交也不敢回滚,只能无限等待协调者的最终决定。这带来两类问题:
阻塞:协调者挂了或网络中断,参与者无法自决,业务线程/锁资源被长期占用
进退两难:参与者贸然提交会破坏原子性;贸然回滚也可能与其他节点的提交相冲突
工程副作用:长时间占锁、长事务、资源饥饿、吞吐下降,甚至雪崩。

直观例子:协调者收齐所有YES后挂了。2PC 里参与者都已准备就绪,但没有最终指令,谁也不敢动,导致系统卡死。

2) 3PC 的设计目标:在可判定超时的条件下非阻塞

3PC(Three-Phase Commit)的目标不是更强一致,而是降低阻塞:
在一个同步或部分同步网络(消息延迟有明确上限 Δ)下,引入超时与一个缓冲阶段,让参与者在协调者失联时能自行做决定,不再无限等待。

3PC的关键前提假设(很重要):
故障模型为停机型(Fail-Stop):节点故障后只会停止服务,不会发送错误消息(即不作恶)
消息延迟有上限:网络传输、节点处理的延迟不会超过 Δ,因此超时可作为协调者失联的有效判定依据
无严重网络分区:若出现分区(部分节点断连),3PC 的一致性可能被破坏(见第 5 节)

同步网络:消息从发起到接收的延迟,一定≤某个明确的固定值 Δ,且节点处理消息的速度也有上限,全程可预判。
部分同步网络:大部分时候消息延迟≤Δ,但允许偶尔超出(可恢复),核心是多数情况下能按同步网络的规则决策。

3) 3PC 的核心改动:把 2PC 的准备再切半

        3PC 的核心改动是将 2PC 的 Prepare 阶段拆分为 CanCommit(预询问)和 PreCommit(预提交)两个阶段,再保留 DoCommit(正式提交)阶段,通过三阶段日志 + 超时自决规则,将 2PC 的单一不确定窗口拆分为两个可安全决策的窗口。

阶段协调者行为参与者行为超时规则(核心)
1. CanCommit(预询问)向所有参与者发送是否可提交请求,等待反馈仅自检(不占锁、不持久化关键日志),若可行返回 YES,否则返回NO

协调者:超时未收齐YES → 宣告Abort

参与者超时未收到协调者后续指令 → 直接Abort(安全,因未占资源)

2. PreCommit(预提交)仅当收齐所有YES时,发送预提交请求;否则发送Abort收到预提交后,持久化预提交完成日志(占锁、预留资源),返回ACK;收到Abort则直接回滚

协调者:超时未收齐ACK → 发送Abort

参与者超时未收到DoCommit指令 → 自主Commit(安全,因所有节点已通过预询问)

3. DoCommit(正式提交)收齐预提交ACK后,发送正式提交请求;若中途发现异常(如参与者回滚),则发送Abort收到Commit则执行提交、释放资源、删除锁;收到Abort则回滚。返回ACK给协调者

非阻塞的本质在于两条超时自决规则
3PC 通过阶段拆分,让参与者在任何超时场景下都有安全决策:
CanCommit 阶段超时:在 CanCommit 等不到协调者/指令,直接 ABORT
PreCommit 阶段超时:在 PreCommit 等不到DoCommit ,自主 COMMIT

这把 2PC 的唯一不确定窗口拆成两个:
PreCommit 之前超时 → 放弃(保证不会有人已提交)
PreCommit 之后超时 → 提交(保证大家都具备提交条件)

阶段1:CanCommit(预询问)
协调者 → 参与者:能提交吗?
参与者自检资源/逻辑,可行则回 YES,否则 NO
——超时策略:收不齐 YES => 协调者宣告 ABORT;参与者也可安全放弃阶段2:PreCommit(预提交)
条件:收齐所有 YES
协调者 → 参与者:进入“可提交态”,先落本地日志/锁资源,但还不写入最终提交;参与者回 ACK
——关键:一旦进入 PreCommit,大家都“随时可完成提交”阶段3:DoCommit(正式提交)
协调者 → 参与者:执行提交;参与者提交并释放资源,回 ACK

4) 3PC 如何缓解 2PC 的典型故障场景
用三个场景对比:
场景 A:协调者在收齐 YES 之前宕机
2PC:有人已投 YES,有人还在等,不知道最终态,可能阻塞
3PC:仍处 CanCommit,参与者超时后安全 ABORT(没人进入 PreCommit)

场景 B:协调者在发出 PreCommit 之后、DoCommit 之前宕机
2PC:所有参与者都 prepare 完成,只能无限等最终决定
3PC:大家处于 PreCommit,等不到 DoCommit 就自主 COMMIT(非阻塞)

场景 C:协调者在发出 DoCommit 之后宕机
两者都能依赖持久化日志恢复到一致提交(已收到的提交照常提交,未收到的要么等恢复、要么依据恢复协议补齐)

协调者 DoCommit 后宕机,影响是没法收参与者的最终 ACK、没法统一处理异常,但不影响一致性,因为它已发完 Commit 指令:收到的参与者正常提交,没收到的参与者靠 PreCommit 日志(知道自己该提交),重启 / 超时后也会提交,最终结果一致

重启是因为参与者有可能在 PreCommit 阶段突然宕机,宕机后内存里的状态会丢,重启时只能靠日志找回之前已进入 PreCommit 的状态,才能按规则补提交;若没宕机,超时后直接自主 Commit 即可,不用重启。

5) 3PC 仍然不万能:网络分区下可能不一致
致命边界条件:分区导致有些参与者收到 PreCommit,另一些没收到
收到 PreCommit 的那一侧:按 3PC 规则,超时会 COMMIT
未收到的一侧:按规则会 ABORT
破坏原子性
这就是为什么 3PC 的非阻塞要靠同步/无分区假设;而在真实互联网环境(异步且可能分区),3PC 不能保证强一致

6) 形式化地看:状态机与超时转移

从工程实现角度,3PC 的非阻塞和一致性依赖状态机 + 持久化日志(WAL,Write-Ahead Log) ,确保节点重启后能恢复到正确状态。

参与者的核心状态流转:
Init(初始) → Waiting(CanCommit后,待预提交) → PreCommit(预提交完成) → Commit/Abort(最终态)

状态跃迁规则:
Waiting 状态:超时 / 收到 Abort → 跳转到 Abort;收到 PreCommit → 跳转到 PreCommit
PreCommit 状态:超时 / 收到 Commit → 跳转到 Commit;收到 Abort → 跳转到 Abort
任何状态跃迁前,必须先持久化日志,防止重启后状态丢失

日志的核心作用:幂等恢复
节点宕机重启后,通过读取 WAL 日志确定自身状态:
若日志记录已进入 PreCommit → 直接执行 Commit
若日志记录仅 Waiting → 执行 Abort
若日志记录已 Commit → 无需操作(确保幂等,避免重复提交)

幂等是多次执行同一操作,结果不变;恢复是崩溃后回到崩溃前的正确状态

核心结论

        2PC 的痛点是阻塞:卡在 Prepare 后、Commit 前的不确定窗口,只能死等协调者,活性差但异步环境下安全性稳
        3PC 的改进是拆窗自救:用 CanCommit+PreCommit 拆分窗口,让参与者能按状态超时自决(Waiting→Abort/PreCommit→Commit),缓解阻塞,但代价是多一轮通信、且分区下可能分叉,需依赖同步 / 部分同步网络
        工业界少用 3PC,是因为它解决了 2PC 的阻塞,却引入了分区下的一致性风险,而 Raft/Paxos 等共识协议能在异步 + 分区环境下同时保证安全与活性,更适配复杂场景。

3PC的优缺点

优点:
比 2PC 更少阻塞。
引入超时机制,避免无限等待。

缺点:
实现复杂,消息开销大(多一轮通信)
仍不能完全解决一致性问题(极端网络分区时仍可能矛盾)
在实际工业界应用很少(数据库几乎不用 3PC)

3PC与 Paxos / Raft 对比

3PC:事务原子提交协议,目标是“分布式事务一致性”。
Paxos / Raft:分布式一致性协议,目标是“副本之间达成共识”。

区别:
3PC 偏向数据库事务。
Paxos / Raft 偏向分布式存储、日志复制。
工业界更常用 Raft / Paxos,而不是 3PC。

为啥工业界更爱 Raft/Paxos,不用 3PC?
因为 3PC 的本事太单一,只解决事务原子提交

实际场景中,事务的需求可以用更灵活的方案(如 TCC、Saga)替代,不用死磕 3PC;
副本共识(同步数据、选主)是所有分布式系统的基础刚需(比如分布式数据库、缓存集群、云服务都要),Raft/Paxos 刚好能稳定解决这个刚需,还能容忍网络分区、节点故障,比 3PC 更通用抗造。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/96074.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/96074.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Web 前端可视化开发工具对比 低代码平台、可视化搭建工具、前端可视化编辑器与在线可视化开发环境的实战分析

在前端开发领域,“可视化”已经成为提升效率和降低门槛的重要方向。从 低代码平台 到 前端可视化编辑器,再到 在线可视化开发环境,这些工具都在改变前端的开发方式。 本文将结合真实项目,分析常见的 Web 前端可视化开发工具&#…

单例模式(C++)(错误日志实现)

单例模式一、核心原理二、常见的单例模式实现方式1. 懒汉式(Lazy Initialization)2. 饿汉式(Eager Initialization)三、关键实现细节解析四、单例模式的适用场景与特点使用场景日志工具(确保日志写入的唯一性&#xff…

stm32 链接脚本没有 .gcc_except_table 段也能支持 C++ 异常

stm32 使用 cubemx 生成的 gnu ld 链接脚本没有 .gcc_except_table 段。如下所示 /* ****************************************************************************** ** ** file : LinkerScript.ld ** ** author : Auto-generated by STM32CubeIDE ** ** Abst…

SpringBoot改造MCP服务器(StreamableHTTP)

项目地址: https://gitee.com/kylewka/smart-ai 1 项目说明 MCP(Model Context Protocol)协议是一个用于 AI 模型和工具之间通信的标准协议。随着 AI 应用变得越来越复杂并被广泛部署,原有的通信机制面临着一系列挑战。 近期 MCP …

【数学建模】烟幕干扰弹投放策略优化:模型与算法整合框架

烟幕干扰弹投放策略优化:模型与算法整合框架 基于文献研究和问题需求分析,我们构建了完整的模型与算法整合框架。 一、整体建模框架 1. 核心问题分解 物理层:烟幕弹道运动与扩散特性建模博弈层:导弹识别与决策机制建模优化层&…

结合大数据知识体系对仓库建模方法总结

传统的仓库建模理论(如维度建模)仍然是基石,但大数据的“4V”特性(Volume, Velocity, Variety, Value)要求我们对这些方法进行演进和补充。 以下是结合大数据知识体系对仓库建模方法的总结:一、核心目标&am…

C 语言第一课:hello word c

C 语言第一课&#xff1a;hello word c开发工具创建项目快速学习平台开发工具 个人推荐使用 jetBrains 公司的 CLion 开发工具下载地址 https://www.jetbrains.com/clion/ 创建项目 编写代码 //头文件 #include <stdio.h>//程序入口 int main(){printf("hello w…

基于Java Spring Boot的云原生TodoList Demo 项目,验证云原生核心特性

以下是一个基于 Java Spring Boot 的云原生 TodoList Demo 项目&#xff0c;涵盖 容器化、Kubernetes 编排、CI/CD、可观测性、弹性扩缩容 等核心云原生特性&#xff0c;代码简洁且附详细操作指南&#xff0c;适合入门学习。项目概览 目标&#xff1a;实现一个支持增删改查&…

开源一个轻量级 Go 工具库:go-commons

项目背景 在日常 Go 开发中&#xff0c;我们经常需要处理字符串操作和系统监控相关的功能。虽然 Go 标准库提供了基础的字符串处理能力&#xff0c;但在实际项目中&#xff0c;我们往往需要一些更便捷的工具函数来提高开发效率。 基于"尽可能不使用第三方依赖"的原…

clang(clangd)与arm-linux-gcc、ARMGCC、ICCARM(IAR)、C51编译器的兼容性

环境&#xff1a;vscodeclangdEIDE开发开发单片机&#xff08;C51 keilMDK IAR&#xff09;。 vscode远程clangdarm-linux-gcc(交叉编译工具链)。 &#xff08;1&#xff09;首先clang&#xff08;clangd&#xff09;是兼容gcc的&#xff0c;也就是兼容arm-linux-gcc&#xff…

Docker 部署 Rancher2.4.4

获取2.4.4镜像包docker pull rancher/rancher:v2.4.4创建目录并赋予权限mkdir -p /home/rancher/{data,log} && chmod -R 777 /home/rancher启动容器docker run -d \ --privileged \ --name rancher \ --restartunless-stopped \ -p 80:80 -p 443:443 \ -v /home/ranc…

无root使用adb模式下的scene 用shizuku激活scene教程

本次教程是用shizuku和ShizukuRunner激活scene的adb模式&#xff0c;实现大部分功能&#xff0c;比较简单&#xff0c;如果手机已经root直接使用root模式即可。 工具 scene(点我下载) Shizuku(点我下载) ShizukuRunner(点我下载) 教程 1.首先要有一台支持无线调试的手机(安…

《UE5_C++多人TPS完整教程》学习笔记50 ——《P51 多人游戏中的俯仰角(Pitch in Multiplayer)》

本文为B站系列教学视频 《UE5_C多人TPS完整教程》 —— 《P51 多人游戏中的俯仰角&#xff08;Pitch in Multiplayer&#xff09;》 的学习笔记&#xff0c;该系列教学视频为计算机工程师、程序员、游戏开发者、作家&#xff08;Engineer, Programmer, Game Developer, Author&…

树莓派 Ubuntu 24.04 开机换源总结

1. 图形界面 (桌面版) 如果你刷的是 Ubuntu Desktop 24.04&#xff1a;打开 Software & Updates&#xff08;软件和更新&#xff09;。在 Ubuntu Software 标签里找到 Download from 下拉菜单。默认只有 Main server 和 Server for China&#xff0c;如果想要更多选择&…

工业显示器在地铁电力监控与运维中的应用

在地铁电力监控与运维中&#xff0c;工业显示器凭借其高可靠性、环境适应性和强大的功能集成&#xff0c;成为保障地铁供电系统安全稳定运行的核心设备。以下从关键应用场景、技术优势及实际案例三个维度展开分析&#xff1a;一、核心应用场景变配电室与环控电控室监控 工业显示…

Docker 快速部署单节点 NiFi 1.27

Docker 快速部署单节点 NiFi 1.27 前言 Apache NiFi 是一款强大的数据集成工具&#xff0c;专注于数据的采集、处理和分发&#xff0c;具有可视化流程设计、强大的容错能力等特点。通过 Docker 部署可以快速搭建环境&#xff0c;省去复杂的配置步骤。本文介绍如何使用官方镜像…

php redis 中文API文档手册

php redis 中文API文档手册 Redis::__construct构造函数 $redis new Redis();connect, open 链接redis服务 参数 host: string&#xff0c;服务地址 port: int,端口号 timeout: float,链接时长 (可选, 默认为 0 &#xff0c;不限链接时间) 注: 在redis.conf中也有时间&#xf…

Windows环境下实现GitLab与Gitee仓库代码提交隔离

1. 背景 在开发工作中&#xff0c;我需要同时使用2个代码托管平台&#xff1a;公司统一使用的GitLab和个人学习用的 Gitee。我希望能够在同一台电脑上方便地管理和提交两个平台的代码&#xff0c;实现账号和提交内容的有效隔离。 前提条件&#xff1a; 已安装Git Bash、Tort…

深度解析:抗辐射电源芯片 ASP4644S2B 在空间环境中的单粒子效应表现

摘要&#xff1a;随着航天技术的飞速发展&#xff0c;空间电子设备面临着日益复杂和严苛的辐射环境挑战。单粒子效应&#xff08;SEE&#xff09;作为辐射环境对半导体器件影响的主要形式之一&#xff0c;极大地影响着航天电子系统的可靠性和稳定性。本文通过系统梳理国科安芯推…

【RabbitMQ】如何在 Ubuntu 安装 RabbitMQ

1. 安装部署 Erlang 环境 RabbitMQ 是一套开源的消息队列服务软件&#xff0c;基于 Erlang 语言编写的&#xff0c;因此&#xff0c;在安装 RabbitMQ 之前&#xff0c;我们需要先部署 Erlang 环境&#xff0c;再安装 RabbitMQ 环境&#xff08;就像运行 Java 程序&#xff0c;…