1. 程式人生 > >深入理解分散式系統的2PC和3PC

深入理解分散式系統的2PC和3PC

之前寫過一篇文章專門介紹了一下2PC和3PC(詳見:關於分散式事務、兩階段提交協議、三階提交協議)。上一篇文章中主要介紹了下這兩種分散式一致性協議的概念、具體提交流程以及優缺點。本文在上篇文章的基礎上在深入瞭解下這兩種分散式一致性協議。主要來分析下為什麼2PC存在資料一致性問題,3PC是如何解決了部分2PC存在的問題的,以及為什麼3PC還存在可能導致資料不一致的情況。

對分散式系統的概念及2PC和3PC不瞭解的朋友建議先閱讀分散式系列文章

協調者

在分散式系統中,每一個機器節點雖然都能明確的知道自己執行的事務是成功還是失敗,但是卻無法知道其他分散式節點的事務執行情況。因此,當一個事務要跨越多個分散式節點的時候(比如,淘寶下單流程,下單系統和庫存系統可能就是分別部署在不同的分散式節點中),為了保證該事務可以滿足ACID,就要引入一個協調者(Cooradinator)。其他的節點被稱為參與者(Participant)。協調者負責排程參與者的行為,並最終決定這些參與者是否要把事務進行提交。

二階段提交協議(2PC)

二階段提交協議主要分為來個階段:準備階段和提交階段。

在日常生活中其實是有很多事都是這種二階段提交的,比如西方婚禮中就經常出現這種場景:

牧師:”你願意娶這個女人嗎?愛她、忠誠於她,無論她貧困、患病或者殘疾,直至死亡。Doyou(你願意嗎)?”

新郎:”Ido(我願意)!”

牧師:”你願意嫁給這個男人嗎?愛他、忠誠於他,無論他貧困、患病或者殘疾,直至死亡。Doyou(你願意嗎)?”

新娘:”Ido(我願意)!”

牧師:現在請你們面向對方,握住對方的雙手,作為妻子和丈夫向對方宣告誓言。

新郎:我——某某某,全心全意娶你做我的妻子,無論是順境或逆境,富裕或貧窮,健康或疾病,快樂或憂愁,我都將毫無保留地愛你,我將努力去理解你,完完全全信任你。我們將成為一個整體,互為彼此的一部分,我們將一起面對人生的一切,去分享我們的夢想,作為平等的忠實伴侶,度過今後的一生。

新娘:我全心全意嫁給你作為你的妻子,無論是順境或逆境,富裕或貧窮,健康或疾病,快樂或憂愁,我都將毫無保留的愛你,我將努力去理解你,完完全全信任你,我們將成為一個整體,互為彼此的一部分,我們將一起面對人生的一切,去分享我們的夢想,作為平等的忠實伴侶,度過今後的一生。

上面這個比較經典的橋段就是一個典型的二階段提交過程。

首先協調者(牧師)會詢問兩個參與者(二位新人)是否能執行事務提交操作(願意結婚)。如果兩個參與者能夠執行事務的提交,先執行事務操作,然後返回YES,如果沒有成功執行事務操作,就返回NO。

當協調者接收到所有的參與者的反饋之後,開始進入事務提交階段。如果所有參與者都返回YES,那就傳送COMMIT請求,如果有一個人返回NO,那就返送roolback請求。

值得注意的是,二階段提交協議的第一階段準備階段不僅僅是回答YES or NO,還是要執行事務操作的,只是執行完事務操作,並沒有進行commit還是roolback。和上面的結婚例子不太一樣。如果非要舉例的話可以理解為男女雙方交換定情信物的過程。信物一旦交給對方了,這個信物就不能挪作他用了。也就是說,一旦事務執行之後,在沒有執行commit或者roolback之前,資源是被鎖定的。這會造成阻塞。

2PC存在的問題

下面我們來分析下2PC存在的問題。

這裡暫且不談2PC存在的同步阻塞、單點問題、腦裂等問題(上篇文章中有具體介紹),我們只討論下資料一致性問題。作為一個分散式的一致性協議,我們主要關注他可能帶來的一致性問題的。

2PC在執行過程中可能發生協調者或者參與者突然宕機的情況,在不同時期宕機可能有不同的現象。

情況一:協調者掛了,參與者沒掛

這種情況其實比較好解決,只要找一個協調者的替代者。當他成為新的協調者的時候,詢問所有參與者的最後那條事務的執行情況,他就可以知道是應該做什麼樣的操作了。所以,這種情況不會導致資料不一致。

情況二:參與者掛了,協調者沒掛

這種情況其實也比較好解決。如果協調者掛了。那麼之後的事情有兩種情況:

  • 第一個是掛了就掛了,沒有再恢復。那就掛了唄,反正不會導致資料一致性問題。

  • 第二個是掛了之後又恢復了,這時如果他有未執行完的事務操作,直接取消掉,然後詢問協調者目前我應該怎麼做,協調者就會比對自己的事務執行記錄和該參與者的事務執行記錄,告訴他應該怎麼做來保持資料的一致性。

情況三:參與者掛了,協調者也掛了

這種情況比較複雜,我們分情況討論。

  • 協調者和參與者在第一階段掛了。

    • 由於這時還沒有執行commit操作,新選出來的協調者可以詢問各個參與者的情況,再決定是進行commit還是roolback。因為還沒有commit,所以不會導致資料一致性問題。
  • 第二階段協調者和參與者掛了,掛了的這個參與者在掛之前並沒有接收到協調者的指令,或者接收到指令之後還沒來的及做commit或者roolback操作。

    • 這種情況下,當新的協調者被選出來之後,他同樣是詢問所有的參與者的情況。只要有機器執行了abort(roolback)操作或者第一階段返回的資訊是No的話,那就直接執行roolback操作。如果沒有人執行abort操作,但是有機器執行了commit操作,那麼就直接執行commit操作。這樣,當掛掉的參與者恢復之後,只要按照協調者的指示進行事務的commit還是roolback操作就可以了。因為掛掉的機器並沒有做commit或者roolback操作,而沒有掛掉的機器們和新的協調者又執行了同樣的操作,那麼這種情況不會導致資料不一致現象。
  • 第二階段協調者和參與者掛了,掛了的這個參與者在掛之前已經執行了操作。但是由於他掛了,沒有人知道他執行了什麼操作。

    • 這種情況下,新的協調者被選出來之後,如果他想負起協調者的責任的話他就只能按照之前那種情況來執行commit或者roolback操作。這樣新的協調者和所有沒掛掉的參與者就保持了資料的一致性,我們假定他們執行了commit。但是,這個時候,那個掛掉的參與者恢復了怎麼辦,因為他之前已經執行完了之前的事務,如果他執行的是commit那還好,和其他的機器保持一致了,萬一他執行的是roolback操作那?這不就導致資料的不一致性了麼?雖然這個時候可以再通過手段讓他和協調者通訊,再想辦法把資料搞成一致的,但是,這段時間內他的資料狀態已經是不一致的了!

所以,2PC協議中,如果出現協調者和參與者都掛了的情況,有可能導致資料不一致。

為了解決這個問題,衍生除了3PC。我們接下來看看3PC是如何解決這個問題的。

三階段提交協議(3PC)

3PC最關鍵要解決的就是協調者和參與者同時掛掉的問題,所以3PC把2PC的準備階段再次一分為二,這樣三階段提交就有CanCommitPreCommitDoCommit三個階段。在第一階段,只是詢問所有參與者是否可可以執行事務操作,並不在本階段執行事務操作。當協調者收到所有的參與者都返回YES時,在第二階段才執行事務操作,然後在第三階段在執行commit或者rollback。

這裡再舉一個生活中類似三階段提交的例子:

班長要組織全班同學聚餐,由於大家畢業多年,所以要逐個打電話敲定時間,時間初定10.1日。然後開始逐個打電話。

班長:小A,我們想定在10.1號聚會,你有時間嘛?有時間你就說YES,沒有你就說NO,然後我還會再去問其他人,具體時間地點我會再通知你,這段時間你可先去幹你自己的事兒,不用一直等著我。(協調者詢問事務是否可以執行,這一步不會鎖定資源

小A:好的,我有時間。(參與者反饋

班長:小B,我們想定在10.1號聚會……不用一直等我。

班長收集完大家的時間情況了,一看大家都有時間,那麼就再次通知大家。(協調者接收到所有YES指令

班長:小A,我們確定了10.1號聚餐,你要把這一天的時間空出來,這一天你不能再安排其他的事兒了。然後我會逐個通知其他同學,通知完之後我會再來和你確認一下,還有啊,如果我沒有特意給你打電話,你就10.1號那天來聚餐就行了。對了,你確定能來是吧?(協調者傳送事務執行指令,這一步鎖住資源。如果由於網路原因參與者在後面沒有收到協調者的命令,他也會執行commit

小A順手在自己的日曆上把10.1號這一天圈上了,然後跟班長說,我可以去。(參與者執行事務操作,反饋狀態

班長:小B,我們覺得了10.1號聚餐……你就10.1號那天來聚餐就行了。

班長通知完一圈之後。所有同學都跟他說:”我已經把10.1號這天空出來了”。於是,他在10.1號這一天又挨個打了一遍電話告訴他們:嘿,現在你們可以出門拉。。。。(協調者收到所有參與者的ACK響應,通知所有參與者執行事務的commit

小A,小B:我已經出門拉。(執行commit操作,反饋狀態

3PC為什麼比2PC好?

直接分析協調者和參與者都掛的情況。

  • 第二階段協調者和參與者掛了,掛了的這個參與者在掛之前已經執行了操作。但是由於他掛了,沒有人知道他執行了什麼操作。

    • 這種情況下,當新的協調者被選出來之後,他同樣是詢問所有的參與者的情況來覺得是commit還是roolback。這看上去和二階段提交一樣啊?他是怎麼解決一致性問題的呢?

    • 看上去和二階段提交的那種資料不一致的情況的現象是一樣的,但仔細分析所有參與者的狀態的話就會發現其實並不一樣。我們假設掛掉的那臺參與者執行的操作是commit。那麼其他沒掛的操作者的狀態應該是什麼?他們的狀態要麼是prepare-commit要麼是commit。因為3PC的第三階段一旦有機器執行了commit,那必然第一階段大家都是同意commit。所以,這時,新選舉出來的協調者一旦發現未掛掉的參與者中有人處於commit狀態或者是prepare-commit的話,那就執行commit操作。否則就執行rollback操作。這樣掛掉的參與者恢復之後就能和其他機器保持資料一致性了。(為了簡單的讓大家理解,筆者這裡簡化了新選舉出來的協調者執行操作的具體細節,真實情況比我描述的要複雜)

簡單概括一下就是,如果掛掉的那臺機器已經執行了commit,那麼協調者可以從所有未掛掉的參與者的狀態中分析出來,並執行commit。如果掛掉的那個參與者執行了rollback,那麼協調者和其他的參與者執行的肯定也是rollback操作。

所以,再多引入一個階段之後,3PC解決了2PC中存在的那種由於協調者和參與者同時掛掉有可能導致的資料一致性問題。

3PC存在的問題

在doCommit階段,如果參與者無法及時接收到來自協調者的doCommit或者rebort請求時,會在等待超時之後,會繼續進行事務的提交。

所以,由於網路原因,協調者傳送的abort響應沒有及時被參與者接收到,那麼參與者在等待超時之後執行了commit操作。這樣就和其他接到abort命令並執行回滾的參與者之間存在資料不一致的情況。

參考資料

相關推薦

深入理解分散式系統2PC3PC

之前寫過一篇文章專門介紹了一下2PC和3PC(詳見:關於分散式事務、兩階段提交協議、三階提交協議)。上一篇文章中主要介紹了下這兩種分散式一致性協議的概念、具體提交流程以及優缺點。本文在上篇文章的基礎上在深入瞭解下這兩種分散式一致性協議。主要來分析下為什麼2PC存在資料一致性

深入理解分散式系統中的快取架構(上)

本文主要介紹大型分散式系統中快取的相關理論,常見的快取元件以及應用場景。 1 快取概述 2 快取的分類 快取主要分為以下四類 2.1 CDN快取 基本介紹 CDN(Content Delivery Network 內容分發網路)的基本原理是廣泛採用

分散式事務-2PC3PC

提到2PC/3PC首先想到的是它是一致性協議,而且經常把它和Paxos協議放在一起比較,並且經常看到這樣的說法"世上只有一種一致性演算法,那就是Paxos",2PC/3PC並不是嚴格意義上的一致性協議,很少被用在處理一致性上;但另一方面又經常看到2PC/3PC和分散式事務放在一起討論,並且大部分的關

分散式事務 - 2PC3PC

協調者 在分散式系統中,每一個機器節點雖然都能明確的知道自己執行的事務是成功還是失敗,但是卻無法知道其他分散式節點的事務執行情況。因此,當一個事務要跨越多個分散式節點的時候(比如,淘寶下單流程,下單系統和庫存系統可能就是分別部署在不同的分散式節點中),為了保證該事務可以滿足ACID,就要引入一個

分散式系統理論基礎 - 一致性、2PC3PC

引言 狹義的分散式系統指由網路連線的計算機系統,每個節點獨立地承擔計算或儲存任務,節點間通過網路協同工作。廣義的分散式系統是一個相對的概念,正如Leslie Lamport所說[1]: What is a distributed systeme. Distribution is in th

分散式系統理論基礎1: 一致性、2PC3PC

狹義的分散式系統指由網路連線的計算機系統,每個節點獨立地承擔計算或儲存任務,節點間通過網路協同工作。廣義的分散式系統是一個相對的概念,正如Leslie Lamport所說[1]:What is a distributed systeme. Distribution is in the eye of the b

深入理解計算機系統 第三章大略第五章大略

$0 一個 編譯 存儲器 系統 32位 做了 ++i 擴展 這2章總結的很少,主要是覺得沒那麽重要。 1.2個操作數的指令,第二個操作數通常是目的操作數:movb a b,move a to b,而add a b,b+=a,指令分為指令類,如mov類:movb,movw,m

深入理解計算機系統》關於csapp.hcsapp.c的編譯問題(轉)

系統 文件中 class net 工作 inux 而且 pan div 編譯步驟如下: 1.我的當前工作目錄為/home/sxh2/clinux,目錄下有3個文件inet_aton.c csapp.h csapp.c。 2.編譯csapp.c文件,命令為gcc -c csa

3.2《深入理解計算機系統》筆記(二)內存高速緩存的原理【插圖】

img sram 本質 text ddr rate too 是我 很大的 《深入計算機系統》筆記(一)主要是講解程序的構成、執行和控制。接下來就是運行了。我跳過了“處理器體系結構”和“優化程序性能”,這兩章的筆記繼續往後延遲! 《深入計算機系統》的一個很大的用處

深入理解計算機系統(2.4)------整數的表示(無符號編碼補碼編碼)

class 映射 們的 c語言 正數 裏的 小例子 負數 類型   上一篇博客我們主要介紹了布爾代數和C語言當中的幾個運算符。那麽這一篇博客我們主要介紹在計算機中整數是如何表示的,諸如我們在編碼過程中遇到的對數據類型進行強制轉換可能會得到意想不到的結果在這篇博客裏你會得到解

深入理解計算機系統(3.1)------匯編語言機器語言

找到 生產 有著 shu 符號 ces pc機 高效率 機器語言   《深入理解計算機系統》第三章——程序的機器級表示。作者首先講解了匯編代碼和機器代碼的關系,闡述了匯編承上啟下的作用;接著從機器語言IA32著手,分別講述了如何存儲數據、如何訪問數據

深入理解計算機系統(3.8)------數組分配訪問

2個 說明 add 如果 c++編譯 類型 操作 http 程序   上一篇博客我們講解了匯編語言中過程(函數)的調用實現。理解數據如何在調用者和被調用者之間傳遞,以及在被調用者當中局部變量內存的分配以及釋放是最重要的。那麽這篇博客我們將講解數組的分配和訪問。 1、

深入理解計算機系統(二)--信息的表示處理

科學 單獨 深入理解計算機系統 輔助 指針 值範圍 二進制表示 程序 不同的 一、信息的表示現代計算機中的信息都是使用二進制的數字進行表示,通常來說,單個的位不是非常有用,但是當把位組合在一起,再加上某種解釋,就能夠表示任何有限集合的元素。三種重要的數字表示:1、無符號編碼

信息的處理表示思維導圖 -讀《深入理解計算機系統

信息 nbsp 運算 思維導圖 計算 整數 深入理解計算機系統 布爾 image 總覽: 信息的存儲: 概念: 十六進制表示法: 字數據大小: 尋址和字節順序: 布爾代數: 浮點數: 整數表示: 整數運算

深入理解計算機系統 第二章 資訊的表示處理

  欣哥劃的重點: 第二章比較難,建議至少掌握下面幾個知識點: 1. 位元組順序 : 大端和小端 2. 執行 圖2-24, 圖2-25程式 show-bytes.c 觀察結果,看看有什麼問題 3. 理解布林運算,位運算 4. 理解無符號數和有符號數, 給一個數,能計算出補碼 5. 理解浮點數的表

深入理解計算機系統----資訊的表示處理

1、最小的可定址的記憶體單位是位元組,記憶體的每個位元組都由一個唯一的數字來標識,稱為地址,所有可能地址的集合稱為虛擬地址空間; 2、十六進位制數字0代表4個二進位制0;二進位制表示中,x=2的n次方就是1後面跟n個0;當n表示成i+4j的形式,可以把x寫成開頭的十六進位制數為1(i=0

深入理解計算機系統——程式結構執行

前言   第一部分 程式結構和執行    正文   1.資訊儲存   虛擬記憶體:是一個非常大的位元組陣列   記憶體的地址:記憶體的每個位元組都由一個唯一的數字來標識   虛擬地址空間:所有可能地址的集合      2.十六進位制的表示法    插播一下 進位制的轉化,(數學渣)會進位制

深入理解計算機系統 第二章資訊的表示儲存、

引言: 這一章我們研究在計算機上如何表示資料和其他型別資料的基本屬性,以及計算機對這些資料執行操作的屬性。在整數運算中,重點描述無符號數和數的補碼所表示的特性;而對於IEEE標準的浮點型資料,一是它是如何表示資料的,二是浮點運算的數學形式。 三種常見的資料型別:整數分為無符號數和有符號數。無

深入理解計算機系統》筆記——資訊的表示處理

資訊的儲存 十六進位制表示法 字 資料大小 定址和位元組順序 資料型別 字串的表示 程式碼的表示 資訊的儲存 資訊是客觀事物的反映,是經過處理加工後得出的資料。 資料是客觀事物的記錄。 計算機內所有的資訊均以二進位制的形式表示,

分散式一致性演算法2PC3PC

      為了解決分散式一致性問題,產生了不少經典的分散式一致性演算法,本文將介紹其中的2PC和3PC。2PC即Two-Phase Commit,譯為二階段提交協議。3PC即Three-Phase Commit,譯為三階段提交協議。   分散式系統和分散式一致性問題