01.分佈式事務解決方案

1.分佈式事務解決方案

剛纔我們編寫的扣減庫存與保存訂單是在兩個服務中存在的,如果扣減庫存後訂單保存失敗了是不會回滾的,這樣就會造成數據不一致的情況,這其實就是我們所說的分佈式事務的問題,接下來我們

1.1 本地事務與分佈式事務

1.1.1 事務

數據庫事務(簡稱:事務,Transaction)是指數據庫執行過程中的一個邏輯單位,由一個有限的數據庫操作序列構成。
事務擁有以下四個特性,習慣上被稱爲ACID特性:
原子性(Atomicity):事務作爲一個整體被執行,包含在其中的對數據庫的操作要麼全部被執行,要麼都不執行。
一致性(Consistency): 事務應確保數據庫的狀態從一個一致狀態轉變爲另一個一致狀態。一致狀態是指數據庫中的數據應滿足完整性約束。除此之外,一致性還有另外一層語義,就是事務的中間狀態不能被觀察到(這層語義也有說應該屬於原子性)。
隔離性(Isolation) 多個事務併發執行時,一個事務的執行不應影響其他事務的執行,如同只有這一個操作在被數據庫所執行一樣。
持久性(Durability) 已被提交的事務對數據庫的修改應該永久保存在數據庫中。在事務結束時,此操作將不可逆轉。

1.1.2 本地事務

起初,事務僅限於對單一數據庫資源的訪問控制,架構服務化以後,事務的概念延伸到了服務中。倘若將一個單一的服務操作作爲一個事務,那麼整個服務操作只能涉及一個單一的數據庫資源,這類基於單個服務單一數據庫資源訪問的事務,被稱爲本地事務(Local Transaction)。

在這裏插入圖片描述

1.1.3 分佈式事務

分佈式事務指事務的參與者、支持事務的服務器、資源服務器以及事務管理器分別位於不同的分佈式系統的不同節點之上,且屬於不同的應用,分佈式事務需要保證這些操作要麼全部成功,要麼全部失敗。本質上來說,分佈式事務就是爲了保證不同數據庫的數據一致性。
最早的分佈式事務應用架構很簡單,不涉及服務間的訪問調用,僅僅是服務內操作涉及到對多個數據庫資源的訪問
在這裏插入圖片描述

當一個服務操作訪問不同的數據庫資源,又希望對它們的訪問具有事務特性時,就需要採用分佈式事務來協調所有的事務參與者。
對於上面介紹的分佈式事務應用架構,儘管一個服務操作會訪問多個數據庫資源,但是畢竟整個事務還是控制在單一服務的內部。如果一個服務操作需要調用另外一個服務,這時的事務就需要跨越多個服務了。在這種情況下,起始於某個服務的事務在調用另外一個服務的時候,需要以某種機制流轉到另外一個服務,從而使被調用的服務訪問的資源也自動加入到該事務當中來。下圖反映了這樣一個跨越多個服務的分佈式事務:

在這裏插入圖片描述

如果將上面這兩種場景(一個服務可以調用多個數據庫資源,也可以調用其他服務)結合在一起,對此進行延伸,整個分佈式事務的參與者將會組成如下圖所示的樹形拓撲結構。在一個跨服務的分佈式事務中,事務的發起者和提交均系同一個,它可以是整個調用的客戶端,也可以是客戶端最先調用的那個服務。

在這裏插入圖片描述

較之基於單一數據庫資源訪問的本地事務,分佈式事務的應用架構更爲複雜。在不同的分佈式應用架構下,實現一個分佈式事務要考慮的問題並不完全一樣,比如對多資源的協調、事務的跨服務傳播等,實現機制也是複雜多變。

1.2 分佈式事務相關理論

1.2.1 CAP定理

在這裏插入圖片描述

CAP定理是在 1998年加州大學的計算機科學家 Eric Brewer (埃裏克.布魯爾)提出,分佈式系統有三個指標
Consistency 一致性
Availability 可用性
Partition tolerance 分區容錯性
它們的第一個字母分別是 C、A、P。Eric Brewer 說,這三個指標不可能同時做到。這個結論就叫做CAP 定理。
分區容錯 Partition tolerance
區間通信可能失敗。比如,一臺服務器放在中國,另一臺服務器放在美國,這就是兩個區,它們之間可能無法通信。

在這裏插入圖片描述

上圖中,G1 和 G2 是兩臺跨區的服務器。G1 向 G2 發送一條消息,G2 可能無法收到。系統設計的時候,必須考慮到這種情況。
一般來說,分區容錯無法避免,因此可以認爲 CAP 的 P 總是成立。CAP 定理告訴我們,剩下的 C 和 A無法同時做到。

可用性 Availability

Availability 中文叫做"可用性",意思是隻要收到用戶的請求,服務器就必須給出迴應。用戶可以選擇向 G1 或 G2 發起讀操作。不管是哪臺服務器,只要收到請求,就必須告訴用戶,到底是v0 還是 v1,否則就不滿足可用性。
在這裏插入圖片描述

一致性 Consistency
Consistency 中文叫做"一致性"。意思是,寫操作之後的讀操作,必須返回該值。舉例來說,某條記錄是 v0,用戶向 G1 發起一個寫操作,將其改爲 v1。

在這裏插入圖片描述
問題是,用戶有可能向 G2 發起讀操作,由於 G2 的值沒有發生變化,因此返回的是 v0。G1 和 G2 讀操作的結果不一致,這就不滿足一致性了。

在這裏插入圖片描述

爲了讓 G2 也能變爲 v1,就要在 G1 寫操作的時候,讓 G1 向 G2 發送一條消息,要求 G2 也改成 v1。
在這裏插入圖片描述

一致性和可用性的矛盾

一致性和可用性,爲什麼不可能同時成立?答案很簡單,因爲可能通信失敗(即出現分區容錯)。
如果保證 G2 的一致性,那麼 G1 必須在寫操作時,鎖定 G2 的讀操作和寫操作。只有數據同步後,才能重新開放讀寫。鎖定期間,G2 不能讀寫,沒有可用性。
如果保證 G2 的可用性,那麼勢必不能鎖定 G2,所以一致性不成立。
綜上所述,G2 無法同時做到一致性和可用性。系統設計時只能選擇一個目標。如果追求一致性,那麼無法保證所有節點的可用性;如果追求所有節點的可用性,那就沒法做到一致性

1.2.2 BASE理論

BASE:全稱:Basically Available(基本可用),Soft state(軟狀態),和 Eventually consistent(最終一致性)三個短語的縮寫,來自 ebay 的架構師提出。BASE 理論是對 CAP 中一致性和可用性權衡的結果,其來源於對大型互聯網分佈式實踐的總結,是基於 CAP 定理逐步演化而來的。其核心思想是:

既是無法做到強一致性(Strong consistency),但每個應用都可以根據自身的業務特點,採用適當的方式來使系統達到最終一致性(Eventual consistency)。

Basically Available(基本可用)
什麼是基本可用呢?假設系統,出現了不可預知的故障,但還是能用,相比較正常的系統而言:
1.響應時間上的損失:正常情況下的搜索引擎 0.5 秒即返回給用戶結果,而基本可用的搜索引擎可以在 1 秒作用返回結果。
2.功能上的損失:在一個電商網站上,正常情況下,用戶可以順利完成每一筆訂單,但是到了大促期間,爲了保護購物系統的穩定性,部分消費者可能會被引導到一個降級頁面。
Soft state(軟狀態)
什麼是軟狀態呢?相對於原子性而言,要求多個節點的數據副本都是一致的,這是一種 “硬狀態”。
軟狀態指的是:允許系統中的數據存在中間狀態,並認爲該狀態不影響系統的整體可用性,即允許系統在多個不同節點的數據副本存在數據延時。
Eventually consistent(最終一致性)
系統能夠保證在沒有其他新的更新操作的情況下,數據最終一定能夠達到一致的狀態,因此所有客戶端對系統的數據訪問最終都能夠獲取到最新的值。

1.3 分佈式事務解決方案

1.3.1 基於XA協議的兩階段提交 2PC

首先我們來簡要看下分佈式事務處理的XA規範

在這裏插入圖片描述

可知XA規範中分佈式事務有AP,RM,TM組成:
其中應用程序(Application Program ,簡稱AP):AP定義事務邊界(定義事務開始和結束)並訪問事務邊界內的資源。
資源管理器(Resource Manager,簡稱RM):Rm管理計算機共享的資源,許多軟件都可以去訪問這些資源,資源包含比如數據庫、文件系統、打印機服務器等。
事務管理器(Transaction Manager ,簡稱TM):負責管理全局事務,分配事務唯一標識,監控事務的執行進度,並負責事務的提交、回滾、失敗恢復等。

二階段協議:
第一階段TM要求所有的RM準備提交對應的事務分支,詢問RM是否有能力保證成功的提交事務分支,RM根據自己的情況,如果判斷自己進行的工作可以被提交,那就對工作內容進行持久化,並給TM回執OK;否則給TM的回執NO。RM在發送了否定答覆並回滾了已經完成的工作後,就可以丟棄這個事務分支信息了。
第二階段TM根據階段1各個RM prepare的結果,決定是提交還是回滾事務。如果所有的RM都prepare成功,那麼TM通知所有的RM進行提交;如果有RM prepare回執NO的話,則TM通知所有RM回滾自己的事務分支。
也就是TM與RM之間是通過兩階段提 交協議進行交互的.
優點: 儘量保證了數據的強一致,適合對數據強一致要求很高的關鍵領域。(其實也不能100%保證強一致)
缺點: 實現複雜,犧牲了可用性,對性能影響較大,不適合高併發高性能場景。

1.3.2 TCC補償機制

TCC 其實就是採用的補償機制,其核心思想是:針對每個操作,都要註冊一個與其對應的確認和補償
(撤銷)操作。它分爲三個階段:

  • Try 階段主要是對業務系統做檢測及資源預留
  • Confirm 階段主要是對業務系統做確認提交,Try階段執行成功並開始執行 Confirm階段時,默認Confirm階段是不會出錯的。即:只要Try成功,Confirm一定成功。
  • Cancel 階段主要是在業務執行錯誤,需要回滾的狀態下執行的業務取消,預留資源釋放。

在這裏插入圖片描述

例如: A要向 B 轉賬,思路大概是:
在這裏插入圖片描述

優點: 相比兩階段提交,可用性比較強
缺點: 數據的一致性要差一些。TCC屬於應用層的一種補償方式,所以需要程序員在實現的時候多寫很多補償的代碼,在一些場景中,一些業務流程可能用TCC不太好定義及處理。

1.3.3 消息最終一致性

消息最終一致性應該是業界使用最多的,其核心思想是將分佈式事務拆分成本地事務進行處理,這種思路是來源於ebay。我們可以從下面的流程圖中看出其中的一些細節:
在這裏插入圖片描述

基本思路就是:
消息生產方,需要額外建一個消息表,並記錄消息發送狀態。消息表和業務數據要在一個事務裏提交,也就是說他們要在一個數據庫裏面。然後消息會經過MQ發送到消息的消費方。如果消息發送失敗,會進行重試發送。
消息消費方,需要處理這個消息,並完成自己的業務邏輯。此時如果本地事務處理成功,表明已經處理成功了,如果處理失敗,那麼就會重試執行。如果是業務上面的失敗,可以給生產方發送一個業務補償消息,通知生產方進行回滾等操作

優點: 一種非常經典的實現,避免了分佈式事務,實現了最終一致性。
缺點: 消息表會耦合到業務系統中,如果沒有封裝好的解決方案,會有很多雜活需要處理。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章