參考
http://www.javashuo.com/article/p-tciejkkc-ko.htmlhtml
http://www.javashuo.com/article/p-cbmjybgy-da.html算法
http://www.javashuo.com/article/p-derlvkbc-gc.html數據庫
在分佈式系統中,每個機器節點雖然都可以明確地知道本身在進行事務操做過程當中的結果是成功或失敗,但卻沒法直接獲取到其餘分佈式節點的操做結果.所以,當一個事務操做須要跨越多個分佈式節點的時候,爲了保持事務處理的ACID特性,就須要引入一個稱爲協調者(Coordinator)的組件來統一調度全部分佈式節點的執行邏輯,這些調度的分佈式節點則被稱爲參與者(Participant).協調者負責調用參與者的行爲,並最終決定這些參與者是否要把事務真正進行提交.網絡
基於這個思想,衍生出了二階段提交(2PC)和三階段提交(3PC)兩種協議.架構
2PC
2PC,是Two-Phase Commit的縮寫,即二階段提交,是計算機網絡尤爲是在數據庫領域內,爲了是基於分佈式系統架構下的全部節點在進行事務處理過程當中可以保持原子性和一致性而設計的一種算法.分佈式
一般,二階段提交協議也被認爲是一種一致性協議,用來保證分佈式系統數據的一致性.spa
目前,絕大部分的關係型數據庫都是採用二階段提交協議來完成事務處理的,利用該協議可以很是方便地完成全部分佈式事務參與者的協調,統一決定事務的提交或回滾,從而可以有效地保證分佈式數據一致性,所以二階段提交協議被普遍的應用在許多分佈式系統中..net
階段一: 提交事務請求(投票階段)
- 事務詢問
協調者向全部的參與者發送事務內容,詢問是否能夠執行事務提交操做,並開始等待各參與者的響應.
- 執行事務
各參與者節點執行事務操做,
並將Undo和Redo信息記入事務日誌中.
- 各參與者向協調者反饋事務詢問的響應
若是參與者成功執行了事務操做,那麼就反饋給協調者Yes響應,表示事務能夠執行;若是參與者沒有成功執行事務,那麼就反饋給協調者No響應,表示事務不能夠執行.
階段二: 執行事務提交(執行階段)
在階段二中, 協調者會根據各參與者的反饋狀況來決定最終是否能夠進行事務提交的操做,正常狀況下,包含如下兩種可能.計算機網絡
執行事務提交
假設協調者從全部的參與者得到的反饋都是Yes響應,那麼就會執行事務提交.
- 發送提交請求
協調者向全部參與者節點發出Commit請求.
- 事務提交反饋事務
參與者接收到Commit請求後,會正式執行事務提交操做,並在完成提交以後釋放在整個事務執行期間佔用的事務資源.
- 提交結果
參與者在完成事務提交以後,向協調者發送Ack消息.
- 完成事務
協調者接收到全部參與者反饋的Ack消息後,完成事務.
中斷事務
假如任何一個參與者向協調者反饋了No響應,或者在等待超時以後,協調者尚沒法接收到全部參與者的反饋響應,那麼就會中斷事務.設計
- 發送回滾請求
協調者向全部參與者節點發出Rollback請求.
- 事務回滾
參與者接收到Rollback請求後,會利用其在階段一中記錄的Undo信息來執行事務回滾操做,並在完成回滾以後釋放在整個事務執行期間佔用的資源.
- 反饋事務回滾結果
參與者在完成事務回滾以後,向協調者發送Ack消息.
- 中斷事務
協調者接收到全部參與者反饋的Ack消息後,完成事務中斷.
階段二故障分析
只分析協調者和參與者都掛掉的狀況
scene1:存在參與者執行了commit(或rollback)操做
scene2:問了一圈參與者都是未開始commit(或rollback)
總結
簡單地講,二階段提交將一個事務的處理過程分爲了投票和執行兩個階段,其核心是對每一個事務都採用先嚐試後提交的處理方式,所以也能夠將二階段提交看作一個強一致性的算法.
優勢
原理簡單,實現方便
缺點
- 同步阻塞
在二階段提交的執行過程當中,全部參與該事務操做的邏輯都處於阻塞狀態,也就是說,各個參與者在等待其餘參與者響應的過程當中,將沒法進行其餘任何操做.
- 單點問題
一旦協調者出現問題,那麼整個二階段提交流程將沒法運轉,更爲嚴重的是,若是協調者是在階段二中出現問題的話,那麼其餘參與者將會一直處於事務資源的狀態中,而沒法繼續完成事務操做.
- 數據不一致
可能發生只有部分參與者接收到了Commit請求,因而這部分收到了Commit請求的參與者就會進行事務提交,而其餘沒有收到Commit請求的參與者則沒法進行事務提交,因而整個分佈式系統便出現了數據不一致現象.
- 太過保守
二階段提交協議沒有設計較爲完善的容錯機制,任意一個節點的失敗都會致使整個事務的失敗.
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
該階段將進行真正的事務提交,會存在兩種可能的狀況.
須要注意的是,一旦進入階段三,可能會存在如下兩種故障.
- 協調者出現問題
- 協調者和參與者之間的網絡出現故障
不管出現哪一種狀況,最終都會致使參與者沒法及時接收到來自協調者的doCommit或是abort請求,針對這樣的異常狀況,參與者都會在等待超時以後,繼續進行事務提交.
執行提交
- 發送提交請求
進入這一階段,假設協調者處於正常工做狀態,而且它接收到了來自全部參與者的Ack響應,那麼它將從預提交狀態轉換到提交狀態,並向全部的參與者發送doCommit請求
- 事務提交
參與者接收到doCommit請求後,會正式執行事務提交操做,並在完成提交以後釋放在整個事務執行期間佔用的事務資源
- 反饋事務提交結果
參與者在完成事務提交以後,向協調者發送Ack消息
- 完成事務
協調者接收到全部參與者反饋的Ack消息後,完成事務
中斷事務
進入這一階段,假設協調者處於正常工做狀態,而且有任意一個參與者向協調者反饋了No響應,或者在等待超時以後,協調者尚沒法接收到全部參與者的反饋響應,那麼就會中斷事務.
- 發送中斷請求
協調者向全部的參與者節點發送Abort請求
- 事務回滾
參與者接收到Abort請求後,會利用其在階段二中記錄的Undo信息來執行事務回滾操做,並在完成回滾以後釋放在整個事務執行期間佔用的資源
- 反饋事務回滾結果
參與者在完成事務回滾以後,向協調者發送Ack消息
- 中斷事務
協調者接收到全部從參與者反饋的Ack消息後,中斷事務
總結
優勢
相較於二階段提交協議,三階段提交協議最大的優勢就是下降了參與者的阻塞範圍,而且可以在出現單點故障後繼續達成一致.
缺點
三階段提交協議在去除阻塞的同時也引入了新的問題,那就是在參與者接收到PreCommit消息後,若是網絡出現分區,此時協調者所在的節點和參與者沒法進行正常的通訊,在這種狀況下,該參與者依然會進行事務提交,這必然會出現數據的不一致性.