漫話:如何給女友解釋什麼是2PC(二階段提交)?

週末晚上,正在家裏面看綜藝節目,忽然女友跑過來找我打《王者榮耀》。算法

打了幾把遊戲,終於能夠歇息一會了,準備繼續看個人綜藝,但是女友過來找我給他講講到底什麼是二階段提交。網絡

分佈式一致性

還好咱們以前專門給女友介紹過什麼是分佈式,要否則這個話題說來就話長了。分佈式

在以前介紹分佈式的時候,咱們以飯店的後廚爲例,今天繼續以前的例子來講說什麼是分佈式一致性。網站

隨着飯店的發展,慢慢的從只有一個廚師演變成有多個廚師,進而演變成有洗菜工、配菜師、廚師等多個職位。3d

當有了多種分工以後,就勢必須要協調這些人之間的合做。日誌

好比餐廳客人點了一份番茄炒蛋,而後後廚開始準備起來,洗菜工開始洗西紅柿,配菜師開始準備雞蛋,廚師開始向鍋內加油準備炒菜。這是一種很正常的狀況。cdn

可是,若是消息傳達的不到位,或者洗菜師傅臨時不在廚房等,就會致使有的人已經開始準備起來,可是有的人並無準備。blog

這就像是一個分佈式系統同樣的,當咱們在電商網站下單的時候,須要有多個分佈式服務同時服務,如支付系統進行支付、紅包系統進行紅包扣減、庫存系統扣減庫存、物流系統更新物流信息等。遊戲

可是,若是其中某一個系統在執行過程當中失敗了,或者因爲網絡緣由沒有收到請求,那麼,整個系統可能就有不一致的現象了,即:付了錢,扣了紅包,可是庫存沒有扣減。事務

這就是所謂的分佈式系統的數據一致性問題。

二階段提交

之因此剛剛的例子中會出現一致性問題,就是由於每個員工都只關注本身所作的事情,沒法關注到其餘人,那麼,要想保證總體的一致性,就須要在後廚中引入一個新的角色,負責統籌,這個角色來進行協調和調配全部人。

那麼,引入一個協調者負責協調全部參與者的工做,這個在分佈式系統中其實就是X/Open組織定義的分佈式事務處理模型,而二階段提交就是根據這一模型衍生出來的。

舉個例子,五我的相約打王者榮耀,想要一塊兒玩須要如下幾個步驟:

有一我的想要五黑玩王者榮耀,因而他開始聯繫本身的小夥伴們。

組織者:小A,咱們準備玩王者榮耀,你要是能夠來參加的話,如今你就登陸游戲,而後在遊戲好友上給我回復個消息。

小A登陸本身的遊戲帳號,而後告訴組織者:小A已就位。

組織者:小B、小C、小D,咱們準備玩王者榮耀,你要是能夠來參加的話,如今你就登陸游戲,而後在遊戲好友上給我回復個消息。

小B、小C、小D分別登陸本身的遊戲帳號,而後告訴組織者:小B、小C、小D已就位。

組織者發現全部人都就位了,因而在遊戲上逐一通知你們,

組織者:小A,我邀請你了,你進來吧。

小A接受邀請

組織者:小B、小C、小D,我邀請你了,你進來吧。

小小B、小C、小D接收邀請

因而,5我的在王者峽谷愉快的玩耍了起來。

對於五我的開黑這個事務操做,在開始準備前五我的都是空閒狀態,忙着本身的事情。在組織者協調過以後,你們也要達成一個一致的狀態,即如下兩種狀況之一:

  • 一、五我的愉快的開始一塊兒玩遊戲

  • 二、五我的都退出遊戲,仍是去忙本身的事情。

若是最後有一部分人在遊戲裏一直等,另一部分並無進入遊戲,那麼就是數據不一致了。

以上過程,就是一個典型的二階段提交(2PC)的過程,在分佈式系統中,也有一樣的問題,而且能夠採用一樣的解決辦法。

在分佈式系統中,每一個節點雖然能夠知曉本身的操做時成功或者失敗,卻沒法知道其餘節點的操做的成功或失敗(只知道本身有時間能夠玩王者榮耀,不知道其餘人有沒有)。

當一個事務跨越多個節點時,爲了保持事務的ACID特性,須要引入一個做爲協調者的組件來統一掌控全部參與者的操做結果並最終指示這些節點是否要把操做結果進行真正的提交(組織者通知各位參與者一塊兒進入遊戲房間)。

所以,二階段提交的算法思路能夠歸納爲:參與者將操做成敗通知協調者,再由協調者根據全部參與者的反饋情報決定各參與者是否要提交操做仍是停止操做。

所謂的兩個階段是指:第一階段:準備階段(投票階段)和第二階段:提交階段(執行階段)

準備階段

事務協調者給每一個參與者發送Prepare消息,每一個參與者要麼直接返回失敗(告知組織者本身沒時間,不能一塊兒玩遊戲),要麼在本地執行事務(登陸王者榮耀),但不提交(先不開始遊戲)。

能夠進一步將準備階段分爲如下三個步驟:

  • 1)協調者節點向全部參與者節點詢問是否能夠執行提交操做,並開始等待各參與者節點的響應。(詢問是否能夠一塊兒玩遊戲)

  • 2)參與者節點執行詢問發起爲止的全部事務操做,並將Undo信息和Redo信息寫入日誌。(登陸王者榮耀遊戲)

  • 3)各參與者節點響應協調者節點發起的詢問。若是參與者節點的事務操做實際執行成功,則它返回一個」贊成」消息;(告知組織者本身已經登陸成功)若是參與者節點的事務操做實際執行失敗,則它返回一個」停止」消息。(告知組織者本身暫時沒法一塊兒玩遊戲,如本身的帳號被限制沒法打排位)

提交階段

若是協調者收到了參與者的失敗消息或者超時(有人不能一塊兒玩遊戲,或者一直沒有回覆),直接給每一個參與者發送回滾消息(告知其餘人,暫時取消遊戲);不然,發送提交消息(邀請你們進入遊戲房間);參與者根據協調者的指令執行提交或者回滾操做(進入房間一塊兒玩遊戲或者退出遊戲去作別的事情)。

接下來分兩種狀況分別討論提交階段的過程。

當協調者節點從全部參與者節點得到的相應消息都爲」贊成」時:

  • 1)協調者節點向全部參與者節點發出」正式提交」的請求(要求全部已登陸的朋友加入遊戲房間)。

  • 2)參與者節點正式完成操做,並釋放在整個事務期間內佔用的資源(接受邀請,進入房間)。

  • 3)參與者節點向協調者節點發送」完成」消息(點擊"準備",進入準備狀態)。

  • 4)協調者節點受到全部參與者節點反饋的」完成」消息後,完成事務(進入王者峽谷)。

若是任一參與者節點在第一階段返回的響應消息爲」停止」,或者 協調者節點在第一階段的詢問超時以前沒法獲取全部參與者節點的響應消息時:

  • 1)協調者節點向全部參與者節點發出」回滾操做」的請求(告知全部人取消遊戲)。

  • 2)參與者節點利用以前寫入的Undo信息執行回滾,並釋放在整個事務期間內佔用的資源(退出遊戲,去作本身的事情)。

  • 3)參與者節點向協調者節點發送」回滾完成」消息(告訴組織者本身知道了,後面有機會再玩)。

  • 4)協調者節點受到全部參與者節點反饋的」回滾完成」消息後,取消事務(取消本次遊戲活動)。

2PC的缺點

以上過程實際上是有一些缺點的,如

一、當參與者收到組織者的消息以後,須要登陸游戲,在遊戲中等待組織者的再次邀請,這個過程比較浪費時間。

二、若是在這個過程當中,組織者忽然有什麼事情被打斷了,那麼那些已經進入遊戲的參與者就可能一直等下去。

三、在全部人都登陸游戲以後,組織者經過邀請要求全部人加入他的房間,這時候若是有一些網絡異常、或者參與者沒在手機前面等狀況,可能會有一部分用戶加入了房間,有一部分沒加入。

四、若是組織者在遊戲中開始邀請全部參與者的時候,他邀請了第一我的以後,他和這個被他邀請的人都掉線了。這時候另外三我的就不知道到底應該怎麼辦了。

以上問題,分佈式系統的2PC階段同樣存在,分別對應如下問題:

一、同步阻塞問題

執行過程當中,全部參與節點都是事務阻塞型的。當參與者佔有公共資源時,其餘第三方節點訪問公共資源不得不處於阻塞狀態。

二、單點故障

因爲協調者的重要性,一旦協調者發生故障。參與者會一直阻塞下去。尤爲在第二階段,協調者發生故障,那麼全部的參與者還都處於鎖定事務資源的狀態中,而沒法繼續完成事務操做。(若是是協調者掛掉,能夠從新選舉一個協調者,可是沒法解決由於協調者宕機致使的參與者處於阻塞狀態的問題)

三、數據不一致

在二階段提交的階段二中,當協調者向參與者發送commit請求以後,發生了局部網絡異常或者在發送commit請求過程當中協調者發生了故障,這回致使只有一部分參與者接受到了commit請求。而在這部分參與者接到commit請求以後就會執行commit操做。可是其餘部分未接到commit請求的機器則沒法執行事務提交。因而整個分佈式系統便出現了數據部一致性的現象。

四、二階段沒法解決的問題:

協調者再發出commit消息以後宕機,而惟一接收到這條消息的參與者同時也宕機了。那麼即便協調者經過選舉協議產生了新的協調者,這條事務的狀態也是不肯定的,沒人知道事務是否被已經提交。

總結一下,就是說2PC並非完美的,他存在着同步阻塞問題、單點故障問題、沒法100%保證數據一致性等問題。

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息