一文看懂分布式事務

2021-01-07 Java編程技術樂園

及時獲取有趣有料的技術文章

本地事務

事務 Transaction 由一組 SQL 組成,具有四個 ACID 特性:

Atomicity:原子性,構成事務的一組SQL,要麼全部生效,要麼全不生效,不會出現部分生效的情況。Consistency:一致性,資料庫經過事務操作後從一種狀態轉變為另一個狀態。可以說原子性是從行為上描述,而一致性是從結果上描述。Isolation:隔離性,事務操作的數據對象相對於其他事務操作的數據對象相互隔離,互不影響。Durability:持久性,事務提交後,其結果就是永久性的,即使發生宕機(非磁碟損壞)。

事務實現

對於 MySQL 資料庫(InnoDB 存儲引擎)而言,隔離性是通過不同粒度的鎖機制來實現事務間的隔離。

原子性、一致性和持久性通過 redo log 重做日誌和 undo log 回滾日誌來保證的。

redo log:當資料庫對數據做修改的時候,需要把數據頁從磁碟讀到 buffer pool 中,然後在 buffer pool 中進行修改。

那麼這個時候 buffer pool 中的數據頁就與磁碟上的數據頁內容不一致,稱 buffer pool 的數據頁為 dirty page 髒數據。

如果這個時候發生非正常的 DB 服務重啟,那麼這些數據還沒在內存,並沒有同步到磁碟文件中(注意,同步到磁碟文件是個隨機 IO),也就是會發生數據丟失。

如果這個時候,能夠在有一個文件,當 buffer pool 中的 data page 變更結束後,把相應修改記錄記錄到這個文件(注意,記錄日誌是順序 IO)。

那麼當 DB 服務發生 crash 的情況,恢復 DB 的時候,也可以根據這個文件的記錄內容,重新應用到磁碟文件,數據保持一致。

undo log:undo 日誌用於存放數據被修改前的值,如果修改出現異常,可以使用 undo 日誌來實現回滾操作,保證事務的一致性。另外 InnoDB MVCC 事務特性也是基於 undo 日誌實現的。

undo 日誌分為 insert undo log(insert 語句產生的日誌,事務提交後直接刪除)和 update undo log(delete 和 update 語句產生的日誌,由於該 undo log 可能提供 MVVC 機制使用,所以不能再事務提交時刪除)。

問題引入

CAP 理論

CAP 原則又稱 CAP 定理,指的是在一個分布式系統中的一致性(Consistency)、可用性(Availability)、分區容錯性(Partition tolerance)。

CAP 原則指的是,這三個要素最多只能同時實現兩點,不可能三者兼顧。但由於在分布式系統中,分區容錯性必然存在,所以只能在一致性和可用性妥協。

傳統的 DBMS,如 MySQL 其實 CA 組合,在主從架構下,讀寫分離的情況下,是犧牲一定的一致性的(主從延遲)。

Base 理論:

base available,基本可用,分布式系統在出現故障時,允許損失部分可用功能,保證核心功能可用。soft state,軟狀態,允許系統中存在中間狀態,這個狀態不影響系統可用性。eventually consistent,最終一致性,系統的中間狀態經過短暫的時間後到達一致狀態。

如何解決

場景舉例

考慮這樣一種業務場景,系統 A 調用系統 B 的退款服務進行退款,系統 A 更改內部退款狀態,接著調用系統 C 的簡訊服務通知用戶。

在這樣的一個場景下,由於網絡不可靠的必然存在,存在 A、B、C 三個系統之間一致性的問題。

本地表

針對上述場景,設計兩張表:退款記錄表和簡訊發送記錄表以及相應的補償 Job。

具體實現過程:

新增退款記錄表,狀態為處理中。調用系統 B 的退款服務進行退款。更新退款記錄狀態為對應的狀態(成功/失敗)。如果退款成功,則新增簡訊發送記錄,記錄狀態為待發送。調用系統 C 的簡訊服務,發送簡訊。更新簡訊發送記錄為已發送。

退款補償 Job,查詢退款記錄表中處理中的記錄,調用系統 B 的退款服務,退款成功處理:

新增簡訊發送記錄,記錄狀態為待發送。調用系統 C 的簡訊服務,發送簡訊。更新簡訊發送記錄為已發送。

簡訊通知補償 Job,查詢簡訊發送記錄中待發送的記錄,調用系統 C 的簡訊服務:

調用系統 C 的簡訊服務,發送簡訊。更新簡訊發送記錄為已發送。

注意:

系統 B 和系統 C 需要根據調用方傳的 uuid 支持冪等。系統 A、B、C 會出現短暫的不一致,但最終一致。

事務消息

可以將其視為兩階段提交消息實現,以確保分布式系統中的最終一致性。事務性消息可確保本地事務的執行和消息的發送可以原子方式執行。

但是由於事務消息異步的特性,調用方拿不到消費方的處理結果,適用於不關心對方的返回結果/對方負責保證處理成功。

針對上述場景,增加兩個事務消息的方式解決一致性問題,系統 A 通過發送事務消息的方式與系統 B 和系統 C 進行交互。

具體實現過程:

發送退款的事務消息。新增退款記錄,狀態為:處理中。Commit 退款事務消息。

提供 MQ 事務 callback:

退款 callback 查詢:有退款記錄且為處理中則 Commit;其他則 Rollback。發送簡訊 callback 查詢:有退款記錄且成功則 Commit;其他則 Rollback。

退款同步 Job,查詢退款記錄表中處理中的記錄,調用系統 B 的退款查詢接口同步狀態,其中退款成功處理:

發送簡訊的事務消息更新退款記錄為成功Commit 簡訊事務消息

相關理論

二階段提交

二階段提交是解決分布式事務問題的重要理論基礎,但也存在著明顯的問題:

阻塞問題,參與者將協議消息發送給協調器後,它將阻塞直到收到提交或回滾,只能依賴協調者的超時機制。協調者單點問題,如果協調者出現故障,則某些參與者將一直無法收到提交或回滾的消息。

為了解決二階段提交出現的問題,又有了三階段提交(Three-phase commit):

解決阻塞問題:將 2PC 中的第一階段一分為二,提供了一個 CanCommit 階段,此階段並不鎖定資源,這樣可以大幅降低阻塞概率。解決單點問題:在參與者這邊也引入了超時機制。

DTP Model

X/Open 分布式事務處理 DTP(Distributed Transaction Processing)模型是一種軟體體系架構,已經成為事實上的事務模型組件的行為標準。

它允許多個應用程式共享由多個資源管理器提供的資源,並允許其工作被協調為全局事務:

ApplicationProgram(AP),應用程式定義了事務邊界並指定構成事務的操作。ResourceManager(RM),資源管理器用來管理我們需要訪問的共享資源,我們可以將它理解為關係資料庫、文件存儲系統、消息隊列、印表機等。TransactionManager(TM),事務管理器是一個獨立的組件,他為事務分配標識符並監視事務的執行情況,負責事務完成和故障恢復。CommunicationResourceManager(CRM),通信資源管理器控制一個或多個 TM domain 之間分布式應用的通信。

XA Specification:XA 規範是 X/Open 關於分布式事務處理(DTP)的規範。規範描述了全局的事務管理器與局部的資源管理器之間的接口。

XA 規範的目的是允許多個資源(如資料庫,應用伺服器,消息隊列,等等)在同一事務中訪問,這樣可以使 ACID 屬性跨越應用程式而保持有效。

XA 使用兩階段提交來保證所有資源同時提交或回滾任何特定的事務。

XA 規範描述了資源管理器要支持事務性訪問所必需做的事情。

TCC

Saga

在 Saga 模式下,分布式事務內有多個參與者,每一個參與者都是一個衝正補償服務,需要用戶根據業務場景實現其正向操作和逆向回滾操作。

分布式事務執行過程中,依次執行各參與者的正向操作,如果所有正向操作均執行成功,那麼分布式事務提交。

如果任何一個正向操作執行失敗,那麼分布式事務會去退回去執行前面各參與者的逆向回滾操作,回滾已提交的參與者,使分布式事務回到初始狀態。

Saga 模式下分布式事務通常是由事件驅動的,各個參與者之間是異步執行的,Saga 模式是一種長事務解決方案。

Saga 模式的優勢是:

一階段提交本地資料庫事務,無鎖,高性能。參與者可以採用事務驅動異步執行,高吞吐。補償服務即正向服務的「反向」,易於理解,易於實現。

缺點:Saga 模式由於一階段已經提交本地資料庫事務,且沒有進行「預留」動作,所以不能保證隔離性。

開源項目

Seata

Seata 是一款開源的分布式事務解決方案,致力於在微服務架構下提供高性能和簡單易用的分布式事務服務。支持 AT、TCC、Saga、XA 四種模式,對微服務框架支持友好。

如下圖所示,Seata 中有三大模塊,分別是 TM、RM 和 TC。其中 TM 和 RM 是作為 Seata 的客戶端與業務系統集成在一起,TC 作為 Seata 的服務端獨立部署:

TC:事務協調者,維護全局和分支事務的狀態,驅動全局事務提交或回滾。TM:事務管理器,定義全局事務的範圍:開始全局事務、提交或回滾全局事務。RM:資源管理器,管理分支事務處理的資源,與 TC 交談以註冊分支事務和報告分支事務的狀態,並驅動分支事務提交或回滾。

在 Seata 中,分布式事務的執行流程:

TM 開啟分布式事務(TM 向 TC 註冊全局事務記錄)。按業務場景,編排資料庫、服務等事務內資源(RM 向 TC 匯報資源準備狀態 )。TM 結束分布式事務,事務一階段結束(TM 通知 TC 提交/回滾分布式事務)。TC 匯總事務信息,決定分布式事務是提交還是回滾。TC 通知所有 RM 提交/回滾資源,事務二階段結束。

①AT 模式

AT 模式是一種無侵入的分布式事務解決方案。

在 AT 模式下,用戶只需關注自己的「業務 SQL」,用戶的 「業務 SQL」 作為一階段,Seata 框架會自動生成事務的二階段提交和回滾操作。

一階段:業務數據和回滾日誌記錄在同一個本地事務中提交,釋放本地鎖和連接資源。二階段:提交異步化,非常快速地完成。回滾通過一階段的回滾日誌進行反向補償。

在一階段,Seata 會攔截「業務 SQL」,首先解析 SQL 語義,找到「業務 SQL」要更新的業務數據,在業務數據被更新前,將其保存成「before image」,然後執行「業務 SQL」更新業務數據,在業務數據更新之後,再將其保存成「after image」,最後生成行鎖。

以上操作全部在一個資料庫事務內完成,這樣保證了一階段操作的原子性。

②TCC 模式

一個分布式的全局事務,整體是兩階段提交的模型。全局事務是由若干分支事務組成的,分支事務要滿足兩階段提交的模型要求,即需要每個分支事務都具備自己的:

一階段 prepare 行為。二階段 commit 或 rollback 行為。

TCC 模式,不依賴於底層數據資源的事務支持:

一階段 prepare 行為:調用自定義的 prepare 邏輯。二階段 commit 行為:調用自定義的 commit 邏輯。二階段 rollback 行為:調用自定義的 rollback 邏輯。

所謂 TCC 模式,是指支持把 自定義 的分支事務納入到全局事務的管理中。

③Saga 模式

目前 Seata 提供的 Saga 模式是基於狀態機引擎來實現的,機制是:

通過狀態圖來定義服務調用的流程並生成 json 狀態語言定義文件。狀態圖中一個節點可以是調用一個服務,節點可以配置它的補償節點。狀態圖 json 由狀態機引擎驅動執行,當出現異常時狀態引擎反向執行已成功節點對應的補償節點將事務回滾 (異常發生時是否進行補償也可由用戶自定義決定)。可以實現服務編排需求,支持單項選擇、並發、子流程、參數轉換、參數映射、服務執行狀態判斷、異常捕獲等功能。

狀態機引擎原理:

圖中的狀態圖是先執行 stateA,再執行 stateB,然後執行 stateC。"狀態"的執行是基於事件驅動的模型,stateA 執行完成後,會產生路由消息放入 EventQueue,事件消費端從 EventQueue 取出消息,執行 stateB。在整個狀態機啟動時會調用 Seata Server 開啟分布式事務,並生產 xid,然後記錄"狀態機實例"啟動事件到本地資料庫。當執行到一個"狀態"時會調用 Seata Server 註冊分支事務,並生產 branchId,然後記錄"狀態實例"開始執行事件到本地資料庫。當一個"狀態"執行完成後會記錄"狀態實例"執行結束事件到本地資料庫,然後調用 Seata Server 上報分支事務的狀態。當整個狀態機執行完成, 會記錄"狀態機實例"執行完成事件到本地資料庫,然後調用 Seata Server 提交或回滾分布式事務。

作者:VectorJin

出處:https://juejin.im/post/5e066c9ff265da33b0718f89

相關焦點

  • 一文搞懂分布式事務-CAP理論
    網際網路系統中,分布式事務是無法避免的,目前多數解決方案是BASE理論,最終一致性,結合事務補償。1.什麼是CAP理論。因為事務過程中,系統處於一個不一致狀態,不同的節點的數據並不完全一致。比如,client無法讀取到未提交的事務的數據,也不會讀到事務中間寫入的數據。可用性(Availability)非故障節點在合理的時間內返回合理的響應(不是錯誤和超時響應)。不能是錯誤或者是超時,結果是合理的,並不是一定是"正確"的結果。
  • 一文詳解 SpringBoot 多數據源中的分布式事務
    隨著微服務的拆分,肯定設計到分庫分表,但這之中肯定設計到分布式事務。最典型的例子就是銀行轉帳,比如銀行A給銀行B轉帳500 塊錢,流程肯定是銀行A-500,銀行B+500,在這個過程要麼都成功,要麼都成仁。
  • 一文解決:25張圖讓你徹底掌握分布式事務原理
    所以 2PC 在分布式應用場景中很少使用。所以前文提到的電商場景無法使用 2PC,因為 shopping-service 通過 RPC 接口或者 Rest 接口調用 repo-service 和 order-service 間接訪問 repo_db 和 order_db。除非 shopping-service 直接配置 repo_db 和 order_db 作為自己的資料庫。
  • 分布式事務和分布式hash
    NeverTh | 作者urlify.cn/fM36be | 來源分布式事務是什麼?分布式事務就是保證各個微服務之間數據一致,本質上就是保證不同資料庫的數據一致性。大致流程:準備階段 向各個參與者發送準備命令,可以理解為把除了提交事務之外的事情都做好。所有參與者都返回準備成功則下一階段提交事務,否則下一階段協調者就會向所有參與者發送回滾事務的請求,即分布式事務執行失敗。提交階段 可能提交事務也可能回滾事務,並且存在回滾失敗或者提交失敗,失敗之後就會不斷重試。
  • TX-LCN—分布式事務框架(一)
    一、分布式事務1.分布式事務是什麼?在分布式系統中,事務參與者在不同的分布式節點上或事務操作的數據源不是同一個,這些情況產生的事務都叫做分布式事務。這些問題都可以由分布式事務解決方案TX-LCN解決。一階段提交協議相對簡單。優點也很直觀,它不用再與其他的對象交互,節省了判斷步驟和時間,所以在性能上是在階段提交協議中最好的。但缺點也很明顯:資料庫確認執行事務的時間較長,出問題的可能性就隨之增大。如果有多個數據源,一階段提交協議無法協調他們之間的關係。3.
  • 深入理解分布式事務
    1、什麼是分布式事務分布式事務就是指事務的參與者、支持事務的伺服器、資源伺服器以及事務管理器分別位於不同的分布式系統的不同節點之上。以上是百度百科的解釋,簡單的說,就是一次大的操作由不同的小操作組成,這些小的操作分布在不同的伺服器上,且屬於不同的應用,分布式事務需要保證這些小操作要麼全部成功,要麼全部失敗。本質上來說,分布式事務就是為了保證不同資料庫的數據一致性。
  • 阿里P7力推的「分布式事務介紹」看完不虧,看懂血賺
    分布式事務:分布式事務就是指事務的參與者、支持事務的伺服器、資源伺服器以及事務管理器分別位於不同的分布式系統的不同節點之上。簡單的說,就是一次大的操作由不同的小操作組成,這些小的操作分布在不同的伺服器上,且屬於不同的應用,分布式事務需要保證這些小操作要麼全部成功,要麼全部失敗。本質上來說,分布式事務就是為了保證不同資料庫的數據一致性。
  • 阿里終面:分布式事務原理
    現代企業多採用分布式的微服務,因此更多的是要解決多個微服務之間的分布式事務問題。即這些方案本質上都是事務協調者協調各個事務參與者的本地事務的進度,使所有本地事務共同提交或回滾,最終達成一種全局的 ACID 特性。在協調的過程中,協調者需要收集各個本地事務的當前狀態,並根據這些狀態發出下一階段的操作指令。
  • 透徹,分布式事務一網打盡
    然後再分析一波分布式事務框架 Seata 的具體實現,看看分布式事務究竟是如何落地的,畢竟協議要落地才是有用的。並且在我們平日的談論中,所謂的事務往往簡單的指代一系列的操作全部執行成功,或者全部失敗,不會出現一些成功一些失敗的情形。清晰了平日我們對事務的定義之後,再來看看什麼是分布式事務。分布式事務由於網際網路的快速發展,以往的單體架構頂不住這麼多的需求,這麼複雜的業務,這麼大的流量。
  • 基於MQ的分布式事務方案,斷電了咋辦
    涉及到分布式、微服務,面試一定會問分布式事務的處理方案,強一致性這種就不說了,很好奇現在是否還有企業在分布式系統中使用強一致性。最終一致性的實現,例如2PC、TCC本文就不說了,性能上,實現成本上都不理想。我從工作中以及跟朋友交流接觸到的消息來看,採用MQ較多。這就衍生出一個被問到很多次的問題:給MQ發消息失敗了怎麼辦,例如MQ伺服器斷電了。
  • 想要輕鬆搞定MySQL事務?一招解決分布式一致性
    TCC將事務提交劃分成兩個階段,Try即為一階段,Confirm 和 Cancel 是二階段並行的兩個分支,二選一。從階段劃分上非常像2PC,我們是否可以說TCC是一種2PC或者2PC變種呢?Saga的定義是 「長時間活動的事務 」(Long Lived Transaction,後文簡稱為LLT)。他是普林斯頓大學 HECTOR GARCIA-MOLINA 教授在1987年的一篇關於分布式資料庫的論文中提出來的概念。Long Lived 從字面意義上不清晰,Long 到底意味著多長?
  • 為什麼要有分布式事務 分布式事務解決的什麼問題 一次解答
    可以這麼認為,分布式事務是在分布式環境下能保證數據一致性程序單元 在說說什麼是數據一致性,數據一致性是相對的,是複合邏輯的數據統一。  比如張三轉帳給李四,張三-100,李四+100. 這是一致。       解釋 分布式環境 為什麼會出 一致性問題,所以分布式事務就是來解決這些問題的。
  • 如何選擇分布式事務解決方案?
    阿里妹導讀:分布式事務中涉及的參與者分布在異步網絡中,參與者通過網絡通信來達到分布式一致性,網絡通信不可避免出現失敗、超時的情況,因此分布式事務的實現比本地事務面臨更多的困難。本文歸納總結五種分布式事務解決方案,並剖析其特點。較長,同學們可收藏後再看。文末福利:Java 程式設計師學習清單。
  • 最全的分布式事務總結
    事務的定義 22. 資料庫本地事務四大特性 ACID 23. mysql InnoDB 實現原理 24. 什麼是分布式事務 35. 分布式事務產生的原因 46. 分布式事務的基礎理論 47. 分布式事務協議 58. 分布式常用解決方案 79.
  • 分布式事務,看這篇就夠了
    所以 2PC 在分布式應用場景中很少使用。所以前文提到的電商場景無法使用 2PC,因為 shopping-service 通過 RPC 接口或者 Rest 接口調用 repo-service 和 order-service 間接訪問 repo_db 和 order_db。除非 shopping-service 直接配置 repo_db 和 order_db 作為自己的資料庫。
  • 分布式事務淺析及簡單實現
    作者:翟飛在分布式系統中,為了保證數據的高可用,通常,我們會將數據保留多個副本(replica),這些副本會放置在不同的物理的機器上。為了對用戶提供正確的 CRUD 等語義,我們需要保證這些放置在不同物理機器上的副本是一致的。分布式事務在現在遍地都是分布式部署的系統中幾乎是必要的。
  • Spring Boot整合分布式事務簡介
    一. 分布式事務簡介1.什麼是分布式事務百度百科對分布式事務的解釋如下:分布式事務就是指事務的參與者、支持事務的伺服器、資源伺服器以及事務管理器分別位於分布式系統的不同節點之上。XA 事務1. XA協議XA(eXtended Architecture)是指由X/Open 組織提出的分布式交易處理的規範。XA 是一個分布式事務協議,由Tuxedo 提出,所以分布式事務也稱為XA 事務。
  • 這樣理解分布式事務你是不是就會懂了?
    分布式事務主要解決分布式一致性的問題。說到底就是數據的分布式操作導致僅依靠本地事務無法保證原的性。與單機版的事務不同的是,單機是把多個命令打包成一個統一處理,分布式事務是將多個機器上執行的命令打包成一個命令統一處理。
  • 分布式事務的 N 種實現「轉」
    2PC 是幾乎所有分布式事務算法的基礎,後續的分布式事務算法幾乎都由此改進而來。需求樣例這裡我們定義一個充值需求,後續我們在各個實現中看看如何為該需求實現分布式事務。阿里開源,其特點是用一個事務管理器,來管理每個服務的事務,本質上是 2PC(後文會解釋) 的一種實現。
  • 一行代碼,保障分布式事務一致性—GTS
    而對於Chris Richardson提到的第二個問題,現在還沒有通用方案很好的解決微服務產生的事務問題。分布式事務已經成為微服務落地最大的阻礙,也是最具挑戰性的一個技術難題。 為此,本文將深入和大家探討微服務架構下,分布式事務的各種解決方案,並重點為大家解讀阿里巴巴提出的分布式事務解決方案----GTS。