Java開發大型互聯網架構分佈式事務系統設計之分佈式原理分析

Java NoSQL 編程語言 MySQL 圖靈學院 圖靈學院 2017-11-02

引言

分佈式事務是指事務的參與者、支持事務的服務器、資源服務器以及事務管理器分別位於不同的分佈式系統的不同節點之上。

什麼是分佈式事務

簡單的說,就是一次大的操作由不同的小操作組成,這些小的操作分佈在不同的服務器上,且屬於不同的應用,分佈式事務需要保證這些小操作要麼全部成功,要麼全部失敗。本質上來說,分佈式事務就是為了保證不同數據庫的數據一致性。

優點:

XA接口標準化、使用簡單,使用成本也很低;

缺點:

性能不理想,很難滿足互聯網大併發需求。開銷大,分佈式事務RT相較於單機事務有數量級的差距;分佈式事務對相關資源的加鎖機制增加了併發衝突,影響到系統吞吐和可伸縮性;

XA要求資源管理必須實現XA接口,對資源管理器提出了要求,限制了業務方的產品選型;在Mysql數據庫中支持的不太理想,mysql的XA實現,沒有記錄prepare階段日誌,主備切換回導致主庫與備庫數據不一致。許多nosql也沒有支持XA,這讓XA的應用場景變得非常狹隘。

分佈式事務的應用場景

支付

最經典的場景就是支付了,一筆支付,是對買家賬戶進行扣款,同時對賣家賬戶進行加錢,這些操作必須在一個事務裡執行,要麼全部成功,要麼全部失敗。而對於買家賬戶屬於買家中心,對應的是買家數據庫,而賣家賬戶屬於賣家中心,對應的是賣家數據庫,對不同數據庫的操作必然需要引入分佈式事務。

在線下單

買家在電商平臺下單,往往會涉及到兩個動作,一個是扣庫存,第二個是更新訂單狀態,庫存和訂單一般屬於不同的數據庫,需要使用分佈式事務保證數據一致性。

常見的分佈式事務解決方案

基於XA協議的兩階段提交

XA是一個分佈式事務協議,由Tuxedo提出。XA中大致分為兩部分:事務管理器和本地資源管理器。其中本地資源管理器往往由數據庫實現,比如Oracle、DB2這些商業數據庫都實現了XA接口,而事務管理器作為全局的調度者,負責各個本地資源的提交和回滾。XA實現分佈式事務的原理如下:

Java開發大型互聯網架構分佈式事務系統設計之分佈式原理分析

總的來說,XA協議比較簡單,而且一旦商業數據庫實現了XA協議,使用分佈式事務的成本也比較低。但是,XA也有致命的缺點,那就是性能不理想,特別是在交易下單鏈路,往往併發量很高,XA無法滿足高併發場景。XA目前在商業數據庫支持的比較理想,在mysql數據庫中支持的不太理想,mysql的XA實現,沒有記錄prepare階段日誌,主備切換回導致主庫與備庫數據不一致。許多nosql也沒有支持XA,這讓XA的應用場景變得非常狹隘。

分佈式事務定義

分佈式事務就是指事務的參與者、支持事務的服務器、資源服務器以及事務管理器分別位於不同的分佈式系統的不同節點之上。以上是百度百科的解釋,簡單的說,就是一次大的操作由不同的小操作組成,這些小的操作分佈在不同的服務器上,且屬於不同的應用,分佈式事務需要保證這些小操作要麼全部成功,要麼全部失敗。本質上來說,分佈式事務就是為了保證不同數據庫的數據一致性。

標準模式

讀未提交(read uncommitted)和讀已提交(read committed),其中讀未提交是缺省設置

Read uncommitted

標準模式在讀未提交的隔離級別下,存在髒寫,髒讀的風險。

髒寫出現的概率很低,只有以下幾個條件同時滿足才會出現:

A) 事務1修改了T表的一行記錄;

B) 事務2接著也修改了T表的同一行記錄;

C) 事務1因為某種原因需要回滾

上面3個條件同時滿足時,事務1回滾失敗,出現髒寫情況,這時事務系統告警模塊會通知到業務人員,需要根據系統的Undo日誌進行恢復。為什麼說發生概率很低?一個分佈式事務完成時間通常是毫秒級,兩個分佈式事務在這麼短時間內併發修改同一行記錄概率很低,假設萬分之一;事務失敗的概率假設也是萬分之一,則出現髒寫的概率是億分之一,可以說概率非常低了。

髒寫出現概率極低,即使出現,由於在業務庫上記錄了詳細的undo/redo log,手工恢復代價也通常較小;所以髒寫問題對絕大多數應用場景的負面影響可以忽略,建議採用這種讀未提交的隔離級別,比讀已提交級別有更好的性能。

髒讀指用戶讀到了分佈式事務的中間狀態。對於成功的分佈式事務,這種中間狀態基本可以認為是沒有負面影響的;對於失敗的分佈式事務,也只有很少的場景下會有負面影響,因為這種中間狀態持續時間很短(通常是毫秒級),用戶很難感知。即使用戶看到了中間狀態,通常也是能夠理解的,因為他知道自己事務失敗了。

標準模式的“讀未提交”隔離級別是的主流應用,它兼顧了易用性與較高的性能,適用於多數分佈式事務場景

Read committed

標準模式在讀已提交的隔離級別下,將對所管理的所有讀已提交的分佈式事務,進行寫入記錄的行級鎖檢查,當發現鎖衝突,採用重試策略(最長550ms),如果經過重試後還是拿不到鎖,將拒絕後進的事務,並將異常拋出給上層業務系統。

需要說明的是:僅能保證被管理的讀已提交的事務間的Read Committed的隔離性。

隔離級別可以通過的RM配置項進行設置。

讀已提交隔離級別比讀未提交增大了開銷(10%~20%),如果select語句也採用讀已提交則會有更大開銷。如4.1.1所分析,實際業務場景下,讀未提交是足夠安全的,不建議使用讀已提交隔離級別。

分佈式事務原理:分段式提交

分佈式事務通常採用2PC協議,全稱Two Phase Commitment Protocol。該協議主要為了解決在分佈式數據庫場景下,所有節點間數據一致性的問題。分佈式事務通過2PC協議將提交分成兩個階段:

prepare;

commit/rollback

階段一為準備(prepare)階段。即所有的參與者準備執行事務並鎖住需要的資源。參與者ready時,向transaction manager報告已準備就緒。

階段二為提交階段(commit)。當transaction manager確認所有參與者都ready後,向所有參與者發送commit命令。

如下圖所示:

事務協調者transaction manager

因為XA 事務是基於兩階段提交協議的,所以需要有一個事務協調者(transaction manager)來保證所有的事務參與者都完成了準備工作(第一階段)。如果事務協調者(transaction manager)收到所有參與者都準備好的消息,就會通知所有的事務都可以提交了(第二階段)。MySQL 在這個XA事務中扮演的是參與者的角色,而不是事務協調者(transaction manager)。

總結

以 上就是我對Java開發大型互聯網架構分佈式事務系統設計之分佈式原理分析問題及其優化總結,分享給大家,希望大家知道什麼是Java開發大型互聯網架構分佈式事務系統設計之分佈式原理分析問題及其優化。覺得收穫的話可以點個關注收藏轉發一波喔,謝謝大佬們支持!

  • 1、多寫多敲代碼,好的代碼與紮實的基礎知識一定是實踐出來的

  • 2、可以去百度搜索騰訊課堂圖靈學院的視頻來學習一下java架構實戰案例,還挺不錯的。

  • 最後,每一位讀到這裡的網友,感謝你們能耐心地看完。希望在成為一名更優秀的Java程序員的道路上,我們可以一起學習、一起進步!都能贏取白富美,走向架構師的人生巔峰!

  • 3丶想了解學習以上課程內容可加群:469717771 驗證碼頭條(06 必過)歡迎大家的加入喲!

Java開發大型互聯網架構分佈式事務系統設計之分佈式原理分析

相關推薦

推薦中...