當前位置:
首頁 > 知識 > 螞蟻金服大規模分散式事務實踐及四種分散式事務模式

螞蟻金服大規模分散式事務實踐及四種分散式事務模式

螞蟻金服大規模分散式事務實踐及四種分散式事務模式


本文詳細講解了在分散式架構演進中,螞蟻金服面對的跨服務、跨資料庫的業務數據一致性問題以及應對措施,並分享了分散式事務 Seata 的 AT、TCC、Saga 和 XA 四種模式。

作者/來源: 紹輝


本文整理自螞蟻金服技術專家、分散式事務 Seata 發起者之一張森(花名:紹輝)在 GIAC 全球互聯網架構大會的分享。本文詳細講解了在分散式架構演進中,螞蟻金服面對的跨服務、跨資料庫的業務數據一致性問題以及應對措施,並分享了分散式事務 Seata 的 AT、TCC、Saga 和 XA 四種模式。

一、自研分散式事務解決數據一致性問題

1.1 分散式事務問題產生原因

1.1.1 資料庫的水平拆分螞蟻金服的業務資料庫起初是單庫單表,但隨著業務數據規模的快速發展,數據量越來越大,單庫單表逐漸成為瓶頸。所以我們對資料庫進行了水平拆分,將原單庫單表拆分成資料庫分片。

如下圖所示,分庫分表之後,原來在一個資料庫上就能完成的寫操作,可能就會跨多個資料庫,這就產生了跨資料庫事務問題。

螞蟻金服大規模分散式事務實踐及四種分散式事務模式

1.1.2 業務服務化拆分在業務發展初期,「一塊大餅」的單業務系統架構,能滿足基本的業務需求。但是隨著業務的快速發展,系統的訪問量和業務複雜程度都在快速增長,單系統架構逐漸成為業務發展瓶頸,解決業務系統的高耦合、可伸縮問題的需求越來越強烈。

如下圖所示,螞蟻金服按照面向服務(SOA)的架構的設計原則,將單業務系統拆分成多個業務系統,降低了各系統之間的耦合度,使不同的業務系統專註於自身業務,更有利於業務的發展和系統容量的伸縮。

螞蟻金服大規模分散式事務實踐及四種分散式事務模式

業務系統按照服務拆分之後,一個完整的業務往往需要調用多個服務,如何保證多個服務間的數據一致性成為一個難題。


1.2 螞蟻金服遇到的數據一致性問題

在資料庫水平拆分、服務垂直拆分之後,一個業務操作通常要跨多個資料庫、服務才能完成。在分散式網路環境下,我們無法保障所有服務、資料庫都百分百可用,一定會出現部分服務、資料庫執行成功,另一部分執行失敗的問題。

當出現部分業務操作成功、部分業務操作失敗時,業務數據就會出現不一致。以金融業務中比較常見的「轉賬」場景為例:

如下圖所示,在支付寶的「轉賬」操作中,要分別完成 4 個動作:

  1. 創建交易訂單;
  2. 創建支付訂單;
  3. A 賬戶扣錢;
  4. B 賬戶加錢;

而完成以上操作要分別訪問 3 個服務和 4 個資料庫。

螞蟻金服大規模分散式事務實踐及四種分散式事務模式

在分散式環境下,肯定會出現部分操作成功、部分操作失敗的問題,比如:A 賬戶的錢扣了,但是 B 賬戶的錢沒加上,這就造成了資金損失,影響資金安全。

在金融業務場景下,我們必須保證「轉賬」的原子性,要麼所有操作全部成功,要麼全部失敗,不允許出現部分成功部分失敗的現象。

為了解決跨資料庫、跨服務的業務數據一致性問題,螞蟻金服自主研發了分散式事務中間件。

從 2007 年開始做分散式事務並支持雙十一,至今已經有 12 年。

2013 年,螞蟻金服開始做單元化改造,分散式事務也開始支持 LDC、異地多活和高可用容災,解決了機房故障情況下服務快速恢復的問題。

2014 年,螞蟻金服 分散式事務中間件 (Distributed Transaction-eXtended) (DTX)開始通過螞蟻金融雲對外輸出,我們發展了一大批的外部用戶。在發展外部客戶的過程中,外部客戶表示願意犧牲一部分性能(無螞蟻的業務規模)以換取接入便利性和無侵入性。所以在 2015 年,我們開始做無侵入的事務解決方案:FMT 模式和 XA 模式。


二、投入開源社區,共建開源分散式事務 Seata

2.1 分散式事務 Seata 介紹

Seata( 簡單可擴展自治事務框架 (Simple Extensible Autonomous Transaction Architecture))是 2019 年 1 月份螞蟻金服和阿里巴巴共同開源的分散式事務解決方案。Seata 開源半年左右,目前已經有接近一萬 star,社區非常活躍。我們熱忱歡迎大家參與到 Seata 社區建設中,一同將 Seata 打造成開源分散式事務標杆產品。

螞蟻金服大規模分散式事務實踐及四種分散式事務模式


2.2 分散式事務 Seata 產品模塊

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

螞蟻金服大規模分散式事務實踐及四種分散式事務模式

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

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

2.3 分散式事務 Seata 解決方案

Seata 會有 4 種分散式事務解決方案,分別是 AT 模式、TCC 模式、Saga 模式和 XA 模式。

2.3.1 AT 模式今年 1 月份,Seata 開源了 AT 模式。AT 模式是一種無侵入的分散式事務解決方案。在 AT 模式下,用戶只需關注自己的「業務 SQL」,用戶的 「業務 SQL」 作為一階段,Seata 框架會自動生成事務的二階段提交和回滾操作。

螞蟻金服大規模分散式事務實踐及四種分散式事務模式

AT 模式如何做到對業務的無侵入:

一階段

在一階段,Seata 會攔截「業務 SQL」,首先解析 SQL 語義,找到「業務 SQL」要更新的業務數據,在業務數據被更新前,將其保存成「before image」,然後執行「業務 SQL」更新業務數據,在業務數據更新之後,再將其保存成「after image」,最後生成行鎖。以上操作全部在一個資料庫事務內完成,這樣保證了一階段操作的原子性。

螞蟻金服大規模分散式事務實踐及四種分散式事務模式

二階段提交

二階段如果是提交的話,因為「業務 SQL」在一階段已經提交至資料庫, 所以 Seata 框架只需將一階段保存的快照數據和行鎖刪掉,完成數據清理即可。

螞蟻金服大規模分散式事務實踐及四種分散式事務模式

二階段回滾

二階段如果是回滾的話,Seata 就需要回滾一階段已經執行的「業務 SQL」,還原業務數據。回滾方式便是用「before image」還原業務數據;但在還原前要首先要校驗臟寫,對比「資料庫當前業務數據」和 「after image」,如果兩份數據完全一致就說明沒有臟寫,可以還原業務數據,如果不一致就說明有臟寫,出現臟寫就需要轉人工處理。

螞蟻金服大規模分散式事務實踐及四種分散式事務模式

AT 模式的一階段、二階段提交和回滾均由 Seata 框架自動生成,用戶只需編寫「業務 SQL」,便能輕鬆接入分散式事務,AT 模式是一種對業務無任何侵入的分散式事務解決方案。

2.3.2 TCC 模式2019 年 3 月份,Seata 開源了 TCC 模式,該模式由螞蟻金服貢獻。TCC 模式需要用戶根據自己的業務場景實現 Try、Confirm 和 Cancel 三個操作;事務發起方在一階段 執行 Try 方式,在二階段提交執行 Confirm 方法,二階段回滾執行 Cancel 方法。

螞蟻金服大規模分散式事務實踐及四種分散式事務模式

TCC 三個方法描述:

  1. Try:資源的檢測和預留;
  2. Confirm:執行的業務操作提交;要求 Try 成功 Confirm 一定要能成功;
  3. Cancel:預留資源釋放。

業務模型分 2 階段設計:

用戶接入 TCC ,最重要的是考慮如何將自己的業務模型拆成兩階段來實現。

以「扣錢」場景為例,在接入 TCC 前,對 A 賬戶的扣錢,只需一條更新賬戶餘額的 SQL 便能完成;但是在接入 TCC 之後,用戶就需要考慮如何將原來一步就能完成的扣錢操作,拆成兩階段,實現成三個方法,並且保證一階段 Try 成功的話 二階段 Confirm 一定能成功。

螞蟻金服大規模分散式事務實踐及四種分散式事務模式

如上圖所示,Try 方法作為一階段準備方法,需要做資源的檢查和預留。在扣錢場景下,Try 要做的事情是就是檢查賬戶餘額是否充足,預留轉賬資金,預留的方式就是凍結 A 賬戶的 轉賬資金。Try 方法執行之後,賬號 A 餘額雖然還是 100,但是其中 30 元已經被凍結了,不能被其他事務使用。

二階段 Confirm 方法執行真正的扣錢操作。Confirm 會使用 Try 階段凍結的資金,執行賬號扣款。Confirm 方法執行之後,賬號 A 在一階段中凍結的 30 元已經被扣除,賬號 A 餘額變成 70 元 。

如果二階段是回滾的話,就需要在 Cancel 方法內釋放一階段 Try 凍結的 30 元,使賬號 A 的回到初始狀態,100 元全部可用。

用戶接入 TCC 模式,最重要的事情就是考慮如何將業務模型拆成 2 階段,實現成 TCC 的 3 個方法,並且保證 Try 成功 Confirm 一定能成功。相對於 AT 模式,TCC 模式對業務代碼有一定的侵入性,但是 TCC 模式無 AT 模式的全局行鎖,TCC 性能會比 AT 模式高很多。

2.3.3 Saga 模式Saga 模式是 Seata 即將開源的長事務解決方案,將由螞蟻金服主要貢獻。在 Saga 模式下,分散式事務內有多個參與者,每一個參與者都是一個沖正補償服務,需要用戶根據業務場景實現其正向操作和逆向回滾操作。

分散式事務執行過程中,依次執行各參與者的正向操作,如果所有正向操作均執行成功,那麼分散式事務提交。如果任何一個正向操作執行失敗,那麼分散式事務會去退回去執行前面各參與者的逆向回滾操作,回滾已提交的參與者,使分散式事務回到初始狀態。

螞蟻金服大規模分散式事務實踐及四種分散式事務模式

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

2.3.4 XA 模式XA 模式是 Seata 將會開源的另一種無侵入的分散式事務解決方案,任何實現了 XA 協議的資料庫都可以作為資源參與到分散式事務中,目前主流資料庫,例如 MySql、Oracle、DB2、Oceanbase 等均支持 XA 協議。

XA 協議有一系列的指令,分別對應一階段和二階段操作。「xa start」和 「xa end」用於開啟和結束XA 事務;「xa prepare」 用於預提交 XA 事務,對應一階段準備;「xa commit」和「xa rollback」用於提交、回滾 XA 事務,對應二階段提交和回滾。

在 XA 模式下,每一個 XA 事務都是一個事務參與者。分散式事務開啟之後,首先在一階段執行「xa start」、「業務 SQL」、「xa end」和 「xa prepare」 完成 XA 事務的執行和預提交;二階段如果提交的話就執行 「xa commit」,如果是回滾則執行「xa rollback」。這樣便能保證所有 XA 事務都提交或者都回滾。

螞蟻金服大規模分散式事務實踐及四種分散式事務模式

XA 模式下,用戶只需關注自己的「業務 SQL」,Seata 框架會自動生成一階段、二階段操作;XA 模式的實現如下:

螞蟻金服大規模分散式事務實踐及四種分散式事務模式

一階段

在 XA 模式的一階段,Seata 會攔截「業務 SQL」,在「業務 SQL」之前開啟 XA 事務(「xa start」),然後執行「業務 SQL」,結束 XA 事務「xa end」,最後預提交 XA 事務(「xa prepare」),這樣便完成 「業務 SQL」的準備操作。

二階段提交

執行「xa commit」指令,提交 XA 事務,此時「業務 SQL」才算真正的提交至資料庫。

二階段回滾

執行「xa rollback」指令,回滾 XA 事務,完成「業務 SQL」回滾,釋放資料庫鎖資源。

XA 模式下,用戶只需關注「業務 SQL」,Seata 會自動生成一階段、二階段提交和二階段回滾操作。XA 模式和 AT 模式一樣是一種對業務無侵入性的解決方案;但與 AT 模式不同的是,XA 模式將快照數據和行鎖等通過 XA 指令委託給了資料庫來完成,這樣 XA 模式實現更加輕量化。


三、分散式事務在螞蟻金服的實踐

螞蟻金服從 2007 年開始研發和應用分散式事務中間件,用 TCC 模式解決各類金融場景的數據一致性問題,後續又演進出 FMT(AT)、XA、Saga 等模式,各種模式分別適用於各類業務場景。我們決定將螞蟻金服多年的技術積累開源出來,與社區共享螞蟻金服的科技成果。

螞蟻金服內部的分散式事務產品,在實現原理和使用方式上,與 Seata 類似,不同的是,為了支持雙十一,對性能進行了極致優化,為了支持金融系統的高可用容災,藉助螞蟻金服三地五中心架構實現了分散式事務服務的高可用容災;接下來主要介紹螞蟻金服在性能優化和高可用容災方面的實踐經驗。

螞蟻金服大規模分散式事務實踐及四種分散式事務模式


3.1 極致性能優化

3.1.1 同庫模式通常,一個 TM 會產生一筆主事務日誌,一個 RM 會產生一條分支事務日誌,每個分散式事務由一個 TM 和若干 RM 組成,一個分散式事務總共會有 1+N 條事務日誌(N 為 RM 個數)。

在默認情況下,分散式事務執行過程中客戶端將事務日誌發送給服務端,服務端再將事務日誌存儲至資料庫中,一條事務日誌的存儲鏈路會有 2 次 TCP ,分別是「客戶端到服務端」和「服務端到資料庫」, 我們稱這種模式為異庫模式。

在異庫模式下,分散式事務存儲事務日誌總共需要 2*(1+N) 次左右的 TCP 通信。在 RM 數量較少的業務場景下,分散式事務性能還能接收,但有些業務場景下 RM 數量較多,此時事務內 TCP 數量也會增多,分散式事務性能急劇下降。

螞蟻金服大規模分散式事務實踐及四種分散式事務模式

在事務執行過程中,客戶端和服務端進行通信的目的是為了存儲事務日誌。如果客戶端在存儲事務日誌時,繞過服務端直接將事務日誌寫入資料庫(如上圖「同庫模式」所示),那麼一筆事務日誌的存儲鏈路就由原來的 2 次 TCP 變成只需訪問一次資料庫便可,每條事務日誌的存儲減少了一次 TCP 通信,整個分散式事務就減少了 N+2 次 TCP 請求,分散式事務的性能大幅提升。我們將客戶端直接將事務日誌存儲至資料庫的模式稱為同庫模式。

3.1.2 二階段非同步執行通常情況下,分散式事務發起方會依次執行一階段和二階段方法,然後結束分散式事務,返回結果。如果讓分散式事務發起方執行完一階段之後馬上結束並返回結果,二階段交由獨立的線程或者進程非同步執行,這樣分散式事務的二階段會晚幾秒鐘或者若干分鐘執行,但事務的最終結果不會有任何改變。

二階段非同步執行之後,分散式事務的最終結果不會有任何影響,但是事務發起方要執行的內容減少一半(一階段和二階段都執行變成只執行一階段),直觀的用戶感受是分散式事務的性能提升了 50%。

螞蟻金服大規模分散式事務實踐及四種分散式事務模式


3.2 分散式事務高可用

為了保障金融系統的高可用,分散式事務服務必須達到 99.99% 的可用率。分散式事務使用了螞蟻金服的三地五中心架構部署,在每個機房都獨立部署分散式事務服務,分散式事務服務是無狀態的,而底層資料庫副本在各機房間也是雙向同步,這樣業務流量從一個機房切到另外一個機房,分散式事務服務不會對業務有任何影響,從而保證了分散式事務服務的高可用。

螞蟻金服大規模分散式事務實踐及四種分散式事務模式


四、總結

在分散式架構演進中,螞蟻金服對資料庫進了水平拆分,對服務面向功能進行了服務化拆分,從而出現了跨服務、跨資料庫的業務數據一致性挑戰。

2007 年,螞蟻金服自主研發分散式事務中間件經歷 12 年的嚴苛業務錘鍊。2019 年,將多年的技術積累分享給開源分散式事務 Seata,並持續投入社區共建。目前 Seata 提供了 AT、TCC、Saga 和 XA 四種模式,每一種模式分別有各自的應用場景,豐富的解決方案幫助用戶解決給了各類場景的數據一致性問題。

最後一部分,分享了螞蟻金服具體的實踐。為了支持雙十一的高性能需求,對分散式事務進行了極致的性能優化,例如同庫模式、二階段非同步執行。為了使金融服務的可用性達到 99.99%,螞蟻金服分散式事務採用三地五中心架構,異地多活的部署模式保障了分散式事務服務的高可用。

點擊「了解更多」可訪問文內鏈接

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 Linux技術 的精彩文章:

使用 ImageGlass 以幻燈片形式快速查看 JPG 圖像
每日安全資訊:數據跟蹤應該是選擇加入而不是選擇退出

TAG:Linux技術 |