【分布式】分布式事务解决方案概述
本地事務與分布式事務
事務
數據庫事務(簡稱:事務,Transaction)是指數據庫執行過程中的一個邏輯單位,由一個有限的數據庫操作序列構成。
事務擁有以下四個特性,習慣上被稱為ACID特性:
- 原子性(Atomicity):事務作為一個整體被執行,包含在其中的對數據庫的操作要么全部被執行,要么都不執行。
- 一致性(Consistency):事務應確保數據庫的狀態從一個一致狀態轉變為另一個一致狀態。一致狀態是指數據庫中的數據應滿足完整性約束。除此之外,一致性還有另外一層語義,就是事務的中間狀態不能被觀察到(這層語義也有說應該屬于原子性)。
- 隔離性(Isolation):多個事務并發執行時,一個事務的執行不應影響其他事務的執行,如同只有這一個操作在被數據庫所執行一樣。
- 持久性(Durability):已被提交的事務對數據庫的修改應該永久保存在數據庫中。在事務結束時,此操作將不可逆轉。
本地事務
起初,事務僅限于對單一數據庫資源的訪問控制,架構服務化以后,事務的概念延伸到了服務中。倘若將一個單一的服務操作作為一個事務,那么整個服務操作只能涉及一個單一的數據庫資源,這類基于單個服務單一數據庫資源訪問的事務,被稱為本地事務(Local Transaction)。
分布式事務
分布式事務指事務的參與者、支持事務的服務器、資源服務器以及事務管理器分別位于不同的分布式系統的不同節點之上,且屬于不同的應用,分布式事務需要保證這些操作要么全部成功,要么全部失敗。本質上來說,分布式事務就是為了保證不同數據庫的數據一致性。
最早的分布式事務應用架構很簡單,不涉及服務間的訪問調用,僅僅是服務內操作涉及到對多個數據庫資源的訪問。
當一個服務操作訪問不同的數據庫資源,又希望對它們的訪問具有事務特性時,就需要采用分布式事務來協調所有的事務參與者。
對于上面介紹的分布式事務應用架構,盡管一個服務操作會訪問多個數據庫資源,但是畢竟整個事務還是控制在單一服務的內部。如果一個服務操作需要調用另外一個服務,這時的事務就需要跨越多個服務了。在這種情況下,起始于某個服務的事務在調用另外一個服務的時候,需要以某種機制流轉到另外一個服務,從而使被調用的服務訪問的資源也自動加入到該事務當中來。下圖反映了這樣一個跨越多個服務的分布式事務:
如果將上面這兩種場景(一個服務可以調用多個數據庫資源,也可以調用其他服務)結合在一起,對此進行延伸,整個分布式事務的參與者將會組成如下圖所示的樹形拓撲結構。在一個跨服務的分布式事務中,事務的發起者和提交均系同一個,它可以是整個調用的客戶端,也可以是客戶端最先調用的那個服務。
較之基于單一數據庫資源訪問的本地事務,分布式事務的應用架構更為復雜。在不同的分布式應用架構下,實現一個分布式事務要考慮的問題并不完全一樣,比如對多資源的協調、事務的跨服務傳播等,實現機制也是復雜多變。
分布式事務相關理論
CAP定理
CAP定理是在 1998年加州大學的計算機科學家 Eric Brewer (埃里克.布魯爾)提出,分布式系統有三個指標
- Consistency 一致性
- Availability 可用性
- Partition tolerance 分區容錯性
它們的第一個字母分別是 C、A、P。Eric Brewer 說,這三個指標不可能同時做到。這個結論就叫做CAP 定理。
分區容錯 Partition tolerance
大多數分布式系統都分布在多個子網絡。每個子網絡就叫做一個區(partition)。分區容錯的意思是,區間通信可能失敗。比如,一臺服務器放在中國,另一臺服務器放在美國,這就是兩個區,它們之間可能無法通信。
上圖中,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 無法同時做到一致性和可用性。系統設計時只能選擇一個目標。如果追求一致性,那么無法保證所有節點的可用性;如果追求所有節點的可用性,那就沒法做到一致性。
BASE理論
BASE:全稱:Basically Available(基本可用),Soft state(軟狀態),和 Eventually consistent(最終一致性)三個短語的縮寫,來自 ebay 的架構師提出。BASE 理論是對 CAP 中一致性和可用性權衡的結果,其來源于對大型互聯網分布式實踐的總結,是基于 CAP 定理逐步演化而來的。其核心思想是:
既是無法做到強一致性(Strong consistency),但每個應用都可以根據自身的業務特點,采用
適當的方式來使系統達到最終一致性(Eventual consistency)。
Basically Available(基本可用)
什么是基本可用呢?假設系統,出現了不可預知的故障,但還是能用,相比較正常的系統而言:
Soft state(軟狀態)
什么是軟狀態呢?相對于原子性而言,要求多個節點的數據副本都是一致的,這是一種 “硬狀態”。
軟狀態指的是:允許系統中的數據存在中間狀態,并認為該狀態不影響系統的整體可用性,即允許系統在多個不同節點的數據副本存在數據延時。
Eventually consistent(最終一致性)
系統能夠保證在沒有其他新的更新操作的情況下,數據最終一定能夠達到一致的狀態,因此所有客戶端對系統的數據訪問最終都能夠獲取到最新的值。
分布式事務解決方案
基于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%保證強一致)
缺點: 實現復雜,犧牲了可用性,對性能影響較大,不適合高并發高性能場景。
TCC補償機制
TCC 其實就是采用的補償機制,其核心思想是:針對每個操作,都要注冊一個與其對應的確認和補償(撤銷)操作。它分為三個階段:
- Try 階段主要是對業務系統做檢測及資源預留
- Confirm 階段主要是對業務系統做確認提交,Try階段執行成功并開始執行 Confirm階段時,默認Confirm階段是不會出錯的。即:只要Try成功,Confirm一定成功。
- Cancel 階段主要是在業務執行錯誤,需要回滾的狀態下執行的業務取消,預留資源釋放。
例如: A要向 B 轉賬,思路大概是:
我們有一個本地方法,里面依次調用
1、首先在 Try 階段,要先調用遠程接口把 B和 A的錢給凍結起來。
2、在 Confirm 階段,執行遠程調用的轉賬的操作,轉賬成功進行解凍。
3、如果第2步執行成功,那么轉賬成功,如果第二步執行失敗,則調用遠程凍結接口對應的解凍方法 (Cancel)。
優點: 相比兩階段提交,可用性比較強
缺點: 數據的一致性要差一些。TCC屬于應用層的一種補償方式,所以需要程序員在實現的時候多寫很多補償的代碼,在一些場景中,一些業務流程可能用TCC不太好定義及處理。
消息最終一致性
消息最終一致性應該是業界使用最多的,其核心思想是將分布式事務拆分成本地事務進行處理,這種思路是來源于ebay。我們可以從下面的流程圖中看出其中的一些細節:
基本思路就是:
-
消息生產方,需要額外建一個消息表,并記錄消息發送狀態。消息表和業務數據要在一個事務里提交,也就是說他們要在一個數據庫里面。然后消息會經過MQ發送到消息的消費方。如果消息發送失敗,會進行重試發送。
-
消息消費方,需要處理這個消息,并完成自己的業務邏輯。此時如果本地事務處理成功,表明已經處理成功了,如果處理失敗,那么就會重試執行。如果是業務上面的失敗,可以給生產方發送一個業務補償消息,通知生產方進行回滾等操作。
生產方和消費方定時掃描本地消息表,把還沒處理完成的消息或者失敗的消息再發送一遍。如果有靠譜的自動對賬補賬邏輯,這種方案還是非常實用的。
優點: 一種非常經典的實現,避免了分布式事務,實現了最終一致性。
缺點: 消息表會耦合到業務系統中,如果沒有封裝好的解決方案,會有很多雜活需要處理。
總結
以上是生活随笔為你收集整理的【分布式】分布式事务解决方案概述的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【模板引擎】Springboot整合Th
- 下一篇: 【消息中间件】Spring整合Rabbi