2PC和3PC协议
2PC和3PC協議
目錄
在分布式系統中,每個機器節點雖然能夠明確知道自己在進行事務操作過程中的結果是成功或失敗,但卻無法直接獲取其他分布式節點的操作結果。因此,當一個事務操作需要跨越多個分布式節點的時候,為了保持事務處理的ACID特性,就需要引入一個稱為“協調者(Coordinator)”的組件來統一調度所有分布式節點的執行邏輯,這些被調度的分布式節點則被稱為“參與者(Participant)”。協調者負責調度參與者的行為,并最終決定這些參與者是否要把事務真正進行提交。基于這個思想,衍生出了二階段提交和三階段提交兩種協議。
1. 2PC
2PC,是 Two-Phase Commit 的縮寫,即二階段提交。是計算機網絡尤其是在數據庫領域內,為了使基于分布式系統架構下的所有節點在進行事務處理過程中能保持原子性和一致性而設計的一種算法。二階段提交也被認為是一種一致性協議,用來保證分布式數據的一致性。
協議說明
二階段提交協議將事務的提交過程分成了兩個階段來進行處理,其執行流程如下。
階段一:提交事務請求
協調者向所有的參與者發送事務內容,詢問是否可以執行事務提交操作,并開始等待各參與者的響應。
各參與者節點執行事務操作,并將 Undo 和 Redo 信息記入事務日志中。
如果參與者成功執行了事務操作,那么就反饋給協調者 Yes 響應,表示事務可以執行;如果參與者沒有成功執行事務,那么就反饋給協調者 No 響應,表示事務不可以執行。
上述內容近似協調者組織各參與者對一次事務操作的投票表態過程,因此二階段提交協議的階段一也被稱為“投票階段”,即各參與者投票表明是否要繼續執行接下來的事務提交操作。
階段二:執行事務提交
在階段二中協調者會根據各參與者的反饋情況來決定最終是否可以進行事務提交操作,在正常情況下,包含以下兩種可能。
執行事務提交
假設協調者從所有的參與者獲取的反饋都是 Yes 響應,那么就會執行事務提交。
協調者向所有參與者節點發送 Commit 請求。
參與者接收到 Commit 請求后,會正式執行事務提交操作,并在完成提交之后釋放在正式事務執行期間占用的資源。
參與者在完成事務提交之后,向協調者發送 Ack 消息。
協調者接收到所有參與者反饋的 Ack 消息后,完成事務。
中斷事務
假設任何一個參與者向協調者反饋 No 響應,或者在等待超時之后,協調者尚無法接受到所有參與者的反饋響應,那么就會中斷事務。
協調者向所有的參與者發送 Rollback 請求。
參與者接受到 Rollback 請求后,會利用其在階段一中記錄的 Undo 信息來執行事務回滾操作,并在完成回滾之后釋放在整個事務執行期間占用的資源。
參與者在完成事務回滾之后,向協調者發送 Ack 消息。
協調者接受到所有參與者反饋的 Ack 消息后,完成事務中斷。
以上就是二階段提交的過程中,前后兩個階段分別進行的處理邏輯。簡單來講,二階段提交將一個事務的處理過程分為了投票和執行兩個階段,其核心是對每個事務都采用先嘗試提交的處理方式,因此也可以將二階段提交看做一個強一致性的算法。
下圖展示了二階段提交過程中“事務提交”和“事務中斷”兩種場景下的交互流程。
優缺點
二階段提交協議的優點:原理簡單,實現方便。
二階段提交協議的缺點:同步阻塞,單點問題,腦裂,太過保守。
-
同步阻塞
二階段提交協議存在的最明顯也是最大的一個問題就是同步阻塞,這會極大地限制分布式系統的性能。在二階段提交的執行過程中,所有參與該事務操作的邏輯都處于阻塞狀態,也就是說,各個參與者在等待其他參與者響應過程中,將無法進行其他任何操作。 -
單點問題
一旦協調者出現問題,那么整個二階段提交流程將無法運轉,更為嚴重的是,如果協調者是在階段二中出現問題的話,那么其他參與者將會一直處于鎖定事務資源的狀態中,無法繼續完成事務操作。 -
數據不一致
在二階段提交協議的階段二,即執行事務提交的時候,當協調者向所有的參與者發送 Commit 請求之后,發生了局部網絡異常或者是協調者在尚未發送完 Commit 請求之前自身發送了崩潰,導致最終只有部分參與者收到了 Commit請求。于是,這部分收到了 Commit 請求的參與者就會進行事務的提交,而其他沒有收到 Commit 請求的參與者則無法進行事務提交,于是整個分布式系統就會出現數據不一致現象。 -
太過保守
如果在協調者指示參與者進行事務提交詢問的過程中,參與者出現故障而導致協調者始終無法獲取到所有參與者的響應信息的話,這時協調者只能依靠自身的超時機制來判斷是否需要中斷事務,這樣的策略顯得比較保守。換句話說,二階段提交協議沒有涉及較為完善的容錯機制,任意一個節點的失敗都會導致整個事務的失敗。
2. 3PC
了解二階段提交協議的設計和實現原理,并明確指出了其在實際運行過程中可能存在諸多問題,比如同步阻塞、協調者的單點問題、腦裂和太過保守的容錯機制等缺陷,因此研究者在二階段提交協議的基礎上進行了改進,提出了三階段提交協議。
協議說明
3PC,是 Three-Phase Commit 的縮寫,即三階段提交,是 2PC 的改進版,其將二階段提交協議的“提交事務請求”過程一分為二,形成了 canCommit,preCommit 和 doCommit三個階段組成的事務處理協議,協議設計圖如下:
階段一:canCommit
事務詢問。
協調者向所有的參與者發送一個包含事務內容的 canCommit 請求,詢問是否可以執行事務提交操作,并開始等待各參與者的響應。
各參與者向協調者反饋事務詢問的響應。
參與者在接收到來自協調者的 canCommit 請求后,正常情況下,如果其自身認為可以順利執行任務,那么就會反饋 Yes 響應,并進入預備狀態,否則反饋 No 響應。
階段二:preCommit
在階段二,協調者會根據各參與者的反饋情況來決定是否進行事務的 PreCommit 操作,正常情況下,包含兩種可能。
執行事務預提交
假如協調者從所有的參與者獲得的反饋都是 Yes,那么就會執行事務預提交。
協調者向所有參與者節點發出 preCommit 請求,并進入 Prepared 階段。
參與者接收到 preCommit 請求后,會執行事務操作,并將 Undo 和 Redo 信息記錄到事務日志中。
如果參與者成功執行了事務操作,那么就會反饋給協調者 Ack 響應,同時等待最終的指令:提交(commit)或中止(abort)。
中斷事務
假如任何一個參與者向協調者反饋了 No 響應,或者在等待超時之后,協調者尚無法接受到所有參與者的反饋響應,那么就會中斷事務。
協調者向所有的參與者節點發送 abort 請求。
無論是收到來自協調者的 abort 請求,或者是在等待協調者請求過程中出現超時,參與者都會中斷事務。
階段三:doCommit
該階段將進行真正的事務提交,會存在以下兩種可能的情況。
執行提交
進入這一階段,假設協調者處于正常工作狀態,并且它接收到了來自所有參與者的 Ack 響應,那么它將從“預提交”狀態轉換到“提交”狀態,并向所有的參與者發送 doCommit 請求。
參與者接收到 doCommit 請求后,會正式執行事務提交操作,并在完成提交之后釋放在整個事務執行期間占用的事務資源。
參與者在完成事務提交之后,向協調者發送 Ack 消息。
協調者接收到所有參與者反饋的 Ack 消息后,完成事務。
中斷事務
進入這一階段,假設協調者處于正常工作狀態,并且有任意一個參與者向協調者反饋了 No 響應,或者在等待超時之后,協調者尚無法接收到所有參與者的反饋響應,那么就會中斷事務。
協調者向所有的參與者節點發送 abort 請求。
參與者接收到 abort 請求后,會利用其在階段二中記錄的 Undo 信息來執行回滾操作,并在完成回滾之后釋放在整個事務執行期間占用的資源。
參與者在完成事務回滾之后,向協調者發送 Ack 消息。
協調者接收到所有參與者反饋的 Ack 消息后,中斷事務。
需要注意的是,一旦進入階段三,可能會存在以下兩種故障。
- 協調者出現問題。
- 協調者和參與者之間的網絡出現故障。
無論哪種情況,最終都會導致參與者無法及時接收來自協調者的 doCommit 或是 abort 請求,針對這樣的異常情況,參與者都會在等待超時之后,繼續進行事務提交。
優缺點
三階段提交協議的優點:相較于二階段提交協議,三階段提交協議最大的優點就是降低了參與者的阻塞范圍,并且能夠在出現單點故障后繼續達成一致。
三階段提交協議的缺點:三階段提交協議在去除阻塞的同時也引入了新的問題,那就是在參與者接收到 preCommit 消息后,如果網絡出現分區,此時協調者所在的節點和參與者無法進行正常網絡通信,在這種情況下,該參與者依然會進行事務的提交,這必然會出現數據的不一致。
總結
- 上一篇: MySQL索引知识点
- 下一篇: Zookeeper 的 ZAB 协议