如何實現微服務架構下的分布式事務?


摘要:微服務架構下,如何克服分布式事務難題?

什么是微服務?微服務有什么優勢和困難?

什么是微服務架構?

簡而言之,微服務架構的系統是一個分布式的系統,按業務進行划分為獨立的服務單元,解決單體系統的不足,同時也滿足越來越復雜的業務需求。每個微服務僅關注於完成一件任務並很好地完成該任務。

微服務架構的優勢

1. 將復雜的業務拆分成多個小的業務,每個業務拆分成一個服務,將復雜的問題簡單化。利於分工,降低新人的學習成本。

2. 微服務系統是分布式系統,業務與業務之間完全解耦,隨着業務的增加可以根據業務再拆分,具有極強的橫向擴展能力。

3. 服務間采用 HTTP 協議通信,服務與服務之間完全獨立。每個服務可以根據業務場景選取合適的編程語言和數據庫。

4. 服務獨立部署,每個服務的修改和部署對其他服務沒有影響。

雖然微服務有以上的優勢,但是微服務實踐仍處於探索階段,很多中小型互聯網公司,鑒於經驗、技術實力等問題,微服務落地比較困難。著名架構師Chris Richardson指出,目前微服務主要存如下幾方面困難:

1. 單體應用拆分為分布式系統后,進程間的通訊機制和故障處理措施變的更加復雜。

2. 系統微服務化后,一個看似簡單的功能,內部可能需要調用多個服務並操作多個數據庫實現,服務調用的分布式事務問題變的非常突出。

3. 微服務數量眾多,其測試、部署、監控等都變的更加困難。

隨着RPC框架的成熟,第一個問題已經逐漸得到解決。例如Dubbo可以支持多種通訊協議,Spring Cloud可以非常好的支持restful調用。對於第三個問題,隨着Docker、DevOps技術的發展以及各公有雲PaaS平台自動化運維工具的推出,微服務的測試、部署與運維會變得越來越容易。

而對於第二個問題,現在還沒有通用方案很好的解決微服務產生的事務問題。分布式事務已經成為微服務落地最大的阻礙,也是最具挑戰性的一個技術難題。下面將深入和大家探討微服務架構下,分布式事務的各種解決方案。

微服務架構下,如何克服分布式事務難題?

什么是事務

事務是由一組SQL語句組成的邏輯處理單元,事務具有以下4個屬性,通常簡稱為事務的ACID屬性:

原子性(Atomicity):事務是一個原子操作單元,其對數據的修改,要么全都執行,要么全都不執行。

一致性(Consistent):在事務開始和完成時,數據都必須保持一致狀態。這意味着所有相關的數據規則都必須應用於事務的修改,以保持數據的完整性。

隔離性(Isolation):數據庫系統提供一定的隔離機制,保證事務在不受外部並發操作影響的“獨立”環境執行。數據庫事務隔離級別由低到高依次為Read uncommitted、Read committed、Repeatable 、Serializable。

持久性(Durability):事務完成之后,它對於數據的修改是永久性的,即使出現系統故障也能夠保持。

分布式事務典型場景:

銀行轉賬業務是一個典型分布式事務場景,通常包括以下三種情況:

A. 支行內轉賬:同一銀行的相同支行內轉賬

B. 行內轉賬:同一銀行的不同支行間轉賬

C. 跨行轉賬:不同銀行的系統進行轉賬

對於傳統集中式架構,A、B通常為本地事務,C為分布式事務。業務微服務改造后,轉入、轉出通常為不同的微服務,同一個微服務也通常運行於不同實例中。A可能變成一個分布式事務,也可能通過一些方法規避,在本地事務內完成。B和C很難規避,只能是分布式事務。

微服務最佳實踐建議盡量規避分布式事務,但是在很多業務場景(比如上面的B、C轉賬場景),分布式事務是一個繞不開的技術問題。

分布式事務常用解決方案

為了解決分布式系統一致性問題,前人在性能和數據一致性的反反復復權衡過程中總結了許多典型的協議和算法。其中,最常用的是兩階提交協議(2 Phase Commitment Protocol)。

兩階段提交方案

交易中間件與數據庫通過 XA 接口規范,使用兩階段提交來完成一個全局事務, XA 規范的基礎是兩階段提交協議。

第一階段是表決階段,所有參與者都將本事務能否成功的信息反饋發給協調者;第二階段是執行階段,協調者根據所有參與者的反饋,通知所有參與者,步調一致地在所有分支上提交或者回滾。

兩階段提交方案應用非常廣泛,典型商用軟件包括Oracle Tuxedo和IBM CICS。它的優點是對業務代碼侵入較低,但缺點也很明顯:

性能低下:由於 XA 協議自身的特點,它會造成事務資源長時間得不到釋放,鎖定周期長,而且在應用層上面無法干預,數據並發沖突高的場景性能很差。

單點問題:協調者在整個兩階段提交過程中扮演着舉足輕重的作用,一旦協調者所在服務器宕機,就會影響整個數據庫集群的正常運行。比如在第二階段中,如果協調者因為故障不能正常發送事務提交或回滾通知,那么參與者們將一直處於阻塞狀態。

同步阻塞:兩階段提交執行過程中,所有的參與者都需要聽從協調者的統一調度,期間處於阻塞狀態而不能從事其他操作,效率及其低下。

因此,兩階段提交方案在互聯網業務中很少使用,無法滿足高並發需求。

為了這個彌補這種方案帶來性能低的問題,大家又想出了很多種方案來解決,通過在應用層做文章,即入侵業務的方式,比較典型的是TCC 方案和基於可靠消息的最終一致性方案。

TCC事務方案

TCC事務模型在電商、金融領域落地較多。TCC方案其實是兩階段提交的一種改進。其將整個業務邏輯的每個分支顯式的分成了Try、Confirm、Cancel三個操作。Try部分完成業務的准備工作,confirm部分完成業務的提交,cancel部分完成事務的回滾。基本原理如下圖所示。

事務開始時,業務應用會向事務協調器注冊啟動事務。之后業務應用會調用所有服務的try接口,完成一階段准備。之后事務協調器會根據try接口返回情況,決定調用confirm接口或者cancel接口。如果接口調用失敗,會進行重試。

TCC方案讓應用自己定義數據庫操作的粒度,使得降低鎖沖突、提高吞吐量成為可能,比如華為分布式事務中間件DTM性能極高,普通配置服務器可以支持全局事務1萬+ TPS,分支事務3萬+ TPS。 當然TCC方案也有不足之處,集中表現在以下兩個方面:

業務侵入性強。業務邏輯的每個分支都需要實現try、confirm、cancel三個操作,應用侵入性較強,改造成本高。

實現難度較大。為了滿足一致性的要求,要充分考慮冪等操作,允許重復執行,也要防止資源懸掛,做好並發訪問控制和數據可見性控制等。

上述原因導致TCC方案大多被研發實力較強、有迫切需求的大公司所采用。微服務倡導服務的輕量化,而TCC方案中很多事務的處理邏輯需要應用自己編碼實現,復雜且開發量大。

基於消息的最終一致性方案

消息一致性方案是通過消息中間件保證上下游應用數據操作的一致性。基本思路是將本地操作和發送消息放在一個本地事務中,保證本地操作和消息發送要么兩者都成功或者都失敗。下游應用向消息系統訂閱該消息,收到消息后執行相應操作。

消息最終一致方案從本質上講是將分布式事務轉換為兩個本地事務,然后依靠下游業務的重試機制達到最終一致性。基於消息的最終一致性方案對應用侵入性也很高,應用需要進行大量業務改造,成本非常高。

入侵代碼的方案是基於現有情形“迫不得已”才推出的解決方案,實際上它們實現起來非常不優雅,比如TCC,一個事務的調用通常伴隨而來的是對該事務接口增加一系列的反向操作,提交邏輯必然伴隨着回滾的邏輯,這樣的代碼會使得項目非常臃腫,維護成本高。

針對上面所說的分布式事務解決方案的痛點,很顯然,我們理想的分布式事務解決方案肯定是性能要好而且要對業務無侵入,業務層無需關心分布式事務機制的約束,做到事務與業務分離,也就是本文所重點推薦的非侵入事務。

非侵入事務方案

a. 典型架構

非侵入事務典型架構如下圖所示:

事務核心組件包括:

Transaction Coordinator (TC): 事務協調器,分布式事務大腦,產生和維護全局事務、分支事務,推進事務提交與回滾的二階段處理。TC Server以集群形式提供事務協調能力。

Transaction Manager (TM): 定義全局事務的邊界,與事務協調器通信以開啟、提交或回滾全局事務。

Resource Manager (RM): 資源管理器,管理分支事務處理的資源,與事務協調器通信以開啟、結束事務分支,並接收事務協調器指令完成二階段分支事務提交或回滾。

Lock Server (LS): 分布式鎖服務器,可以通過它對進行中的分布式事務所操作的資源查詢、加鎖、放鎖。

一個分布式事務稱為一個全局事務,下面掛若干個分支事務,一個分支事務是一個滿足 ACID 的本地事務。非侵入事務的核心思想是資源管理器攔截業務SQL,對其解析並做額外的一些數據處理,產生undo log並保存,一旦發生全局事務回滾,通過各個分支事務對應的undo log完成所有分支事務回滾。

大家很容易想到,兩個全局事務並行修改了相同數據,可能會造成根據undo log完成回滾產生數據錯誤。解決的方法是通過Lock Server對事務所修改數據加鎖,全局事務提交后立即放鎖,全局事務回滾則等待分支事務回滾完成放鎖。

b. 典型流程

典型分布式事務主要執行步驟如下:

1.TM請求TC開始新的全局事務,TC創建全局事務並返回全局事務ID(XID)。

2.根據XID構建事務上下文,通過微服務的調用鏈傳播。

3.RM發現自己處於事務上下文,得到全局事務ID並解析SQL,產生undo log和分布式事務鎖數據,請求TC創建分支事務。

4.TC 通過LS加鎖,加鎖成功后創建分支事務ID並返回。

5.RM 把分支事務ID與undo log關聯,與業務原始SQL在一個本地事務內提交。

6.重復3~5,為全局事務范圍內的每個本地事務創建一個分支事務。

7.如果全局事務邊界內沒有任何異常,則TM請求TC提交全局事務;如果有異常,則TM請求TC回滾全局事務。

8. TC標記全局事務狀態,如果為提交則立即通過LS放鎖。推進XID所對應全局事務下的所有分支事務進行二階段處理,發送請求到RM。

9.RM完成分支事務的提交或回滾,並返回狀態到TC。

10.TC對完成回滾的分支通過LS放鎖。所有分支完成后,返回全局事務處理結果到TM。

二階段事務處理比較關鍵,在此重點說明一下。

c. 分支事務提交

如果全局事務狀態為提交,則對每個分支發起分支提交,流程如下圖所示:

RM收到分支事務提交請求,先保存分支事務的ID在隊列中並返回。一個線程定時從隊列中取出一批分支事務ID,構建SQL批量刪除所對應的undo log日志。分支事務提交可以異步批量處理,是因為全局事務已經提交,undo log作為中間狀態已經不再重要,只要定期清理即可。

d. 分支事務回滾

如果全局事務狀態為回滾或超時,則對每個分支發起分支回滾,流程如下圖所示:

RM收到分支事務回滾請求,開啟一個本地事務,通過分支ID找到對應的undo log,構建回滾SQL語句並執行,刪除undo log,然后提交本地事務。如果順利完成,TC收到響應后通過LS清理該分支所占用資源。

e. 性能分析

非侵入事務相比XA兩階段提交一個重要性能優勢在於鎖定資源時間更短。實際業務中,我們知道絕大多數事務狀態為提交,很少比例為回滾。對於XA來說,無論是提交還是回滾,資源都是在二階段釋放。對本文所介紹的非侵入事務來說,提交狀態的全局事務,二階段沒有必要拿鎖,只有少比例的回滾狀態的全局事務,才需要在二階段放鎖。

非侵入事務不受限於數據庫XA接口,實現完全可控。TC、RM、LS這些關鍵組件對性能影響很大,良好的設計、實現可以取得非常高的性能。非侵入式事務實踐證明,它可以輕松滿足絕大多數高並發業務場景的性能需求。

典型核心業務系統分布式事務改造實例

華為雲Stack為某運營商核心業務系統分布式事務改造,該客戶業務在月初充值、扣費業務高峰期等常見的並發場景時,對分布式系統提出挑戰:

  • 高並發的分布式事務訪問賬戶表,XA兩階段提交由於加鎖時間長,嚴重影響業務。整體性能要求達1000+ TPS,傳統或開源分布式事務難以滿足高可用性與高性能要求。
  • XA事務與其他數據庫操作的一致性問題。需要把XA事務作為DTM TCC事務的一個分支,將別的數據庫操作是另外的分支。

華為雲Stack混合雲解決方案分布式事務中間件DTM通過一系列創新技術,提供高性能、高可用、高可靠、高安全、低侵入、易使用的分布式事務服務,支持TCC事務和非侵入事務兩種模型,助力企業微服務化改造,優雅地解決分布式系統下數據一致性難題。

 

點擊關注,第一時間了解華為雲新鮮技術~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM