分布式2PC理论

目录

什么是分布式 2PC(Two-Phase Commit)

2PC 的工作原理

2PC 的优缺点

为什么 2PC 不完全可靠?

超时问题

协调者故障


什么是分布式 2PC(Two-Phase Commit)

定义
        2PC 是一种原子提交协议,用于把一次“跨多个节点/资源管理器”的事务做成要么全部提交、要么全部回滚
参与角色只有两个:
协调者(Coordinator / 事务管理器 TM):发起、收集投票并下达最终决定。
参与者(Participants / RM):各个数据库/服务,执行本地操作并在提交前表态

资源管理器(RM)是管理具体数据资源的组件,即使在同一节点上,不同类型的资源管理器也属于多个资源。常见的资源管理器包括:
数据库
消息队列
缓存
分布式文件系统
例如一个事务需要同时完成
数据库更新订单状态消息队列发送通知消息,这两个操作分别由数据库 RM消息队列 RM管理,属于跨资源管理器的事务。

两阶段握手(简化时序)

  应用││ 1. 执行业务写入(各节点先本地执行但不提交)▼
协调者 ──Prepare──► 参与者1/2/.../N     (阶段一:投票/准备)◄─Yes/No─┆      ◄─Yes/No─┆├─若全部 Yes → ──Commit──► 全部参与者   (阶段二:提交)└─有 No/超时 → ──Rollback► 全部参与者   (阶段二:回滚)

关键点
        参与者在 Prepare 成功时必须把提交所需日志落盘、加锁/冻结相关行,承诺“收到 Commit 就一定能提交、收到 Rollback 就一定能回滚”
        2PC 只负责原子提交的协调,并不替代各节点的并发控制(MVCC/2PL)与隔离级别

为什么要Prepare 阶段落盘 + 加锁/冻结?

当参与者收到协调者的 Prepare 请求时,它要做两件关键事:

1. 写日志(落盘)

在数据库里,这叫 Prepare Log

含义是:我已经执行了本地事务的操作(写入/更新),但是先不提交。

写日志到磁盘是为了保证:即使机器宕机重启,能恢复我当时是准备提交的状态,避免数据丢失。

2. 锁定相关资源

比如要更新一行库存,把它加上锁,保证别的事务不能改。

因为你还没最终决定提交还是回滚,所以必须冻结住,避免数据被其他事务破坏。

3. 承诺的含义

如果后来收到 Commit 指令:一定能提交(因为日志+锁都在)

如果收到 Rollback:一定能回滚(因为我记录了未提交前的状态)

2PC 只负责原子提交协调,不替代并发控制?

2PC 解决的问题:
保证一个跨节点事务,要么所有人都提交,要么所有人都回滚。
(即原子性 + 一致性)

但它不解决的问题:
多个事务并发时的数据冲突。
比如两个事务同时扣库存,一个要减 5,一个要减 10,该谁先执行?会不会导致库存负数?
这种属于并发控制的范畴,需要 MVCC(多版本并发控制)或 2PL(两阶段加锁)等机制。

在分布式事务中的地位
        2PC 是最经典最通用的原子提交基线方案XA 标准就是基于 2PC。MySQL/PostgreSQL/Oracle 等都提供(XA、Prepared Transactions)
        它把跨库/跨服务的一致提交从业务里抽象到事务管理器(TM)层来做,业务方只关心成功/失败
        现代系统里,2PC常作为强一致方案的起点,在需要更高可用/弹性的场景,会引入 3PC、TCC、Saga、Paxos/Raft+两段提交等替代或改进。

什么是原子提交基线方案?
在分布式系统里,最基础最常见最权威的解决原子提交的方法就是 2PC

原子提交 = 所有节点的结果要么全成,要么全败

基线方案 = 社区/学术界/工业界最普遍认可的最低要求的做法

换句话说:
2PC 是跨节点事务一致性的起点和底线
如果连 2PC 都没实现,就不能保证强一致性

XA 标准是啥?

XA 标准由 X/Open 组织提出的一种分布式事务接口规范

它规定了事务管理器(TM)和资源管理器(RM) 之间的接口。

内核就是基于 2PC 协议。

结构:

TM(Transaction Manager):负责全局事务的开始、提交、回滚。

RM(Resource Manager):数据库、消息队列等资源。

XA 定义了 TM 调用 RM 的接口,比如 xa_start, xa_prepare, xa_commit, xa_rollback

所以XA是2PC的工业标准化版本
MySQL、Oracle、DB2 都支持XA接口

XA、Prepared Transactions 是啥?

XA 事务就是遵循 XA 标准的分布式事务。应用调用 TM,TM 协调多个 RM(数据库),执行 2PC 流程。比如 Java EE 里的 JTA(Java Transaction API) 就是 XA 的实现。

Prepared Transactions(预提交事务)

是数据库对 2PC 的支持点。

在 Prepare 阶段,数据库执行事务但不提交,写入 Prepare 日志。

PostgreSQL 就有 PREPARE TRANSACTION 'xid'; 命令

它允许事务在待提交/待回滚的状态下存活,直到协调者发出最终决定

这就是为什么数据库里有 prepared state 这种中间状态既不是 committed,也不是 rolled back。它就是 2PC 的产物

与单机事务的区别

维度单机事务(本地 DB)分布式事务 2PC
参与节点1 个多个 RM
提交决定本地直接 COMMIT/ROLLBACK由协调者收集投票后统一决定
故障模型只考虑本机/本库还要考虑网络分区、消息丢失、任意一方宕机
锁的持有持有到本地提交从 Prepare 开始到最终决议都要持有(更长,易阻塞)
恢复通过 WAL/REDO/UNDO还需要全局事务日志和决议重放
代价一次落盘两轮网络往返 + 多节点落盘,延迟与抖动更大

单机是我自己说了算
2PC 是所有人都说能交卷,我再统一交;有人说不行就全部撤回

2PC 的工作原理

2PC(Two-Phase Commit,两阶段提交)就是:
在一个跨多个节点的事务中,引入一个 协调者(Coordinator),它负责向所有参与者(Participants) 发号施令。整个协议分为两个阶段:
准备阶段(Prepare/Voting Phase)
提交阶段(Commit Phase)
核心思想:先投票,再决策。
参与者要么一致答能提交,要么有任何一方答不行
协调者最后统一下达全部提交全部回滚的命令。

1. 协调者与参与者的角色
协调者(Coordinator)
类似总指挥
负责发起事务、收集各参与者反馈、做出最终决策。
有权决定全体提交或全体回滚。
参与者(Participants)
每个分布式节点,比如数据库分片、库存服务、支付服务。
接到指令时:
准备阶段执行本地事务并锁定资源。
提交阶段根据协调者的决定,真正提交或回滚。

2. 消息交互流程(投票 + 提交)

整个过程的时序图:

应用事务发起│▼
[协调者]  -------------------  发起 Prepare 请求  ------------------► [参与者1..N]◄-------------------- 返回 Yes/No --------------------││ 收集所有投票│├── 如果全部 Yes → 发送 Commit 请求│                         └────────► [参与者1..N 提交事务并解锁]│└── 如果有 No/超时 → 发送 Rollback 请求└────────► [参与者1..N 回滚事务并解锁]

交互过程就是:
投票阶段:协调者问 → 参与者答。
提交阶段:协调者决定 → 参与者执行。

两个阶段的作用

阶段一:准备阶段(Voting Phase / Prepare Phase)
协调者动作:
给所有参与者发出 Prepare 请求。

参与者动作:
执行本地事务操作
写入 Undo Log/Redo Log,并持久化
给相关记录加锁,防止并发修改
回复协调者Yes(我已准备好,可以提交)或 No(执行失败,不能提交)

作用:让所有参与者表态,保证在进入下一步前,大家都能提交

阶段二:提交阶段(Commit Phase)
协调者动作:
收集所有参与者的投票结果
如果全是 Yes → 发 Commit 请求
如果有 No 或超时 → 发 Rollback 请求

参与者动作:
收到 Commit:真正提交事务(把日志刷盘 + 更新数据可见 + 解锁)
收到 Rollback:撤销事务(按 Undo Log 回滚 + 解锁)

作用:做出最终决定,保证所有节点的事务命运一致

2PC 的优缺点

优点(为什么很多系统以 2PC 为起点)

1) 强一致性(原子提交)
保证跨多个资源的要么都成功,要么都失败
发生在同一事务内的多处写入,由协调者统一裁决,避免部分提交的脏状态。
 

2) 模型简单、生态成熟
角色清晰(协调者/参与者)、时序固定(Prepare→Commit/Rollback),实现成本低。
XA 标准等接口广泛可用,落地门槛低。

2PC 是把跨节点的一组写操作变成不可分割的原子动作的通用基线方案

缺点(为什么实际大规模场景常“绕开”或“增强”2PC)

痛点现象成因影响常见缓解
阻塞参与者长时间持锁等待Prepare 后到最终决议之间必须锁定行/范围吞吐下降、延迟陡增、易死锁缩短事务,把耗时 IO 移到事务外;原子语句更新;乐观并发+重试;按键/分片限流
协调者单点协调者宕机后事务悬而未决(in-doubt)2PC 天生非容错,协调者保存全局决议参与者一直持锁或占用“prepared”槽位协调者做共识化(Raft/Paxos)复制日志;恢复/重放;人工清理超时 in-doubt
网络分区/消息丢失有人收到了决议,有人没收到;或一直等不到决议分布式不可靠通信 + 2PC 无法自证全局状态可用性下降(等不到决定就不能推进),甚至运维介入决议落盘后幂等重试广播;参与者定期“拉取决议”;运维回收
性能开销额外的两轮网络 RTT + 两次强制落盘Prepare 要 fsync(承诺点),Commit 也要落盘延迟上升、吞吐降低,抖动放大批量化/合并事务、网络就近、降低事务跨度;“Presumed Abort/Commit”优化日志
运维复杂度“悬而未决事务”排查困难跨库跨机房,状态不一致但持锁业务阻塞、SLA 受损统一事务监控;超时/重放工具;灰度回滚策略
极端下的启发式决策参与者自作主张回滚/提交长超时 + 业务压力导致“heuristic”操作破坏原子性(最坏)严禁启发式提交;只允许回滚启发式并做审计;预案演练

为什么 2PC 不完全可靠?

2PC 在安全性(原子性)上依赖“协调者最终能把同一个决议告知所有参与者”;在可用性上会阻塞。一旦协调者长时间不可达、或网络分区持续存在,系统就会陷入悬而未决(in-doubt)状态;如果采用启发式决策(heuristic),则安全性也不再保证。

1. 协调者宕机 → 事务悬挂(in-doubt)
时序窗口:
    W1:协调者在收集投票前挂掉 → 没人进入 prepared,安全
    W2:所有参与者已返回 YES,协调者尚未把提交决议落盘/广播就挂 → 所有参与者处于prepared、加锁,不知道后续如何
    W3:协调者已写入提交决议且广播给部分参与者后挂 → 有的已提交,有的仍在 prepared(等 待决议)
        从最终性看:只要协调者恢复后能补发决议,原子性仍能收敛
        从可用性看:未收到决议的一侧长时间阻塞、占锁、顶资源

2. 网络分区/消息丢失
2PC 假设最终可以把同一决议送达所有参与者。当网络长期分区:
一侧已经提交,另一侧还在 prepared;
对外观测会出现“部分提交、部分未提交”的暂态不一致;
只有当网络恢复、做重放/补发后,才会收敛为一致;期间可用性差。
若人为启发式提交/回滚以“解堵”,则破坏原子性(最坏情况)

3. 阻塞特性是协议内生的
prepared 后,参与者必须持锁直到收到决议,写-写并发会被阻塞;
这不是实现细节,而是 2PC 的承诺点设计决定的(保证“接到 Commit 就一定能提交”)

超时问题

超时 ≠ 可以随便回滚。2PC 的正确做法要分处于哪个阶段

1. 定义
超时:一方在合理时限内没有收到对等方应答(参与者等不到协调者的决议,或协调者等不到参与者的投票)

2. 正确处置(分阶段)
阶段 A:投票前(参与者尚未 prepared)
    协调者可安全地中止事务(Abort),参与者无副作用

阶段 B:参与者已返回 YES(已写入 prepared)
    参与者不得自行提交或回滚(否则破坏原子性)
    正确动作:
        1. 保持 prepared 与锁(可设置上限时间,避免无限占用)
        2. 周期性重试联系协调者
        3. 支持“拉取决议”(用全局事务 ID 向协调者/事务记录表查询最终决定)
        4. 宕机恢复后,从本地prepared 列表中继续追决议

阶段 C:协调者侧超时
    未收到任何参与者的 YES,协调者可以判定失败并发 Rollback
    但一旦发现有人已经 YES,必须先把最终决议落盘(commit/abort),再幂等广播

术语含义执行者场景
commit决议:事务最终执行提交协调者协调者决策阶段(落盘决议)
abort决议:事务最终执行终止协调者协调者决策阶段(落盘决议)
rollback动作:参与者执行 “撤销修改”参与者参与者收到 abort 决议后执行

3. 错误姿势(会破坏原子性)
参与者在 prepared 状态自行回滚或自行提交(所谓 heuristic 决策)
实践中如必须“解堵”,也只允许启发式回滚(保守选择),且需审计与补偿,但依然要明白这已偏离 2PC 的安全模型。

4. “更先进协议”能否避免阻塞?
3PC(三阶段提交)在 2PC 之上加了一个中间状态(pre-commit)和超时可推进机制,理论上减少阻塞;但在异步网络 + 可能分区模型下,3PC 仍存在安全边界问题,工业界很少单独采用。
Paxos/Raft + 两段提交(又称 Paxos Commit)更常见:
决议事务记录写入共识日志,协调者可以无缝切换
参与者可从共识组拉取最终决议,阻塞窗口显著缩小
这并非去掉 2PC,而是把协调者是单点这个薄弱环节用共识加固

协调者故障

1. 问题本质
协调者掌握最终决议的唯一真相;
若它不可达或状态未持久化,参与者就会悬而未决。

2. 改进一:协调者共识化
把协调者的全局决议日志放到 Raft/Paxos:
流程要点:
协调者收齐 YES → 先把提交(或回滚)决议写入共识日志并提交
再向参与者幂等广播该决议
协调者宕机 → 选出新主,凭共识日志里的决议继续补发
参与者重启/超时 → 按事务 ID 拉取决议(而不是干等)

收益:
决议不丢(被多数副本持久化)
协调者不再是单点
in-doubt 时间显著缩短(可用性提升)

3. 改进二:日志恢复 + 决议拉取
协调者恢复:
从共识日志中找出已决定未完播与未决定的事务
对已决定:补发给所有参与者(幂等)
对未决定:根据投票情况与策略统一中止(如 presumed abort)

参与者自救:
启动时扫描本地 prepared 列表
逐个向协调者/事务记录表查询决议并执行
查询不到时按策略退回(只在采用 presumed abort/commit 的系统里,且需与 TM 协议一致)

4. 辅助优化:Presumed Abort / Presumed Commit
Presumed Abort(PA):把默认结局设为回滚(未见到决议就当失败),减少恢复时需要的日志/状态
Presumed Commit(PC):默认提交

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

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

相关文章

【原创】PDF一键导出图片多张图片一键合成PDF

一、界面功能介绍:PDF输出图片和图片合成PDF二合一 开发动力:WPS有此功能需要VIP收费,其他小软件不能满足我的要求 依赖:友好界面组件,pdf输出图片组件,合并组件 NET8.0(NetCore.Winform&#x…

卷积神经网络项目:基于CNN实现心律失常(ECG)的小颗粒度分类系统

卷积神经网络项目实现文档 1、项目简介 1.1 项目名称 ​ 基于CNN实现心律失常(ECG)的小颗粒度分类系统 1.2 项目简介 ​ 心律失常是临床上常见且潜在致命的心血管疾病之一,包括房性早搏(PAC)、室性早搏&#xff0…

Linux(1)|入门的开始:Linux基本指令

一、浅谈操作系统1、操作系统是什么?操作系统是一款做软硬件管理的软件我们可以发现除了上面的应用软件,操作系统、设备驱动和硬件都是为软硬件服务的,为了满足用户的不同需求,在操作系统之上需要有各种不同的应用软件。2、一个好…

基于STM32单片机的OneNet物联网云平台农业土壤湿度控制系统

1 系统功能介绍 本设计为 基于STM32单片机的OneNet物联网云平台农业土壤湿度控制系统。系统以STM32F103C8T6单片机作为核心控制器,结合土壤湿度传感器、OLED液晶显示模块、WiFi模块、继电器驱动电路以及按键电路,实现了土壤湿度的实时采集、显示与远程控…

GooglePlay提审问题记录

1、debug签名问题 原因: 为应用签名 | Android Studio | Android Developers 从 IDE 中运行或调试您的项目时,Android Studio 会自动使用由 Android SDK 工具生成的调试证书为您的应用签名。当您首次在 Android Studio 中运行或调试项目时&#xff…

使用Rag 命中用户feedback提升triage agent 准确率

简述使用 RAG(Retrieval-Augmented Generation),提升 Triage Agent 对用户反馈的处理准确率。这个方案的背景源于当前系统服务多个租户,各租户在业务场景、问题描述方式、术语使用习惯等方面存在极大差异,导致通用模型…

项目管理方法论有哪些流派

项目管理方法论的主要流派包括:瀑布式方法论、敏捷方法论、Scrum方法论、看板方法论、关键路径法(CPM)、计划评审技术(PERT)、挣值管理(EVM)、精益项目管理、六西格玛、PRINCE2方法论。瀑布式方…

Python远程文件管理高并发处理与负载均衡实战

《Python远程文件管理高并发处理与负载均衡实战》 引言 在5G网络和物联网时代,单台服务器每秒处理上万并发请求已成为基本要求。本文基于Python异步编程框架和分布式架构,深入探讨如何构建支持10万+并发连接的远程文件管理系统。通过实战案例演示,系统在某省级政务云平台实…

第十七章 Java基础-常用API-System

文章目录 package zsk.第十三章常用API.a02system;public

uniapp开发 移动端使用字符串替换注意事项

1. uniapp开发 移动端使用replace注意事项uniapp replaceAll方式在手机失效是因为安卓环境下不支持replaceAll方法。在uniapp开发中,如果在安卓环境下使用replaceAll方法,可能会导致页面无法渲染,并且控制台不会反馈错误信息。为了解决这个问…

【动态规划 矩阵快速幂】P10528 [XJTUPC 2024] 崩坏:星穹铁道|普及+

本文涉及知识点 C动态规划 【矩阵快速幂】封装类及测试用例及样例 P10528 [XJTUPC 2024] 崩坏:星穹铁道 题目背景 Corycle 喜欢玩一个由米哈游自主研发的一款回合制战斗游戏------《崩坏:星穹铁道》。这片银河中有名为「星神」的存在,他们…

捡捡java——2、基础07

Maven项目管理工具 maven项目->本地仓库->判断配置文件->没指定->远程仓库-》本地仓库 ->指定了->镜像仓库-》本地仓库 GroupId:一般是逆向公司域名 ArtifactId:一般是项目jar名 Version:版本号 maven目录里面conf&…

蜂窝通信模组OpenCPU的介绍

一、名词解释 OpenCPU 方案在软件功能上,需要将原来在 MCU 上运行的固件功能,放在 Cat.1 模组的 SoC 芯片上运行。同时,原来通过串口协议交互完成的功能,也变成通过 OpenAPI 调用的方式来完成。软件开发、编译及烧录方面&#xff…

沃丰科技出海客服系统对接沃尔玛全球电商平台,赋能中企出海

经济全球化的当下,中国企业出海步伐不断加快,沃尔玛全球电商平台作为全球极具影响力的零售渠道,成为众多中企开拓国际市场的重要选择。然而,跨境服务的复杂性、多语言沟通障碍、文化差异以及各行业的独特需求,始终是中…

Spring Boot 整合 SSE, http长连接

1. 什么是 SSE? (30秒)SSE (Server-Sent Events) 是一种允许服务器通过 HTTP 连接主动向客户端发送实时更新的技术。特点:基于 HTTP,使用简单,单向通信(服务器 -> 客户端),自动重连。对比 We…

类和反射的机制

一、类1.类的生命周期1. 类的编译:通过 javac 命令将 .java 源文件编译成 .class 字节码文件。 2. 类的加载:类加载器(ClassLoader)将 .class 文件从硬盘加载到内存,形成“类对象”,包括加载、链接、初始化…

【论文笔记】VGGT-从2D感知3D:pose估计+稠密重建+点跟踪

VGG组联合Meta改进了dust3r,输入图片,输出对应的一系列3D属性,被CVPR2025收录!1.abstract我们提出了VGGT,一种前馈神经网络,能够直接从场景的一个、几个或数百个视角推断出所有关键的3D属性,包括…

idea2025.2中maven编译中文乱码

问题描述:使用idea2025.2编译器中maven编译java文件后中文出现乱码情况解决方案:添加指令: JAVA_TOOL_OPTIONS-Dfile.encodingUTF-8 在下图位置注意:再次编译时,可以在原本文件中小范围修改一点内容(打个…

【适度精简】Windows 7 旗舰版-emmy精简系统

Windows 7旗舰版曾是非常受欢迎的操作系统,但随着时间推移和技术发展,其在一些场景下暴露出了诸多问题,适度精简的Windows 7旗舰版正是为解决这些问题而出现,以下是从用户软件痛点角度对其背景和作用的分析。 添加图片注释&#x…

数据分析编程第七步:分析与预测

7.1 销售趋势分析利用历史销售数据统计月销售额,计算季节化因子,获取去季节化销售数据,然后进行线性拟合,最后预测接下来的某个月的销售额。第一步:读数,统计月销售额A1file(“sales.csv”).importtc(order…