分布式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
英文地址,請注明出處:http://en.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;…