分布式事务简介
分布式事務簡介
- 事務
- BASE理論
- 2PC
- 第一階段:投票階段
- 第二階段:提交/執行階段(成功流程)
- 第二階段失敗回滾流程
- 2pc可能出現的三種問題
- 3PC
- TCC
- 悲觀鎖與樂觀鎖
- 參考鏈接
事務
BASE理論
BASE 理論是 Basically Available(基本可用),Soft State(軟狀態)和Eventually Consistent(最終一致性)三個短語的縮寫。
其核心思想是:
即使無法做到強一致性(Strong consistency),但每個應用都可以根據自身的業務特點,采用適當的方式來使系統達到最終一致性(Eventual consistency)
2PC
兩階段提交又稱2PC,2PC是一個非常經典的強一致、中心化的原子提交協議。這里所說的中心化是指協議中有兩類節點:一個是中心化協調者節點(coordinator)和N個參與者節點(partcipant)。
分為投票階段和提交/執行階段。舉例 訂單服務A,需要調用 支付服務B 去支付,支付成功則處理購物訂單為待發貨狀態,否則就需要將購物訂單處理為失敗狀態。
第一階段:投票階段
第二階段:提交/執行階段(成功流程)
第二階段失敗回滾流程
2pc可能出現的三種問題
作者:歐陽豐 鏈接:https://zhuanlan.zhihu.com/p/91263461 來源:知乎
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
協調者正常,參與者宕機?:由于 協調者 無法收集到所有 參與者 的反饋,會陷入阻塞情況。?
協調者宕機,參與者正常?:無論處于哪個階段,由于協調者宕機,無法發送提交請求,所有處于執行了操作但是未提交狀態的參與者都會陷入阻塞情況.?
協調者和參與者都宕機:
2PC 無法解決這個問題。
3PC
三階段提交協議(3PC)主要是為了解決兩階段提交協議的阻塞問題,2pc存在的問題是當協作者崩潰時,參與者不能做出最后的選擇。因此參與者可能在協作者恢復之前保持阻塞。三階段提交(Three-phase commit),是二階段提交(2PC)的改進版本。
除了引入超時機制之外,3PC把2PC的準備階段再次一分為二,這樣三階段提交就有CanCommit、PreCommit、DoCommit三個階段。
拋開三階段提交糟糕的性能(并且其也沒有解決2pc丟數據的問題),超時也不是一種可靠的故障檢測機制,因為即使沒有節點崩潰,請求也可能由于網絡問題而超時。出于這個原因,兩階段提交仍然被廣泛使用,盡管存在協調者失效的問題。
所以,因為特性需要(一致性),分布式事務最終會走向分布式共識。
TCC
TCC (Try、Commit、Cancel) 是一種補償型事務,該模型要求應用的每個服務提供 try、confirm、cancel 三個接口,它的核心思想是通過對資源的預留(提供中間態),盡早釋放對資源的加鎖,如果事務可以提交,則完成對預留資源的確認,如果事務要回滾,則釋放預留的資源。
TCC 也是一種兩階段提交協議,可以看作 2PC/XA 的一種變種,但是不會長時間持有資源鎖。
TCC 模型將事務的提交劃分為兩個階段:
- 完成業務檢查(一致性)、預留業務資源(準隔離性),即 TCC 中的 try。
- 如果 try 階段所有業務資源都預留成功,則執行 confirm 操作,否則執行 cancel 操作:
- confirm:不做任何業務檢查,僅僅使用預留的資源執行業務操作,如果失敗會一直重試。
- cancel:取消執行業務操作,釋放預留的資源,如果失敗會一直重試。
TCC 模式中,事務的發起者和參與者都需要記錄事務日志,事務的發起者需要記錄全局事務和各個分支事務的狀態和信息;事務的參與者需要記錄分支事務的狀態。
TCC 事務在執行過程中的任意環節,均可能發生宕機、重啟、網絡中斷等異常情況,此時事務處于非原子狀態和非最終一致狀態,此時就需要根據主事務記錄和分支事務記錄的日志,去完成剩余分支事務的提交或者回滾,使整個分布式事務內所有參展達到最終一致的狀態,實現事務的原子性。
悲觀鎖與樂觀鎖
鎖的一種宏觀分類方式是悲觀鎖和樂觀鎖。悲觀鎖與樂觀鎖并不是特指某個鎖(Java中沒有哪個Lock實現類就叫PessimisticLock或OptimisticLock),而是在并發情況下的兩種不同策略。
- 悲觀鎖(Pessimistic Lock), 就是很悲觀,每次去拿數據的時候都認為別人會修改。所以每次在拿數據的時候都會上鎖。這樣別人想拿數據就被擋住,直到悲觀鎖被釋放。
- 樂觀鎖(Optimistic Lock), 就是很樂觀,每次去拿數據的時候都認為別人不會修改。所以不會上鎖,不會上鎖!但是如果想要更新數據,則會在更新前檢查在讀取至更新這段時間別人有沒有修改過這個數據。如果修改過,則重新讀取,再次嘗試更新,循環上述步驟直到更新成功(當然也允許更新失敗的線程放棄操作)。
悲觀鎖阻塞事務,樂觀鎖回滾重試,它們各有優缺點,不要認為一種一定好于另一種。像樂觀鎖適用于寫比較少的情況下,即沖突真的很少發生的時候,這樣可以省去鎖的開銷,加大了系統的整個吞吐量。但如果經常產生沖突,上層應用會不斷的進行重試,這樣反倒是降低了性能,所以這種情況下用悲觀鎖就比較合適。
參考鏈接
總結
- 上一篇: Windows Azure Storag
- 下一篇: linux 丢包排查思路简述(tcp+r