分布式理論基礎(一)一致性及解決一致性的兩種方式:2PC和3PC


1 一致性

1.1 簡述

一致性,是指對每個節點一個數據的更新,整個集群都知道更新,並且是一致的

假設一個具有N個節點的分布式系統,當其滿足以下條件時,我們說這個系統滿足一致性:

  • 全認同: 所有N個節點都認同一個結果
  • 值合法: 該結果必須由N個節點中的過半節點提出
  • 可結束: 決議過程在一定時間內結束,不會無休止地進行下去

 1.2 面臨着的問題

  • 消息傳遞異步無序: 現實網絡不是一個可靠的信道,存在消息延時、丟失,節點間消息傳遞做不到同步有序
  • 節點宕機: 節點持續宕機,不會恢復
  • 節點宕機恢復: 節點宕機一段時間后恢復,在分布式系統中最常見
  • 網絡分化: 網絡鏈路出現問題,將N個節點隔離成多個部分
  • 拜占庭將軍問題: 節點或宕機或邏輯失敗,甚至不按套路出牌拋出干擾決議的信息

假設現實場景中也存在這樣的問題:

周五 我:晚上下班吃雞 周六凌晨 xc:好的 // 消息延遲
我:... --------------------------------- 我:晚上下班吃雞 xc:No (兩小時后) xc:No problem! // 宕機節點恢復
我:... --------------------------------- 我:晚上下班吃雞 ... // 節點宕機

--------------------------------- 我:晚上下班吃雞 cx:好,我們去大保健! // 拜占庭將軍
我:...

 

 

2 2PC

2.1 簡述

2PC(tow phase commit)兩階段提交。

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

我們將提議的節點稱為協調者(coordinator),其他參與決議節點稱為參與者(participants, 或cohorts)。

 

2.2 階段1

在階段1中,協調者發起一個提議,分別問詢各參與者是否接受,如下圖:

 

 

 

2.3 階段2

在階段2中,協調者根據參與者的反饋,提交或中止事務,如果參與者全部同意則提交,只要有一個參與者不同意就中止。

如下圖:

 

 

2.4 實例

下面我們通過一個例子來說明兩階段提交協議的工作過程:

A組織B、C和D三個人去爬山:如果所有人都同意去爬山,那么活動將舉行;如果有一人不同意去爬山,那么活動將取消。用2PC算法解決該問題的過程如下:

首先A將成為該活動的協調者,B、C和D將成為該活動的參與者。

階段1:

  ①A發郵件給B、C和D,提出下周三去爬山,問是否同意。那么此時A需要等待B、C和D的郵件。

  ②B、C和D分別查看自己的日程安排表。B、C發現自己在當日沒有活動安排,則發郵件告訴A它們同意下周三去爬山。由於某種原因, D白天沒有查看郵 件。那么此時A、B和C均需要等待。到晚上的時候,D發現了A的郵件,然后查看日程安排,發現周三當天已經有別的安排,那么D回復A說活動取消吧。

階段2:

  ①此時A收到了所有活動參與者的郵件,並且A發現D下周三不能去爬山。那么A將發郵件通知B、C和D,下周三爬山活動取消。

  ②此時B、C回復A“太可惜了”,D回復A“不好意思”。至此該事務終止。

 

2.5 優缺點

在異步環境並且沒有節點宕機的模型下,2PC可以滿足全認同、值合法、可結束,是解決一致性問題的一種協議。從協調者接收到一次事務請求、發起提議到事務完成,經過2PC協議后增加了2次RTT(propose+commit),帶來的時延增加相對較少。

二階段提交有幾個缺點:

  • 同步阻塞問題。執行過程中,所有參與節點都是事務阻塞型的。當參與者占有公共資源時,其他第三方節點訪問公共資源不得不處於阻塞狀態。
  • 單點故障。由於協調者的重要性,一旦協調者發生故障。參與者會一直阻塞下去。尤其在第二階段,協調者發生故障,那么所有的參與者還都處於鎖定事務資源的狀態中,而無法繼續完成事務操作。(如果是協調者掛掉,可以重新選舉一個協調者,但是無法解決因為協調者宕機導致的參與者處於阻塞狀態的問題)
  • 數據不一致。在二階段提交的階段二中,當協調者向參與者發送commit請求之后,發生了局部網絡異常或者在發送commit請求過程中協調者發生了故障,這回導致只有一部分參與者接受到了commit請求。而在這部分參與者接到commit請求之后就會執行commit操作。但是其他部分未接到commit請求的機器則無法執行事務提交。於是整個分布式系統便出現了數據部一致性的現象。
  • 二階段無法解決的問題:協調者再發出commit消息之后宕機,而唯一接收到這條消息的參與者同時也宕機了。那么即使協調者通過選舉協議產生了新的協調者,這條事務的狀態也是不確定的,沒人知道事務是否被已經提交。

 

2.6 2pc的衍生

2PC協議包含協調者和參與者,並且二者都有發生問題的可能性。假如協調者發生問題,我們可以選出另一個協調者來提交事務。例如,班長組織活動,如果班長生病了,我們可以請副班長來組織。如果協調者出問題,那么事務將不會取消。例如,班級活動希望每個人都能去,假如有一位同學不能去了,那么直接取消活動即可。或者,如果大多數人去的話那么活動如期舉行(2PC變種)。

 

3 3pc

3.1 簡述

三階段提交(Three-phase commit),是二階段提交(2PC)的改進版本。

與兩階段提交不同的是,三階段提交有兩個改動點。

  • 引入超時機制。同時在協調者和參與者中都引入超時機制。
  • 在第一階段和第二階段中插入一個准備階段。保證了在最后提交階段之前各參與節點的狀態是一致的。

 也就是說,除了引入超時機制之外,3PC把2PC的准備階段再次一分為二,這樣三階段提交就有CanCommitPreCommitDoCommit三個階段。

 

3.2 CanCommit階段

3PC的CanCommit階段其實和2PC的准備階段很像。協調者向參與者發送commit請求,參與者如果可以提交就返回Yes響應,否則返回No響應。

  • 事務詢問 協調者向參與者發送CanCommit請求。詢問是否可以執行事務提交操作。然后開始等待參與者的響應。
  • 響應反饋 參與者接到CanCommit請求之后,正常情況下,如果其自身認為可以順利執行事務,則返回Yes響應,並進入預備狀態。否則反饋No

 

3.3 PreCommit階段

協調者根據參與者的反應情況來決定是否可以記性事務的PreCommit操作。根據響應情況,有以下兩種可能。

假如協調者從所有的參與者獲得的反饋都是Yes響應,那么就會執行事務的預執行。

  • 發送預提交請求 協調者向參與者發送PreCommit請求,並進入Prepared階段。
  • 事務預提交 參與者接收到PreCommit請求后,會執行事務操作,並將undo和redo信息記錄到事務日志中。
  • 響應反饋 如果參與者成功的執行了事務操作,則返回ACK響應,同時開始等待最終指令。

假如有任何一個參與者向協調者發送了No響應,或者等待超時之后,協調者都沒有接到參與者的響應,那么就執行事務的中斷。

  • 發送中斷請求 協調者向所有參與者發送abort請求。
  • 中斷事務 參與者收到來自協調者的abort請求之后(或超時之后,仍未收到協調者的請求),執行事務的中斷。

 

3.4 doCommit階段

該階段進行真正的事務提交,也可以分為以下兩種情況。

執行提交

  • 發送提交請求 協調接收到參與者發送的ACK響應,那么他將從預提交狀態進入到提交狀態。並向所有參與者發送doCommit請求。
  • 事務提交 參與者接收到doCommit請求之后,執行正式的事務提交。並在完成事務提交之后釋放所有事務資源。
  • 響應反饋 事務提交完之后,向協調者發送Ack響應。
  • 完成事務 協調者接收到所有參與者的ack響應之后,完成事務。

中斷事務

協調者沒有接收到參與者發送的ACK響應(可能是接受者發送的不是ACK響應,也可能響應超時),那么就會執行中斷事務。

  • 發送中斷請求 協調者向所有參與者發送abort請求
  • 事務回滾 參與者接收到abort請求之后,利用其在階段二記錄的undo信息來執行事務的回滾操作,並在完成回滾之后釋放所有的事務資源。
  • 反饋結果 參與者完成事務回滾之后,向協調者發送ACK消息
  • 中斷事務 協調者接收到參與者反饋的ACK消息之后,執行事務的中斷。

 

3.5 2pc和3pc的區別

相對於2PC,3PC主要解決的單點故障問題,並減少阻塞,因為一旦參與者無法及時收到來自協調者的信息之后,他會默認執行commit。而不會一直持有事務資源並處於阻塞狀態。但是這種機制也會導致數據一致性問題,因為,由於網絡原因,協調者發送的abort響應沒有及時被參與者接收到,那么參與者在等待超時之后執行了commit操作。這樣就和其他接到abort命令並執行回滾的參與者之間存在數據不一致的情況。

在2PC中一個參與者的狀態只有它自己和協調者知曉,假如協調者提議后自身宕機,在協調者備份啟用前一個參與者又宕機,其他參與者就會進入既不能回滾、又不能強制commit的阻塞狀態,直到參與者宕機恢復。

參與者如果在不同階段宕機,我們來看看3PC如何應對:

  • 階段1: 協調者或協調者備份未收到宕機參與者的vote,直接中止事務;宕機的參與者恢復后,讀取logging發現未發出贊成vote,自行中止該次事務
  • 階段2: 協調者未收到宕機參與者的precommit ACK,但因為之前已經收到了宕機參與者的贊成反饋(不然也不會進入到階段2),協調者進行commit;協調者備份可以通過問詢其他參與者獲得這些信息,過程同理;宕機的參與者恢復后發現收到precommit或已經發出贊成vote,則自行commit該次事務
  • 階段3: 即便協調者或協調者備份未收到宕機參與者t的commit ACK,也結束該次事務;宕機的參與者恢復后發現收到commit或者precommit,也將自行commit該次事務

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM