1. 程式人生 > >分散式事務簡介

分散式事務簡介

目錄

XA協議

XA角色

XA原理

3pc

TCC

為什麼會有分散式事務?

當我們的單個數據庫的效能產生瓶頸的時候,我們可能會對資料庫進行分割槽,分割槽之後可能不同的庫就處於不同的伺服器上了,這個時候單個數據庫的ACID已經不能適應這種叢集環境了。要想解決資料庫叢集的ACID就需要引入分散式事務。

ACID:

原子性(Atomicity): 事務是一個原子操作單元,要麼都執行,要麼都不執行。 

一致性(Consistent):在事務開始和完成時,資料都必須保持一致。 

隔離性(Isoation): 資料庫系統提供一定的隔離機制,保證事務在不受外部併發操作影響的獨立環境執行。 

永續性(Durabe): 事務完成之後,它對資料的修改是永久性的。

XA協議

XA協議是X/Open組織定義的一套分散式事務的標準,這個標準提出了使用二階段提交(2PC – Two-Phase-Commit)來保證分散式事務的完整性。

XA角色

AP(application):應用程式,即需要被事務管理的業務操作。

RM(Resource Manager):資源管理器,一般是資料庫。

TM(Transaction Manager):事務管理器,負責接收來自使用者程式(AP)發起的XA事務指令,並排程和協調參與事務的所有RM(資料庫),確保事務正確完成。

XA原理

1. 參與分散式事務的應用程式AP先到TM上註冊全域性事務。

2. 然後各個AP直接在相應的資源管理器RM上進行事務操作。

3. 操作完成以後,各個AP反饋事務的處理結果給到TM。

4. TM收到所有AP的反饋以後,通過資料庫提供的XA介面進行資料提交或者回滾操作。

2pc提交(two -phaseCommit)

在X/A協議模型中,一個分散式事務所涉及的SQL邏輯都執行完成,併到了(RM)要最後提交事務的關鍵時刻,為了避免分散式系統所固有的不可靠性導致提交事務意外失敗,TM 果斷決定實施兩步走的方案,這個就稱為二階提交。

第一階段:prepare

1. 事務詢問:TM向所有的AP傳送事務內容,詢問是否可以執行事務提交操作,並開始等待各AP的響應。

2. 執行事務:各個AP節點執行事務操作,並將Undo和Redo資訊記錄到事務日誌中,儘量把提交過程中所有消耗時間的操作和準備都提前完成確保後面100%成功提交事務。

3. 事務反饋:如果各個AP成功執行了事務操作,那麼就反饋給TM yes的響應,表示事務可以執行;如果AP沒有成功執行事務,就反饋給TM no的響應,表示事務不可以執行。

上面這個階段有點類似TM組織各個AP對一次事務操作的投票表態過程,因此2pc協議的第一個階段稱為“投票階段”,即各AP投票表決是否需要繼續執行接下去的事務提交操作。

第二階段:commit/rollback

在這個階段,TM會根據各AP的反饋情況來決定最終是否可以進行事務提交操作,正常情況下包含兩種可能。

當所有AP都反饋yes 則執行事務提交操作:

1. 傳送提交請求:TM向所有AP節點發出commit請求。

2. 事務提交:AP接收到commit請求後,會正式執行事務提交操作,並在完成提交之後釋放在整個事務執行期間佔用的資源。

3. 反饋事務提交結果:AP在完成事務提交之後,向TM傳送Ack訊息。

4. 完成事務:TM接收到所有AP反饋的ack訊息後,完成事務。

當有AP反饋no 則執行事務回滾操作:

1. 傳送回滾請求:TM向所有AP發出abort請求。

2. 事務回滾:AP收到abort請求後,會利用在第一階段記錄的Undo資訊來執行事務回滾操作,並在完成回滾之後釋放在整個事務執行期間佔用的資源。

3. 反饋事務回滾結果:各AP在完成事務回滾之後,向TM傳送Ack訊息。

4. 中斷事務:TM接收到所有AP反饋的ack訊息後,完成事務中斷。

2pc的優缺點:

優點:原理簡單,實現很方便,大部分情況下都具有較強的實時一致性。

缺點:

1. 從prepare到commit/rollback過程中,資源實際上一直都是被加鎖的。如果有其他人需要更新這兩條記錄,那麼就必須等待鎖釋放,導致效能下降。

2. 協調者TM存在單點問題,如果TM在第二階段出現故障,那麼AP會一直處於鎖定狀態。

3. 太過保守,任意一個節點失敗都會導致資料回滾。

4. 資料不一致問題,在階段二中,當TM向所有AP傳送commit 請求後,發生了網路異常導致TM 在尚未發完commit請求之前崩潰,可能會導致只有部分的AP接收到commit請求,剩下沒收到commit請求的參與者將無法提交事務,也就可能導致資料不一致的問題。

3pc

在2pc中,準備階段需要執行事務,佔用了整個過程的大部分時間,且每個AP在準備階段前並不知道其他AP的狀況,只能等到事務執行完,統一在TM彙總結果,只要有一個AP失敗,其他AP即便事務執行成功也得進行回滾,等於做了無用功。

3pc針對這個問題,把2pc的準備階段再次一分為二,這樣三階段提交就有CanCommit、PreCommit、DoCommit三個階段。在第一階段,只是詢問所有AP是否可可以執行事務操作,並不在本階段執行事務操作。當TM收到所有AP都返回YES時,在第二階段才執行事務操作,然後在第三階段在執行commit或者rollback。這樣就儘量減少了在有節點異常的情況下正常節點做無用功的機率。

TCC

TCC事務解決方案本質上是一種補償的思路,它把事務執行過程分成try、confirm/cancel 兩個階段,每個階段都由業務程式碼來控制。需要注意的是,TCC事務和2pc的思想類似,但與2pc實現不同,TCC不再是兩階段提交,而只是它對事務的提交/回滾是通過執行一段confirm/cancel業務邏輯來實現,並且也並沒有全域性事務來把控整個事務邏輯。

實現過程:

1. try:完成所有業務檢查(一致性),預留業務資源。

2. confirm:確認執行業務操作,只使用try階段預留的業務資源。

3. cancel:取消try階段預留的業務資源。

TCC與XA區別

XA是資源層面的分散式事務,強一致性,事務提交過程對開發者遮蔽。在2pc提交的整個過程中,一直會持有資源的鎖。

tcc是業務層面的分散式事務,只需要實現最終一致性,提交過程由開發者控制。由於整個過程是由多個獨立的本地事務組成,因此不會對資源一直加鎖。

tcc優缺點:

優點:把資源層面二階段提交上提到了業務層面來實現,不需要額外加鎖佔用資源。

缺點:導致業務複雜化,原本只需要實現一個執行事務的介面,現在需要實現try、confirm、cancel三個介面。

基於訊息佇列的最終一致性方案

通過非同步訊息執行方案的本質是:把分散式事物轉化成多個本地事務,在業務實現冪等性的前提下,依靠訊息本身的可靠性,以及訊息的重試機制達到最終一致性。

什麼是冪等性?

重複呼叫多次產生的業務結果與呼叫一次產生的業務結果相同稱之為冪等。

在分散式架構中,我們呼叫一個遠端服務去完成一個操作,除了成功和失敗以外,還有未知狀態,針對這個未知狀態,我們會採取一些重試的行為,這樣消費者可能會重複收到同一訊息。

對於這種情況,消費端或者服務端需要採取一定的手段來保證資料的安全性。例如可以在消費端建立一張流水錶專門記錄請求唯一流水號,在執行真正的業務前先通過該表來判斷是否是收到了重複請求。

使用訊息佇列的優缺點:

優點:降低業務之間的耦合,無需阻塞,實現了最終一致性,是目前最為流行的分散式事務解決方案。

缺點:需要額外投入成本維護MQ。