螞蟻金服分佈式事務開源以及實踐 | SOFA 開源一週年獻禮

上週,分佈式事務 Fescar 宣佈進行品牌升級:git

Thanks, Fescar ❤️,github

Hello, Seata 🚀。數據庫

Seata 意爲:Simple Extensible Autonomous Transaction Architecture,是一套一站式分佈式事務解決方案。性能優化

項目地址:github.com/seata/seata網絡

image.png

螞蟻金服在 Seata 0.4.0 版本加入了 TCC 模式,後續也會持續輸入。架構

爲了幫助你們理解,分佈式事務開源負責人紹輝進行了一次線下分享,詳細講述了分佈式事務在螞蟻金服的發展,但願能夠幫助你們理解分佈式事務,如下爲分享的文字整理版本。併發

前言

今天的分享將從如下三個部分展開:分佈式事務問題產生的背景、螞蟻金服分佈式事務以及分佈式事務 Seata 的 Roadmap。框架

image.png

分享嘉賓:紹輝 螞蟻金服 分佈式事務開源負責人分佈式

一、分佈式事務問題產生的背景

1.一、數據庫的水平拆分

螞蟻金服早期,業務量比較小,單庫單表便能知足業務需求;可是隨着業務的發展,單庫單表數據庫逐漸成爲瓶頸。爲了解決數據庫的瓶頸問題,咱們對數據庫進行了水平拆分。拆分所帶來的一個問題就是之前一個數據庫上便能完成的寫操做如今要跨多個數據庫,由此帶來了跨庫事務問題。微服務

image.png

1.二、業務的服務化拆分

螞蟻金服早期是單系統架構,全部業務服務幾乎都在少數幾個 APP 中。隨着業務的發展,業務愈來愈複雜,服務之間的耦合度也愈來愈高,故咱們對系統進行了重構,服務按照功能進行解耦和垂直拆分。拆分以後所帶來的問題就是一個業務活動原來只須要調用一個服務就能完成,如今須要調用多個服務才能完成,由此產生了跨服務事務問題。

image.png

1.三、轉帳案例說明數據一致性問題

數據庫的水分拆分以及服務的垂直拆分,所帶來的問題是一個業務活動一般要調用多個服務、訪問多個數據庫才能完成。

以金融業務場景下的轉帳場景爲例,轉帳服務要完成如下操做:

  1. 調用交易系統服務建立交易訂單;
  2. 調用支付系統記錄支付明細;
  3. 調用帳務系統執行 A 扣錢;
  4. 調用帳務系統執行 B 加錢。

以上 4 個操做要跨 3 個系統,訪問 4 個數據庫。而網絡、數據庫、機器等都具備不可靠性,咱們很難保證以上 4 個操做能 100% 所有成功。

在金融屬性的業務中,不容許 A 帳戶的錢扣了,而 B 帳戶的錢沒有加上的現象出現,因此咱們必須想辦法保證 1 ~ 4 這四個操做要麼所有成功,要麼所有失敗;因此螞蟻金服自主研發了分佈式事務中間件,解決跨服務、跨數據庫的數據一致性問題。

image.png

二、螞蟻金服分佈式事務

2.一、分佈式事務理論基礎

在介紹螞蟻金服的分佈式事務中間件以前,先介紹一些分佈式事務的理論背景。

  • 2PC

兩階段提交協議(Two Phase Commitment Protocol)是分佈式事務最基本的協議。在兩階段提交協議中,有一個事務管理器和多個資源管理器,事務管理器分兩階段協調資源管理器。在第一階段,事務管理器詢問全部資源管理器準備是否成功。若是全部資源均準備成功,那麼在第二階段事務管理器會要求全部資源管理器執行提交操做;若是任一資源管理器在第一階段返回準備失敗,那麼事務管理器會要求全部資源管理器在第二階段執行回滾操做。經過事務管理器的兩階段協調,最終全部資源管理器要麼所有提交,要麼所有回滾,最終狀態都是一致的。

image.png

  • TCC

資源管理器有不少實現方式,其中 TCC(Try-Confirm-Cancel)是資源管理器的一種服務化的實現。TCC 是一種比較成熟的分佈式事務解決方案,可用於解決跨數據庫、跨服務業務操做的數據一致性問題。TCC 其 Try、Confirm、Cancel 3 個方法均由業務編碼實現,故 TCC 能夠被稱爲是服務化的資源管理器。

TCC 的 Try 操做做爲一階段,負責資源的檢查和預留;Confirm 操做做爲二階段提交操做,執行真正的業務;Cancel 是二階段回滾操做,執行預留資源的取消,使資源回到初始狀態。

以下圖所示,用戶實現 TCC 服務以後,該 TCC 服務將做爲分佈式事務的其中一個資源,參與到整個分佈式事務中。事務管理器分兩個階段協調 TCC 服務,在第一階段調用全部 TCC 服務的 Try 方法,在第二階段執行全部 TCC 服務的 Confirm 或者 Cancel 方法,最終全部 TCC 服務要麼所有都是提交的、要麼所有都是回滾的。

image.png

2.二、螞蟻金服分佈式產品介紹

螞蟻金服從 2007 年開始作分佈式事務,至今已經有 12 年曆史。螞蟻金服的分佈式事務最初是採用 TCC 實現的,TCC 模式幫螞蟻業務解決了各種金融核心場景下的數據一致性問題。

2007 年咱們開始支持雙十一,爲了知足雙十一的高性能需求,咱們對分佈式事務作了一系列的性能優化。

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

2014年,螞蟻金服分佈式事務中間件開始經過螞蟻金融雲對外輸出,咱們發展了一大批的外部用戶;在發展外部客戶的過程當中,外部客戶表示願意犧牲一部分性能(無螞蟻的業務規模)以換取接入便利性和無侵入性。

因此在 2015年,咱們開始作無侵入的事務解決方案:FMT 模式和 XA 模式。

image.png

螞蟻金服分佈式事務中間件通過長期演進,目前積累了 TCC、FMT 和 XA 三種模式,具備豐富的應用場景。下面分別介紹這三種模式。

2.三、TCC 模式

螞蟻金服的 TCC 模式和前面介紹 TCC 理論中提的 TCC 原理是一致的。不一樣的是,咱們在整個分佈式事務執行過程當中,會去記錄事務日誌,一個分佈式事務會產生一條主事務記錄(對應發起方)和若干分支事務記錄(對應 TCC 參與者)。記錄事務日誌的目的是,當分佈式事務執行過程當中出現異常中斷時,事務恢復服務經過輪詢事務日誌,找出這個異常中斷的事務,補償執行該異常事務剩餘未完成的動做,整個分佈式事務的最終狀態要麼所有提交,要麼所有回滾。

image.png

TCC 設計規範和注意事項:

用戶在接入 TCC 時,大部分工做都集中在如何實現 TCC 服務上。通過螞蟻金服多年的 TCC 應用實踐,總結以下在 TCC 設計和實現過程當中的注意事項:

一、業務操做分兩階段完成:

接入 TCC 前,業務操做只須要一步就能完成。可是在接入 TCC 以後,須要考慮如何將其分紅兩個階段完成:把資源的檢查和預留放在一階段的 Try 操做中進行,把真正的業務操做的執行放在二階段的 Confirm 操做中進行。

如下舉例說明業務模式如何分紅兩階段進行設計,舉例場景:「帳戶 A 的餘額中有 100 元,須要扣除其中 30 元」。

在接入 TCC 以前,用戶編寫 SQL:「update 帳戶表 set 餘額 = 餘額 -20 where 帳戶 = A」,便能一步完成扣款操做。

在接入 TCC 以後,就須要考慮如何將扣款操做分紅兩步完成:

  • Try 操做:資源的檢查和預留。

在扣款場景,Try 操做要作的事情就是先檢查 A 帳戶餘額是否足夠,再凍結要扣款的 30 元(預留資源);此階段不會發生真正的扣款。

  • Confirm 操做:執行真正業務的提交。

在扣款場景下,Confirm 階段作的事情就是發生真正的扣款,把 A 帳戶中已經凍結的 30 元錢扣掉。

  • Cancel 操做:預留資源的釋放。

在扣款場景下,扣款取消,Cancel 操做執行的任務是釋放 Try 操做凍結的 30 元錢,使 A 帳戶回到初始狀態。

image.png

二、併發控制

用戶在實現 TCC 時,應當考慮併發性問題,將鎖的粒度降到最低,以最大限度提升分佈式事務的併發性。

如下仍是以 A 帳戶扣款爲例,「帳戶 A 上有 100 元,事務 T1 要扣除其中的 30 元,事務 T2 也要扣除 30 元,出現併發」。

在一階段 Try 操做中,分佈式事務 T1 和分佈式事務 T2 分別凍結資金的那一部分資金,相互之間無干擾。這樣在分佈式事務的二階段,不管 T1 是提交仍是回滾,都不會對 T2 產生影響,這樣 T1 和 T2 能夠在同一筆業務數據上並行執行。

image.png

三、容許空回滾

以下圖所示,事務協調器在調用 TCC 服務的一階段 Try 操做時,可能會出現由於丟包而致使的網絡超時。此時事務管理器會觸發二階段回滾,調用 TCC 服務的 Cancel 操做,而 Cancel 操做調用未出現超時。

TCC 服務在未收到 Try 請求的狀況下收到 Cancel 請求,這種場景被稱爲空回滾。空回滾在生產環境常常出現,用戶在實現 TCC 服務時,應容許空回滾的執行,即收到空回滾時返回成功。

image.png

四、防懸掛控制

以下圖所示,事務協調器在調用 TCC 服務的一階段 Try 操做時,可能會出現因網絡擁堵而致使的超時。此時事務管理器會觸發二階段回滾,調用 TCC 服務的 Cancel 操做,Cancel 調用未超時。在此以後,擁堵在網絡上的一階段 Try 數據包被 TCC 服務收到,出現二階段 Cancel 請求比一階段 Try 請求先執行的狀況,此 TCC 服務在執行晚到的 Try 以後,將永遠不會再收到二階段的 Confirm 或者 Cancel,形成 TCC 服務懸掛。

用戶在實現 TCC 服務時,要容許空回滾,可是要拒絕執行空回滾以後 Try 請求,要避免出現懸掛。

image.png

五、冪等控制

不管是網絡數據包重傳,仍是異常事務的補償執行,都會致使 TCC 服務的 Try、Confirm 或者 Cancel 操做被重複執行;用戶在實現 TCC 服務時,須要考慮冪等控制,即 Try、Confirm、Cancel 執行一次和執行屢次的業務結果是同樣的。

image.png

2.四、FMT 模式

FMT(Framework-managed transaction)框架管理事務,是一種無侵入的事務解決方案。該模式下,分佈式事務框架會託管全部的事務操做,事務的一階段和二階段操做均由框架自動生成,用戶 SQL 將做爲分佈式事務的一階段,而二階段由框架自動生成「提交/回滾」操做。

image.png

一、FMT 一階段

FMT 的一階段是分佈式事務框架自動生成的,分佈式事務框架會在一階段攔截業務的 SQL 語句,在業務執行前,將業務 SQL 修改前的數據保存成原快照(undo log);在業務 SQL 執行以後,將更新的業務數據保存成新快照(redo log),最後用表名+主鍵值的方式生成行鎖,來作分佈式事務的併發控制。

解析 SQL 語義的目的是爲了便於找到業務要更新的業務數據;而提取表元數據的目的爲了找到業務表的主鍵和惟一性約束鍵,便於生成行鎖。

image.png

二、FMT 二階段

FMT 模式下,一階段主要是爲了保持 undo log、redo log 等中間數據,保持這些中間數據的目的是爲了生成二階段的操做。

image.png

  • FTM 二階段提交

二階段提交操做是自動生成的,因爲業務 SQL 在一階段已經提交至數據庫,故二階段提交只需刪除一階段保存的中間數據(undo log、redo log和行鎖)。

  • FMT 二階段回滾

二階段回滾操做也是自動生成的,目的是使用 undo log 回滾一階段業務 SQL 更新的業務數據。具體操做步驟是:

首先,須要校驗髒寫。校驗髒寫的方式使用 redo log 與數據庫當前值進行對比,若是兩份數據徹底一致則說明沒有出現髒寫,若是兩份數據不一致,則說明出現髒寫;若是出現髒寫,就須要轉人工處理,不能再使用 undo log 回滾業務數據。

而後,還原業務數據。若是未出現髒寫,則使用 undo log 回滾業務數據,使業務數據恢復到初始的值。

最後,刪除中間數據。業務數據還原以後,即可以將中間數據(undo log、redo log和行鎖)所有刪掉,完成回滾操做。

2.五、XA 模式

XA 模式是另一種無侵入的分佈式事務解決方案,不一樣於 FMT 的是,XA 模式下,全部一階段和二階段都由數據庫來完成。螞蟻分佈式事務框架在一階段調用數據的一階段 XA 接口(xa prepare),在二階段調用數據的二階段 XA 接口(xa commit/xa rollback)。

image.png

XA 模式有如下特色:

  1. 主流的數據庫均支持 XA 寫,覆蓋面廣;
  2. 與螞蟻自研數據庫 Oceanbase 深度定製,解決 XA 事務性能問題;
  3. 藉助數據庫的 MVCC 特性,實現了分佈式 MVCC 和全局一致性讀。

三、螞蟻金服投入分佈式事務 Seata 社區共建

2019 年 1 月,基於技術積累,阿里巴巴中間件團隊發起了開源項目 Fescar(Fast & EaSy Commit And Rollback, Fescar),和社區一塊兒共建分佈式事務解決方案。Fescar 爲解決微服務架構下的分佈式事務問題交出了一份不同凡響的答卷。而 Fescar 的願景是讓分佈式事務的使用像本地事務的使用同樣簡單和高效。最終的目標是但願可讓 Fescar 適用於全部的分佈式事務場景。

爲了達到適用於更多的分佈式事務業務場景的目標,螞蟻金服加入 Fescar 社區共建,加入了 TCC 模式。

螞蟻金服的加入引起了社區核心成員的討論,爲了達到適用於全部的分佈式事務業務場景的目標,也爲了社區更中立、更開放、生態更加豐富,社區核心成員們決定進行品牌升級,更名 Seata。Seata 意爲:Simple Extensible Autonomous Transaction Architecture,是一套一站式分佈式事務解決方案。

自開源以來,Seata 一直受益於社區的貢獻。截止目前,分佈式事務 Seata 已經擁有超過 7000 的 Star ,超 55 位 Contributors,開發者們的加入,使得社區的生態更加豐富也更有活力。

2019 年 5 月,Seata 將加入服務端 HA 集羣支持,今後,Seata 能夠達到生產環境使用的標準。

歡迎對分佈式事務有熱情的開發者們加入社區的共建中來,爲 Seata 帶來更多的想象空間。

分佈式事務.png

總結

公衆號:金融級分佈式架構(Antfin_SOFA)

相關文章
相關標籤/搜索