用 Seata 搞定分散式事務的規範化建設-賦能產研|提質增效
一、背景
隨著微服務架構的演進,單體應用按照服務維度進行拆分,組織架構也隨之演進以橫向、縱向維度拆分;導致了原來呼叫一個服務的一個介面就完成的功能,現在需要協同呼叫多個服務的多個介面才能完成。原來在一個庫中就完成的功能,現在可能要涉及多個庫的多張表,通常還會有多種儲存介質一起協作以支撐資料儲存;而這些情況下傳統的本地事務不能保證資料的一致性。
以下圖購買商品下單業務為例,下訂單由訂單服務、賬戶服務和庫存服務 3 個服務來完成。
本地事務只能保證每個服務各自的本地事務,比如庫存服務 DB 操作異常,其透過本地事務回滾後庫存資料無異常,但訂單和賬戶的記錄並未回滾,因為他們並不知道庫存異常了,這便是典型的分散式資料一致性問題。
在生產環境中裝置、程式等都是不可靠的,若它們發生意外則會出現資料不一致的情況;在對資料的一致性要求高的業務場景中,若缺少有效工具的輔助,則常常需要透過如客訴、人工抽檢核對等方式來發現問題,之後再交給程式設計師透過人工智慧來排查、修復;這種方式雖也能解決問題,但從時效和人力兩方面看都很低效,同時也拉低服務質量。
雖然 BASE 論文基於 CAP 定理分析並表述了分散式系統追求高可用的場景下不得不弱化強一致性的觀點,並對眾人產生了深遠的影響,但並不能理解為要降低對一致性的要求,尤其是在某些特殊業務場景中,資料容易出現非預期的不一致或高延遲的不一致時,會給客戶帶來極其不好的使用體驗,嚴重時甚至導致運營無法推進、產品無法落地。所以需要重新審視資料一致性問題,它實際是與系統的可擴充套件性和高可用同等重要 是【基礎 IT 架構】支撐業務高質量轉型、升級的重點也是難點。
二、訴求與選型
應對業務規模、資料規模的不斷擴大,主流技術方案都是透過橫向擴充套件節點以提高非熱點資料的併發效能;而橫向擴充套件節點的效果體現在如下 2 方面:
擴充套件功能節點:對應用進行微服務化改造。 擴充套件資料節點:增加資料分片如分庫分表,使用混合儲存如 mysql + ES 的組合等。
微服務演進方案的優勢很多,但同時也必然會帶來業務資料不一致的問題,有些情況還讓人特頭疼。在之前很長一段時間,受分散式事務技術成熟度、業務的複雜性及實現價效比等多重因素的影響,關於該如何應對分散式業務資料一致性的這個難題,似乎分化成兩種相對的觀念:一種是困難太多、價效比不高,一致性保障讓人有心無力,進而置之不理;另一種則是需迎難而上,各顯神通,導致出現了許多有意思的變種實現,有些可能既不通用也不健壯。
從標準架構規範的大局來看,置之不理或各顯神通這兩種情況都非合理狀態,實際上需要的是一套規範的、通用的、可靠的分散式事務解決方案,能夠幫助開發者在分散式的環境下,既能保證業務資料的一致性,又不需要投入太多的資源用於業務資料一致性的開發維護,還能加快迭代速度保障專案交付。
分散式事務解決方案通常分為兩大類,其中一類是非同步確保型,另一類是非非同步確保型;非同步確保型非本篇主題,暫且不提。重點探討非非同步確保型,在行業中開源產品有Seata
、tcc-transaction
、TX-LCN
、
Hmily
、ByteTCC
、EasyTransaction
等,它們各有特色後續會整理一篇稍詳細點的能力對比介紹。從它們所提供方案的分類來說有:補償型-TCC 、無侵入性-AT、強一致型-XA 、補償性-SAGA 以及LCN。Seata 的能力比較全面,所提供方案種類最多,而且社群活躍度最高。
Seata 從設計層面將事務參與者的角色分為 TC、RM、TM,事務的整體運轉模型如上圖,基於此模型,Seata 支援了TC、AT、XA、SAGA 這 4 種方案,能應對許多應用場景,個人感覺比較貼合日常分散式事務能力訴求的的是 TC 叢集的高可用架構 以及 TCC 和 AT 這兩種事務模式的能力。
1)TC 叢集具有高可用架構
應用到叢集是這樣一個間接的關係:應用 -》事務分組 -》TC 叢集,應用啟動後所指定的事務分組不能變,可透過配置中心變更事務分組所屬的 TC 叢集,Seata 客戶端監聽到這個變更後,會切換到新的 TC 叢集。
2)TCC 模式
TCC 模式要求由業務側透過編碼實現 Try、Confirm、Cancel 3 個方法,TCC 的 Try 操作作為一階段,負責資源的檢查和預留;Confirm 操作作為二階段提交操作,執行真正的業務;Cancel 操作作為二階段回滾操作,執行預留資源的取消,使資源回到初始狀態。
因為各階段都由業務側編碼實現,所以就大大增加了靈活性,容易實現特定場景下的自定義最佳化和特殊功能開發。這個模式幾乎能滿足任何想要的事務場景,如補償型、資源預留型以及訊息事務型等。但也意味著開發的工作量比較大,對開發者的要求比較高。
無論有沒有本地事務控制都可以使用該模式,與底層資料庫事務實現不相關(無需 JDBC 支援)。
Seata 對 TCC 模式實現的完整度比較高,可應對經典的空回滾、防懸掛和冪等控制這三個問題。
3)AT 模式
若把 TCC 模式類比成手動擋駕駛模式,那麼 Seata 的 AT 模式就好比自動擋駕駛模式,使用者配置下資料來源代理,在需要全域性事務的方法上新增註解即可,就是這麼簡單。AT 模式是基於 DataSource 代理實現的,其核心思想就是由框架託管分散式事務:透過代理 DataSource ,攔截 SQL 執行,增強其執行邏輯,由代理側加入額外的能力以完成分散式事務(好似鋼鐵俠的機甲提供了超強能力)。
要求上下游分支事務都支援 JDBC,且所用的 SQL 需要框架能夠支援,有一定的效能損耗,在應用層增加了全域性鎖(行級鎖),高併發有熱點資料的場景需斟酌。
在業務併發不高、邏輯複雜、對一致性要求較高的場景中特別有優勢,只需要引入依賴後調整少量程式碼,方法上增加註解便可擁有完整的分散式事務的能力;這種場景下,特能體現 AT 模式難度低、效率高、更安全的特點。
基於以上評估,Seata 所兼備的 TC 高可用、 TCC 模式和 AT 模式特別符合一套規範的、通用的、可靠的分散式事務解決方案的訴求,能將分散式事務問題從業務中儘量剝離出來(AT模式剝離的比較徹底),作為一個獨立的技術切面由專人管理運維(獨立的服務端和模組化的客戶端),提供簡單、易用、高效、穩定的分散式事務解決方案,體現出以下價值:
架構複雜度降低:分散式事務這個切面的技術問題,全部由 Seata 所提供的服務能力來解決。 設計和開發成本減輕,加快交付和迭代速度:業務邏輯的設計和開發中,若採用 AT 模式,則無需考慮是否涉及分散式事務,是否需要做額外的準備,專注 SQL 編寫實現業務邏輯即可,對業務 0 侵入 。 運營成本降低,保證業務資料準確度,以及出錯時的自動回滾和及時通知
三、如何推進
當下網際網路大環境不太好(盲猜下半年開始好轉),大多公司會調整為業務導向,因此基礎技術領域的部門需重新審視自己的角色、調整自己職責,不能以技術至上的心態一味追求高精尖,而偏愛技術的個體也需調整思路,全力轉向為開發者服務,賦能產研。在老闆業務導向的方針下,新技術的引入、推進就不能再純粹以技術視角考量,要結合業務,評估是否有痛點,是否有需求。
通常 PMO 與業務部門組織需求和使用場景的溝通後,會得到比較一致的反饋,即較多同事有聽到過 Seata 在其他公司的實踐分享,但此技術的可用性、穩定性方面在自家公司尚無案例借鑑,無法給予充足的信任,即使有需求也不敢貿然明確提出使用 Seata 就能解決問題;他們會希望基礎設施先行,給出相容性、效能、穩定性等方面的一些可靠結論。新能力需要業務方提需求,業務方要基礎設施先提供能力保障,這個“死鎖現象”按照工程化的思路重新梳理,可以跟 PMO 商定徐圖緩進的應對之策:
加強對 Seata 技術層的掌控力,針對公司的技術棧和資料庫中介軟體進行全面的功能性驗證,明確其可靠能力的合集;在此過程中梳理原理、解決問題並將驗證結論等進行整理 透過宣導的方式,進行同步、培訓和引導,互動的過程中,蒐集需求和意向使用者以及其需求場景 理清 Seata 的安全保障機制,以最小測試單元的原則來保障試點應用的接入和驗證。
TCC 模式對程式碼的侵入性較高,需要做大量的改造,這對 Seata 的推進並不友好,而 AT 模式能適配的應用場景很多,只需要少量程式碼的微調即可,並且透過 AT 模式即也能證驗證大部分 Seata 的能力。基於以上考慮,可以將嘗試的方向先聚焦到 AT 模式上,有了 AT 模式的技術積累沉澱後,TCC 模式的應用將會水到渠成。
四、探索 AT 模式
4.1 AT 模式業務無侵入的的原理
1)一階段:
在一階段,Seata 會攔截“業務 SQL”,首先解析 SQL 語義,找到“業務 SQL”要更新的業務資料,在業務資料被更新前,將其讀出儲存成“before image”,然後執行“業務 SQL”更新業務資料,在業務資料更新之後,再將其讀出儲存成“after image”,之後生成事務行鎖資訊並向 TC 申請持有鎖。以上操作全部在一個資料庫事務內完成,這樣保證了一階段操作的原子性。
2)二階段-提交:
二階段如果是提交的話,因為“業務 SQL”在一階段已經提交至資料庫, 所以 Seata 框架只需立即將一階段的事務行鎖釋放後(儘早釋放鎖以提升效能),再將對應”before | after image“資料的清理即可(因為本地事務和全域性鎖都已釋放,此環節可採用更高效能的非同步處理)。
3)二階段-回滾:
二階段如果是回滾的話,Seata 就需要回滾一階段已經執行的“業務 SQL”,還原業務資料。回滾方式便是用“before image”還原業務資料;但在還原前要首先要校驗髒寫,對比“資料庫當前業務資料”和 “after image”,如果兩份資料完全一致就說明沒有髒寫,可以還原業務資料,如果不一致就說明有髒寫,出現髒寫就需要轉人工處理。
AT 模式的一階段、二階段提交\回滾均由 Seata 框架自動生成,使用者只需編寫“業務 SQL”,便能輕鬆接入分散式事務,AT 模式是一種對業務無任何侵入的分散式事務解決方案。
4.2 AT 模式的相容性驗證
針對公司的技術棧做相容性驗證,需主要關注兩方面:一是 RPC 框架,如 Dubbo 的事務ID透傳能力;二是公司的資料庫元件,需考慮如單庫、讀寫分離、分庫分表以及動態資料來源切換等場景下的相容性。基於這些情況在自測階段開發一套分散式的應用,用以驗證各種場景下 Seata AT 模式的相容性情況。
1)RPC 中需保障全域性事務 ID 的透傳能力
分散式事務其實現機制中會有全域性事務標識,即 xid,xid 需隨著 RPC 請求傳遞給各分支事務;下游服務也是根據請求上下文中是否有 xid 來判斷自己是否開啟分支事務
2)資料庫元件可從如以下幾個方面設計用例:
用例 | 相容性 | 描述 |
---|---|---|
批處理 | ||
事務隔離性 | 要使用 Seata 提供的應用層全域性行鎖機制,避免髒寫,保障讀已提交 | |
獨立主庫 | ||
讀寫分離 |
3)分庫分表的情況有些特殊
分庫分表中介軟體的實現通常是透過增加一層邏輯 DataSource 如名為 ShardingDataSource ;在其內部維護著一批物理(物理是形容與真實DB保持物理連結) DataSource,在接收 SQL 後,解析 SQL 並計算路由之後將 SQL 轉交給對應的物理 DataSource 來執行
Seata 所需的後設資料、一階段 UndoLog 的寫表和二階段刪除 UndoLog 或執行資料回滾,這些能力的實現依賴的是物理 DataSource ,因為 Seata 無法得知(也無需參與)如何解析 SQL、如何匹配路由規則、如何選擇庫表;另外 Seata 的自動代理處理是無法識別 DataSource 是不是物理 DataSource
具體如何改造呢?對借鑑業界類似產品如 ShardingSphere ,將其對接 Seata 的實現機制進行梳理分析,即可明確方案:對資料庫中間做改造,核心是針對物理 DataSource 做代理,而非邏輯 DataSource,原理如下圖:
4.3 小結
五、試點
5.1 訴求及顧慮
若經過宣導後,有業務團隊表示希望透過接入 Seata 來解決其業務資料一致性的問題,那麼積極配合業務團隊的開發、測試同學做評審,讓他們詳盡的表述訴求,透過溝通確認 Seata 的什麼模式適合他們的業務場景 。另外特別提醒,要收集他們的顧慮之處,通常會包含如下這些:
Seata 的事務能力能否按環境生效(開發、測試生效,留足觀察週期;生產先不生效) 新業務需求的實現依賴分散式事務,且業務邊界很清晰,能否針對特定請求生效,避免汙染原始業務,因為全面迴歸測試的成本很高 AT 模式能否支援按照業務狀態進行強制回滾 Seata 是否有執行期開關和動態降級能力 AT 模式的效能損耗是怎樣
總結來說即 Seata 是否提供了足夠全面的安全保護機制,讓新能力試點能夠滿足最小化測試的原則,並在突發情況下能夠自動降級或快速人工關閉。
5.2 梳理安全保障措施
1)Seata 事務能力能否按環境生效
Seata 有啟動開關,可在開發、測試環境開啟,生產環境關閉;如此便可有足夠的觀察期
2)能否針對特定請求生效
AT 模式是基於資料來源增強來實現的,若要避免對原始業務有干擾,可透過 DataSource 隔離的方式來實現,即:
啟用分散式事務的邏輯使用 Seata 增強的資料來源 不啟用分散式事務的邏輯,使用原始資料來源
3)AT 模式能否支援按照業務狀態進行強制回滾
方法上標註註解的方式下,當業務狀態不滿足預期需要回滾時,可透過顯示的丟擲異常來實現全域性事務回滾 顯式呼叫全域性事務 API 方式下,可根據業務狀態來決定是執行提交還是執行回滾
透過這兩種方法也都可以實現相同方法中,根據入參的屬性值來決定是否啟動分散式事務。
4) Seata 是否有執行期開關和動態降級能力
Seata 內部提供了透過配置中心控制執行時全域性事務的禁用或開啟的能力 Seata 內提供了基於滑動時間視窗和閾值判斷的動態降級管控能力 也可透過 AOP+顯式呼叫全域性事務 API 的方式,配合公司內的流控防護系統實現降級管理
5.3 AT 模式的效能損耗是怎樣
關於 AT 模式的效能損耗,個人認為這個結論的給出會是模糊、不具體的,全域性事務和分支事務的實現會有固定的 RPC 請求、SQL 查詢和記錄儲存等操作,所以關於一次分支事務的額外損耗,其計算邏輯是很清晰的。但一個完整的分散式事務的耗時,受到其分支事務的總個數影響,受每個本地事務中的資料規模和讀寫邏輯影響,也受如熱點資料的密度變化等多方面的影響。
AT 模式的效能到底該如何評判呢?我認為場景化、針對性的測試結果固然非常重要,而無微不至的可觀性支撐也非常有效。全鏈路追蹤系統 SkyWalking 為 Seata 提供了外掛,結合其 JDBC 外掛,可以看到全域性事務、每個分支事務以及全部 SQL 執行的流程和耗時詳情,如下圖所示:
分散式事務的整體效能資料是由諸多分支事務的效能累加而得;有了完整 Trace 資訊的支撐,有的放矢的最佳化有問題的環節(可能是架構設計的問題,也可能是表設計的問題,也可能是 SQL 語句的問題...),那整個事務的效能問題自然就不存在了。
AT 模式有其特定的適用場景,若業務場景不合適,也可考慮 Seata 所提供的更為靈活的 TCC 模式。當然除 Seata 提供這些模式之外,也還有其他的非同步確保型方案。是否使用分散式事務以及使用哪種分散式事務方案需因地制宜。
六、本地化建設與推進
6.1 管理端的建設
與資料庫自動化運維平臺打通
自動初始化支撐 AT 模式的表 undolog 異常記錄的檢視與管理
事務歷史記錄的留存、檢視與統計
異常事務的運維管理
當事務處理異常時主動通知相關方 提供便捷檢視異常事務相關上下文的能力 提供人工終止異常事務的能力
TC叢集適配雙活機制
6.2 業務域邊界的劃分與隔離保障
試點過程中雖然不太需要考慮這個問題,但一旦接入的應用變多以後,需要充分考慮並規劃好 TC 叢集所接入的業務域中應用的規模,以及業務域邊界的劃分和隔離管理。
6.3 推進
多跟專案團隊溝通收集需求場景(如採用分庫分表的專案可能天然缺失一致性保障),適合 AT 模式的場景可快速接入。 透過較為健壯的 TCC 模式 來替代那些歷史遺留的僅有預檢機制卻無回滾機制的事務實現。
七、總結
透過持續深入探究 Seata 的能力、做全面的相容性驗證和技術宣導,讓同事們對 Seata 有進一步的認知和信任。與專案試點同行,加快 Seata 在公司的本地化適配與能力建設,並與社群保持密切的溝通。在遵守安全合規的前提下,可積極參與社群建設,向社群同步、交流實踐歷程和效果,會得到同行者高質量的建議與指導,少走彎路。
另外編者接下來發布《 Seata 1.6.x 原始碼領讀系列》,幫助讀者老師進一步掌握 Seata ,助力產研。
八、最後說一句
我是石頁兄,如果這篇文章對您有幫助,或者有所啟發的話,歡迎關注筆者的微信公眾號【架構染色】進行交流和學習,您的支援是我堅持寫作最大的動力。
另外技術群中也有許多熱心的大佬交流、互助;可透過點選【架構染色】公眾號主頁右下角【交流探討】獲得筆者微信二維碼,加微時備註“加群”即可,期待並歡迎您的加入。
參考並感謝
Seata 新特性,APM 支援 SkyWalking
分散式事務--TCC 的中介軟體--選型/對比
分散式事務 Seata 及其三種模式詳解 | Meetup#3 回顧
透過 AOP 動態建立/關閉 Seata 分散式事務
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70024420/viewspace-2934969/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- seata 分散式事務分散式
- 分散式事務之Seata的AT模型分散式模型
- 分散式事務 —— SpringCloud Alibaba Seata分散式SpringGCCloud
- 分散式事務中介軟體Seata的設計原理分散式
- 分散式事務~從seata例項來學習分散式事務分散式
- 微服務分散式事務元件 Seata(一)微服務分散式元件
- DBPack 賦能 python 微服務協調分散式事務Python微服務分散式
- SpringCloud系列之整合分散式事務Seata應用篇SpringGCCloud分散式
- 分散式事務 SEATA-1.4.1 AT模式 配合NACOS 應用分散式模式
- seata分散式事務AT模式介紹(二)分散式模式
- 分散式事務(七)之Seata簡介分散式
- SpringCloud Alibaba Seata處理分散式事務SpringGCCloud分散式
- SpringCloud Alibaba(六) - Seata 分散式事務鎖SpringGCCloud分散式
- Seata搭建與分散式事務入門分散式
- 工業網際網路賦能經濟發展提質增效VQE
- 工業網際網路賦能經濟發展提質增效WM
- 微服務痛點-基於Dubbo + Seata的分散式事務(AT)模式微服務分散式模式
- Seata 分散式事務框架 TCC 模式原始碼分析分散式框架模式原始碼
- Seata分散式事務TA模式原始碼解讀分散式模式原始碼
- Spring Cloud Alibaba 使用Seata解決分散式事務SpringCloud分散式
- 分散式事務與Seate框架(2)——Seata實踐分散式框架
- Seata 無侵入式分散式事務服務的實現基石-JDBC篇分散式JDBC
- 基於Seata探尋分散式事務的實現方案分散式
- 微服務痛點-基於Dubbo + Seata的分散式事務(TCC模式)微服務分散式模式
- Spring Boot 整合 Seata 解決分散式事務問題Spring Boot分散式
- ShardingSphere如何輕鬆駕馭Seata柔性分散式事務?分散式
- 微服務分散式事務解決方案-開源軟體seata微服務分散式
- 微服務架構 | 11.1 整合 Seata AT 模式實現分散式事務微服務架構模式分散式
- 分散式事務與Seate框架(3)——Seata的AT模式實現原理分散式框架模式
- 分散式事務(一)—分散式事務的概念分散式
- Spring Cloud Seata系列:基於AT模式實現分散式事務SpringCloud模式分散式
- 分散式事務框架 seata-golang 通訊模型詳解分散式框架Golang模型
- 深度剖析一站式分散式事務方案Seata(Fescar)-Server分散式Server
- 深度剖析一站式分散式事務方案 Seata(Fescar)-Server分散式Server
- 深度剖析一站式分散式事務方案Seata-Cient分散式
- 更開放的分散式事務 | 螞蟻金服共建 Seata 社群分散式
- 分散式事務 Seata TCC 模式深度解析 | SOFAChannel#4 直播整理分散式模式
- seata分散式事務TCC模式介紹及推薦實踐分散式模式