2PC與3PC
在分散式系統中,每一個機器節點雖然都能夠明確地知道自己在進行事務操作過程中的結果是成功或失敗,但卻無法直接獲取到其他分散式節點的操作結果。因此,當一個事務操作需要跨越多個分散式節點的時候,為了保持事務處理的ACID特性,就需要引入一個稱為"協調者(Coordinator)"的元件來統一排程所有分散式節點的執行邏輯,這些被排程的分散式節點則被稱為"參與者(Participant)"。協調者負責排程參與者的行為,並最終決定這些參與者是否要把事務真正提交。基於這種思想,衍生出了二階段提交和三階段提交兩種協議,下面先講講二階段提交和三階段提交。
2PC
2PC,是Two-Phase Commit的縮寫,即二階段提交,是計算機網路尤其是在資料庫領域內,為了使基於分散式系統架構下的所有節點在進行事務處理過程中能夠保持原子性和一致性而設計的一種演算法。通常,二階段提交協議也被認為是一種一致性協議,用來保證分散式系統資料的一致性。目前絕大部分的關係型資料庫都是採用二階段提交協議來完成分散式事務處理的,利用該協議能夠非常方便地完成所有分散式事務參與者的協調,統一決定事務的提交或回滾,從而能夠有效地保證分散式資料一致性,因此二階段提交協議被廣泛地應用在許多分散式系統中。
1、階段一:提交事物請求
(1)事務詢問
協調者向所有參與者傳送事務內容,詢問是否可以執行事務提交操作,並開始等待各個參與者的響應
(2)執行事務
各參與者節點執行事務操作,並將Undo和Redo資訊記入事務日誌中
(3)各個參與者向協調者反饋事務詢問的響應
如果參與者成功執行了事務操作,那麼就反饋給協調者Yes響應,表示事務可以執行;如果參與者沒有成功執行事務,那麼就反饋給協調者No響應,表示事務不可以執行
由於上面講述的內容在形式上近似是協調者組織各參與者對一次事務操作的投票表態過程,因此二階段提交協議的階段一也被稱為"投票階段",即各參與者投票表明是否要繼續執行接下去的事務提交操作
2、階段二:執行事務提交
在階段二中協調者會根據各參與者的反饋來決定是否最終可以進行事務提交操作,正常情況下包含兩種可能:
(1)執行事務提交
假如協調者從所有的參與者獲得的反饋都是Yes響應,那麼就會執行事務提交:
a)傳送提交請求
協調者向所有參與者節點發出Commit請求
b)事務提交
參與者收到Commit請求後會正式執行事務提交操作,並在完成提交之後釋放整個事務執行期間佔用的事務資源
c)反饋事務提交操作
參與者在完成事務提交之後,向協調者傳送Ack訊息
d)完成事務
協調者收到所有參與反饋的Ack訊息後完成事務
(2)中斷事務
假如任何一個參與者向協調者反饋了No響應,或者在等待超時之後,協調者尚無法接收到所有參與者的反饋響應,那麼就會中斷事物。
a)傳送回滾請求
協調者向所有參與者節點發出Rollback請求
b)事物回滾
參與者接收到Rollback請求後,會利用其在階段一中記錄的Undo資訊來執行事務回滾操作,並在完成回滾之後釋放在整個事物執行期間佔用的資源
c)反饋事務回滾結果
參與者在完成事物回滾之後,向協調者傳送Ack訊息
d)中斷事物
協調者接收到所有參與者反饋的Ack訊息後,完成事物中斷
以上就是二階段提交過程中,前後兩個階段分別進行的處理邏輯。簡單講,二階段提交嘗試講一個事物的處理過程分為了投票和執行兩個階段,其核心是對每個事物都採取先嚐試後提交的方式,因此也可以將二階段提交看作是一個強一致性的演算法。"事物提交"和"事物中斷"兩種場景分別如圖所示:
2PC的優缺點
1、二階段提交協議的優點:
原理簡單、實現方便
2、二階段提交協議的缺點,重點講一下:
(1)同步阻塞
二階段提交協議存在的最明顯也是最大的一個問題就是同步阻塞,這會極大地限制分散式系統的效能。在二階段提交的執行過程中,所有參與該事物操作的邏輯都處於阻塞狀態,也就是說每個參與者在等待其他參與者響應的過程中,將無法進行其他任何操作
(2)單點問題
從上面的講解以及上圖中可以看出,協調者的角色在整個二階段提交協議中起到了非常重要的作用。一旦協調者出現問題,那麼整個二階段提交流程將無法運轉,更為嚴重的是,如果協調者是在階段二中出現問題的話,那麼其他參與者將一直處於鎖定事物資源的狀態中,而無法繼續完成事物操作
(3)資料不一致
在二階段提交協議的階段二,即執行事務提交的時候,當協調者向所有的參與者傳送Commit請求之後,發生了區域性網路異常或者是協調者在尚未傳送完Commit請求之前自身發生了崩潰,導致最終只有部分參與者收到了Commit請求。於是,這部分收到了Commit請求的參與者就會進行事務的提交,而其他沒有收到Commit請求的參與者則無法進行事物提交,於是整個分散式系統便出現了資料不一致的現象
(4)太過保守
如果在協調者指示參與者進行事務提交詢問的過程中,參與者出現故障而導致協調者始終無法獲取到所有參與者的響應的話,這時協調者只能依靠其自身的超時機制來判斷是否需要中斷事物,這樣的策略顯得比較保守。換句話說,二階段提交協議沒有設計較為完善的容錯機制,任意一個節點的失敗都會導致整個事物的失敗
3PC
2PC在其實際執行過程中可能存在諸如同步阻塞、協調者的單點問題、腦裂和太過保守的容錯機制等缺點,因此研究者在二階段提交協議的基礎上進行了改進,提出了三階段提交協議。
3PC,是Three-Phase Commit的縮寫,即三階段提交協議,是2PC的改進版本,其將二階段提交協議的"提交事物請求"過程一分為二,並形成了由CanCommit、PreCommit和do Commit三個階段組成的事物處理協議,從維基百科上拿一張圖下來看一下三階段提交協議流程示意圖,原圖地址為https://en.wikipedia.org/wiki/File:Three-phase_commit_diagram.png:
1、階段一:CanCommit
(1)事物詢問
協調者向所有的參與者傳送一個包含事物內容的canCommit請求,詢問是否可以執行事務提交操作,並開始等待各參與者的響應
(2)各參與者向協調者反饋事務詢問的響應
參與者在接收到來自協調者的canCommit請求後,正常情況下,如果其自身認為可以順利執行事務,那麼會反饋Yes響應,並進入預備狀態,否則反饋No響應
2、階段二:PreCommit
在階段二中,協調者會根據各參與者的反饋情況來決定是否可以進行事務的PreCommit操作,正常情況下,包含兩種可能:
(1)執行事務預提交
假如協調者從所有的參與者獲得的反饋都是Yes響應,那麼就會執行事務預提交。
a)傳送預提交請求
協調者向參與者節點發出preCommit的請求,進入Prepared階段
b)事務預提交
參與者接收到preCommit請求後,會執行事務操作,並將Undo和Redo資訊記錄到事務日誌中
c)各參與者向協調者反饋事務執行的響應
如果參與者成功執行了事務操作,哪兒就會反饋給協調者Ack響應,同時等待最終的指令:提交(commit)或中止(abort)
(2)中斷事物
假如任何一個參與者向協調者反饋了No響應,或者在等待超時後,協調者尚無法接收到所有參與者的反饋響應,那麼就會中斷事物。
a)傳送中斷請求
協調者向所有參與者節點發出abort請求
b)中斷事物
無論是收到來自協調者的abort請求,或者是在等待協調者請求過程中出現超時,參與者都會中斷事物
3、階段三:doCommit
該階段將進行真正的事物提交,會存在以下兩種可能的情況:
(1)執行提交
a)傳送提交請求
進入這一階段,假設協調者處於正常工作狀態,並且它接收到了來自所有參與者的Ack響應,那麼它將從"預提交"狀態轉換到"提交"狀態,並向所有的參與者傳送doCommit請求
b)事物提交
參與者接收到doCommit請求後,會正式執行事務提交操作,並在完成提交之後釋放在整個事物執行期間佔用的事物資源
c)反饋事物提交結果
參與者在完成事物提交之後,向協調者傳送Ack訊息
d)完成事物
協調者接收到所有參與者反饋的Ack訊息後,完成事物
(2)中斷事物
進入這一階段,假設協調者處於正常工作狀態,並且有任意一個參與者向協調者反饋了No響應,或者在等待超時之後,協調者商無法接收到所有參與者的反饋響應,那麼就會中斷事物
a)傳送中斷請求
協調者向所有的參與者節點傳送abort請求
b)事物回滾
參與者接收到abort請求後,會利用其在階段二中記錄的Undo資訊來執行事務回滾操作,並在完成事物回滾之後釋放在整個事物執行期間所佔用的資源
c)反饋事務反饋結果
參與者在完成事物回滾之後,向協調者傳送Ack訊息
d)中斷事物
協調者接收到所有參與者反饋的Ack訊息後,中斷事物
需要注意的是,一旦進入階段三,可能會出現以下兩種故障:
- 協調者出現問題
- 協調者和參與者之間的網路故障
無論出現哪種情況,最終都會導致參與者無法及時接收到來自協調者的doCommit或者是abort請求,針對這樣的異常情況,參與則都會在等待超時之後,繼續進行事務提交
3PC的優缺點
1、三階段提交的優點
相較於二階段提交協議,三階段提交協議最大的優點就是降低了參與者的阻塞範圍,並且能夠在出現單點故障後繼續達成一致
2、三階段提交的缺點
三階段提交協議在去除阻塞的同時也引入了新的問題,那就是在參與者接收到preCommit訊息後,如果出現網路分割槽,此時協調者所在的節點和參與者無法進行正常的網路通訊,在這種情況下,參與者依然會進行事物的提交,這必然出現資料的不一致