分佈式事務之2pc、3pc

2pc、3pc、paxos、raft都是解決分佈式系統中的一致性問題的。

一、兩個類型的一致性(操作原子性與副本一致性)

1.2pc、3pc協議用於保證屬於多個數據分片上的操作的原子性。這些數據分片可能分佈在不同的服務器上,2PC、3PC協議保證多臺服務器上的操作要麼全部成功,要麼全部失敗。

2.Paxos協議用於保證同一個數據分片的多個副本之間的數據一致性。當這些副本分佈到不同的數據中心時。Raft協議解決Paxos的實現難度

二、2PC

Two-Phase Commit,兩階段提交

1.階段一:Prepare準備階段

流程

(1)事務詢問

協調者向所有的參與者發送事務內容,詢問是否可以執行事務提交操作,並開始等待各參與者的響應

(2)執行事務

各參與者節點執行事務操作,並將Undo和Redo信息計入事務日誌中

(3)各參與者向協調者反饋事務詢問的響應

如果參與者成功執行了事務操作,那麼就反饋給協調者Yes響應,表示事務可以執行;

如果參與者沒有成功執行事務,那麼就反饋給協調者No響應,表示事務不可以執行。 

2.階段二:Commit事務提交階段

 第二階段,有兩種情況,第一種情況是提交事務,第二種情況是回滾事務。

2.1回滾事務

觸發情況:

(1)第一階段prepare階段,協調者收到了部分參與者ACK返回NO

(2)第一階段prepare階段,協調者沒收到部分參與者返回的ack

回滾流程:

1.rollback 請求 協調者向所有參與者發送 Rollback 請求。

2.事務回滾 參與者收到 Rollback 後,使用 Prepare 階段的 Undo 日誌執行事務回滾,完成後釋放事務執行期佔用的所有資源。

3.反饋結果 參與者執行事務回滾後向協調者發送 Ack 響應。

4.中斷事務 接收到所有參與者的 Ack 響應後,完成事務中斷。

2.2 正常提交事務

 觸發情況:

第一階段prepare階段,協調者收到了所有參與者的返送的ack:YES

提交流程:

1.commit 請求 協調者向所有參與者發送 Commit 請求。

2.事務提交 參與者收到 Commit 請求後,執行事務提交,提交完成後釋放事務執行期佔用的所有資源。

3.反饋結果 參與者執行事務提交後向協調者發送 Ack 響應。

4.完成事務 接收到所有參與者的 Ack 響應後,完成事務提交。

3. 2PC的問題

(1)同步阻塞

參與者在等待協調者的指令時,其實是在等待其他參與者的響應,在此過程中,參與者是無法進行其他操作的,也就是阻塞了其運行。 倘若參與者與協調者之間網絡異常導致參與者一直收不到協調者信息,那麼會導致參與者一直阻塞下去。

(2)單點問題

在 2PC 中,一切請求都來自協調者,所以協調者的地位是至關重要的,如果協調者宕機,那麼就會使參與者一直阻塞並一直佔用事務資源。

(3)數據不一致

(4)環境可靠性依賴

協調者 Prepare 請求發出後,等待響應,然而如果有參與者宕機或與協調者之間的網絡中斷,都會導致協調者無法收到所有參與者的響應,那麼在 2PC 中,協調者會等待一定時間,然後超時後,會觸發事務中斷,在這個過程中,協調者和所有其他參與者都是出於阻塞的。這種機制對網絡問題常見的現實環境來說太苛刻了。

4. 2PC出現問題的三種情況

(1)協調者正常,參與者宕機

​ 由於協調者無法收集到所有參與者的反饋,會陷入阻塞情況。

​ 解決方案:引入超時機制,如果協調者在超過指定的時間還沒有收到參與者的反饋,事務就失敗,向所有節點發送終止事務請求。

(2)協調者宕機,參與者正常

​ 無論處於哪個階段,由於協調者宕機,無法發送提交請求,所有處於執行了操作但是未提交狀態的參與者都會陷入阻塞情況.

​ 解決方案:引入協調者備份,同時協調者需記錄操作日誌.當檢測到協調者宕機一段時間後,協調者備份取代協調者,並讀取操作日誌,向所有參與者詢問狀態。

(3)協調者和參與者都宕機

1.發生在第一階段: 因爲第一階段,所有參與者都沒有真正執行commit,所以只需在剩餘的參與者中重新選出一個協調者,新的協調者在重新執行第一階段和第二階段就可以了。

2.發生在第二階段 並且 掛了的參與者在掛掉之前沒有收到協調者的指令。這可能是協調者還沒有發送commit就掛了。這種情形下,新的協調者重新執行第一階段和第二階段操作。

3.發生在第二階段 並且 有部分參與者已經執行完commit操作。就好比這裏訂單服務A和支付服務B都收到協調者 發送的commit信息,開始真正執行本地事務commit,但突發情況,Acommit成功,B確掛了。這個時候目前來講數據是不一致的。雖然這個時候可以再通過手段讓他和協調者通信,再想辦法把數據搞成一致的,但是,這段時間內他的數據狀態已經是不一致的了! 2PC 無法解決這個問題。

三、3PC

3PC 分爲三個階段:CanCommit,PreCommit 和 doCommit。

3PC主要是降低了2PC中的參與者阻塞的範圍:2PC中,當已經進入了第二階段(所有參與者都做完了事務邏輯但是還沒提交事務),但是協調者還沒來得及發送commit就崩潰了,參與者不能做出最後的選擇,導致參與者只能在協調者恢復之前一直保持阻塞。

在2PC的基礎上3PC做的改動:

1、 引入超時機制。同時在協調者和參與者中都引入超時機制。 (原來2PC的時候,只有協調者收不全ACK纔有超時機制,參與者不能因等待命令超時而做出什麼動作)

2、在第一階段和第二階段中插入一個準備階段。保證了在最後提交階段之前各參與節點的狀態是一致的。

1.階段一 CanCommit階段

流程:

(1)事務詢問

協調者向所有參與者發送事務 canCommit 請求,請求中包含事務內容,詢問是否可以執行事務提交操作,並開始等待響應。

(2)反饋詢問結果

參與者收到 canCommit 請求後,分析事務內容,判斷自身是否可以執行事務,如果可以(獲取事務需要的資源,比如嘗試獲取數據庫鎖),那麼就返回 Yes 響應,進入預備狀態。

否則返回 No 響應。

注意:此過程中並沒有執行事務(對比 2PC 的 Prepare 階段,參與者是執行了事務的)。

觸發協調者發送中斷事務命令的異常情況:

(1)協調者發送了CanCommit後,協調者收到了部分參與者ACK返回NO

(2)協調者發送了CanCommit後,協調者沒收到部分參與者返回的ack

2.階段二 PreCommit階段

PreCommit 階段根據各參與者返回的 CanCommit 響應,決定下一步動作。如果收到了所有參與者的 Yes 響應,則執行事務預提交,否則(收到了至少一個 No 響應或一定時長內沒有收到所有參與者的 Yes 響應),執行事務中斷。

事務預提交流程:

1.發送 PreCommit 請求 協調者發送 PreCommit 請求,並進入 Prepared 階段。

2.參與者處理 PreCommit 參與者收到 PreCommit 請求後,執行事務操作,並將 Undo 和 Redo 信息記錄事務日誌中。

3.反饋執行結果 如果參與者成功執行了事務並寫入 Undo 和 Redo 信息,那麼反饋 Ack 給協調者,並等待下一步指令。

觸發協調者發送中斷事務命令的異常情況:

(1)協調者發送了PreCommit後,協調者收到了部分參與者ACK返回NO

(2)協調者發送了PreCommit後,協調者沒收到部分參與者返回的ack

 觸發參與者自己中斷事務的異常情況:

(1)參與者等待PreCommit命令等待超時

3.階段三  DoCommit階段 

流程:

1、發送提交請求
假設協調者正常工作,接收到了所有參與者的ack響應,那麼它將從預提交階段進入提交狀態,並向所有參與者發送doCommit請求

2、事務提交
參與者收到doCommit請求後,正式提交事務,並在完成事務提交後釋放佔用的資源

3、反饋事務提交結果
參與者完成事務提交後,向協調者發送ACK信息

4、完成事務
協調者接收到所有參與者ack信息,完成事務

觸發協調者發送中斷事務命令的異常情況:

(1)協調者發送了DoCommit後,協調者收到了部分參與者ACK返回NO

(2)協調者發送了DoCommit後,協調者沒收到部分參與者返回的ack

 觸發參與者自己提交/中斷事務的異常情況:

(1)協調者出現問題、協調者與參與者之間網絡出現故障等情況,導致參與者無法及時接收到來自協調者的doCommit或是abort請求時。

如果參與者在PreCommit階段執行失敗了給協調者回復的ACK=NO,則參與者在等待超時後自己中斷事務。

如果參與者在PreCommit階段執行成功了給協調者回復的ACK=YES,則參與者在等待超時後自己繼續進行事務提交。

 4、3PC的優缺點

優點:

1.降低了阻塞

參與者返回 CanCommit 請求的響應後,等待第二階段指令,若等待超時,則自動 abort,降低了阻塞;

參與者返回 PreCommit 請求的響應後,等待第三階段指令,若等待超時,則自動 commit 事務,也降低了阻塞;

2.解決單點故障問題

參與者返回 CanCommit 請求的響應後,等待第二階段指令,若協調者宕機,等待超時後自動 abort,;

參與者返回 PreCommit 請求的響應後,等待第三階段指令,若協調者宕機,等待超時後自動 commit 事務;

缺點:

 數據不一致問題仍然是存在的,比如第三階段協調者發出了 abort 請求,然後有些參與者沒有收到 abort,那麼就會自動 commit,造成數據不一致。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章