分散式事務(1)---2PC和3PC理論
分散式事物基本理論:基本遵循CPA理論,採用柔性事物特徵,軟狀態或者最終一致性特點保證分散式事物一致性問題。
分散式事物常見解決方案:
2PC兩段提交協議
3PC三段提交協議(彌補兩端提交協議缺點)
TCC或者GTS(阿里)
訊息中介軟體最終一致性
使用LCN解決分散式事物,理念“LCN並不生產事務,LCN只是本地事務的搬運工”。
一、兩階段提交(2PC)
兩階段提交又稱2PC,2PC是一個非常經典的強一致、中心化的原子提交協議
。
這裡所說的中心化是指協議中有兩類節點:一個是中心化協調者節點
(coordinator)和N個參與者節點
(partcipant)。
兩個階段
:第一階段:投票階段 和第二階段:提交/執行階段。
舉例
訂單服務A,需要呼叫 支付服務B 去支付,支付成功則處理購物訂單為待發貨狀態,否則就需要將購物訂單處理為失敗狀態。
那麼看2PC階段是如何處理的
1、第一階段:投票階段
第一階段主要分為3步
1)事務詢問
協調者 向所有的 參與者 傳送事務預處理請求,稱之為Prepare,並開始等待各 參與者 的響應。
2)執行本地事務
各個 參與者 節點執行本地事務操作,但在執行完成後並不會真正提交資料庫本地事務,而是先向 協調者 報告說:“我這邊可以處理了/我這邊不能處理”。.
3)各參與者向協調者反饋事務詢問的響應
如果 參與者 成功執行了事務操作,那麼就反饋給協調者 Yes 響應,表示事務可以執行,如果沒有 參與者 成功執行事務,那麼就反饋給協調者 No 響應,表示事務不可以執行。
第一階段執行完後,會有兩種可能。1、所有都返回Yes. 2、有一個或者多個返回No。
2、第二階段:提交/執行階段(成功流程)
成功條件
:所有參與者都返回Yes。
第二階段主要分為兩步
1)所有的參與者反饋給協調者的資訊都是Yes,那麼就會執行事務提交
協調者 向 所有參與者 節點發出Commit請求.
2)事務提交
參與者 收到Commit請求之後,就會正式執行本地事務Commit操作,並在完成提交之後釋放整個事務執行期間佔用的事務資源。
3、第二階段:提交/執行階段(異常流程)
異常條件
:任何一個 參與者 向 協調者 反饋了 No 響應,或者等待超時之後,協調者尚未收到所有參與者的反饋響應。
異常流程第二階段也分為兩步
1)傳送回滾請求
協調者 向所有參與者節點發出 RoollBack 請求.
2)事務回滾
參與者 接收到RoollBack請求後,會回滾本地事務。
4、2PC缺點
通過上面的演示,很容易想到2pc所帶來的缺陷
1)效能問題
無論是在第一階段的過程中,還是在第二階段,所有的參與者資源和協調者資源都是被鎖住的,只有當所有節點準備完畢,事務 協調者 才會通知進行全域性提交,參與者 進行本地事務提交後才會釋放資源。這樣的過程會比較漫長,對效能影響比較大。
2)單節點故障
由於協調者的重要性,一旦 協調者 發生故障。參與者 會一直阻塞下去。尤其在第二階段,協調者 發生故障,那麼所有的 參與者 還都處於鎖定事務資源的狀態中,而無法繼續完成事務操作。(雖然協調者掛掉,可以重新選舉一個協調者,但是無法解決因為協調者當機導致的參與者處於阻塞狀態的問題)
2PC出現單點問題的三種情況
(1)協調者正常,參與者當機
由於 協調者 無法收集到所有 參與者 的反饋,會陷入阻塞情況。
解決方案:引入超時機制,如果協調者在超過指定的時間還沒有收到參與者的反饋,事務就失敗,向所有節點傳送終止事務請求。
(2)協調者當機,參與者正常
無論處於哪個階段,由於協調者當機,無法傳送提交請求,所有處於執行了操作但是未提交狀態的參與者都會陷入阻塞情況.
解決方案:引入協調者備份,同時協調者需記錄操作日誌.當檢測到協調者當機一段時間後,協調者備份取代協調者,並讀取操作日誌,向所有參與者詢問狀態。
(3)協調者和參與者都當機
1) 發生在第一階段: 因為第一階段,所有參與者都沒有真正執行commit,所以只需重新在剩餘的參與者中重新選出一個協調者,新的協調者在重新執行第一階段和第二階段就可以了。
2)發生在第二階段 並且 掛了的參與者在掛掉之前沒有收到協調者的指令。也就是上面的第4步掛了,這是可能協調者還沒有傳送第4步就掛了。這種情形下,新的協調者重新執行第一階段和第二階段操作。
3)發生在第二階段 並且 有部分參與者已經執行完commit操作。就好比這裡訂單服務A和支付服務B都收到協調者 傳送的commit資訊,開始真正執行本地事務commit,但突發情況,Acommit成功,B確掛了。這個時候目前來講資料是不一致的。雖然這個時候可以再通過手段讓他和協調者通訊,再想辦法把資料搞成一致的,但是,這段時間內他的資料狀態已經是不一致的了! 2PC 無法解決這個問題。
二、三階段提交(3PC)
三階段提交協議(3PC)主要是為了解決兩階段提交協議的阻塞問題,2pc存在的問題是當協作者崩潰時,參與者不能做出最後的選擇。因此參與者可能在協作者恢復之前保持阻塞。三階段提交(Three-phase commit),是二階段提交(2PC)的改進版本。
與兩階段提交不同的是,三階段提交有兩個改動點。
1、 引入超時機制。同時在協調者和參與者中都引入超時機制。
2、在第一階段和第二階段中插入一個準備階段。保證了在最後提交階段之前各參與節點的狀態是一致的。
也就是說,除了引入超時機制之外,3PC把2PC的準備階段再次一分為二,這樣三階段提交就有CanCommit
、PreCommit
、DoCommit
三個階段。
1、CanCommit階段
之前2PC的一階段是本地事務執行結束後,最後不Commit,等其它服務都執行結束並返回Yes,由協調者發生commit才真正執行commit。而這裡的CanCommit指的是 嘗試獲取資料庫鎖 如果可以,就返回Yes。
這階段主要分為2步
事務詢問
協調者 向 參與者 傳送CanCommit請求。詢問是否可以執行事務提交操作。然後開始等待 參與者 的響應。
響應反饋
參與者 接到CanCommit請求之後,正常情況下,如果其自身認為可以順利執行事務,則返回Yes響應,並進入預備狀態。否則反饋No
2、PreCommit階段
在階段一中,如果所有的參與者都返回Yes的話,那麼就會進入PreCommit階段進行事務預提交。這裡的PreCommit階段 跟上面的第一階段是差不多的,只不過這裡 協調者和參與者都引入了超時機制 (2PC中只有協調者可以超時,參與者沒有超時機制)。
3、DoCommit階段
這裡跟2pc的階段二是差不多的。
總結
相比較2PC而言,3PC對於協調者(Coordinator)和參與者(Partcipant)都設定了超時時間,而2PC只有協調者才擁有超時機制。這解決了一個什麼問題呢?
這個優化點,主要是避免了參與者在長時間無法與協調者節點通訊(協調者掛掉了)的情況下,無法釋放資源的問題,因為參與者自身擁有超時機制會在超時後,
自動進行本地commit從而進行釋放資源。而這種機制也側面降低了整個事務的阻塞時間和範圍。
另外,通過CanCommit、PreCommit、DoCommit三個階段的設計,相較於2PC而言,多設定了一個緩衝階段保證了在最後提交階段之前各參與節點的狀態是一致的。
以上就是3PC相對於2PC的一個提高(相對緩解了2PC中的前兩個問題),但是3PC依然沒有完全解決資料不一致的問題。
參考
只要自己變優秀了,其他的事情才會跟著好起來(上將5)