剛柔並濟的開源分佈式事務解決方案

做者

張亮,京東數科數據研發負責人,Apache ShardingSphere發起人 & PPMCjava

熱愛開源,目前主導開源項目ShardingSphere(原名Sharding-JDBC)和Elastic-Job。擅長以java爲主分佈式架構以及以Kubernetes和Mesos爲主的雲平臺方向,推崇優雅代碼,對如何寫出具備展示力的代碼有較多研究。git

目前主要精力投入在將ShardingSphere打造爲業界一流的金融級數據解決方案之上。ShardingSphere已經進入Apache孵化器,是京東集團首個進入Apache基金會的開源項目,也是Apache基金會首個分佈式數據庫中間件。github


姜寧,華爲開源能力中心技術專家,Apache ServiceComb項目負責人。前紅帽軟件首席軟件工程師,在企業級開源中間件開發方面有十餘年經驗,有豐富的Java開發和使用經驗,函數式編程愛好者。從2006年開始一直從事Apache開源中間件項目的開發工做,前後參與Apache CXF,Apache Camel,以及Apache ServiceMix的開發。對微服務架構,WebServices,Enterprise Integration Pattern,SOA, OSGi 均有比較深刻的研究。sql

博客地址:https://willemjiang.github.io/數據庫


馮徵,紅帽軟件工程師。2009年加入紅帽軟件公司,主要從事事務管理器方面的工做,作爲核心開發人員參與了Narayan和Blacktie項目,在與多個應用服務器(Wildfly, Karaf, Tomcat)和框架(Common DBCP, Spring Boot)的事務處理集成方面有過貢獻。從2017年開始參與了Apache ServiceComb項目,目前是PMC成員之一。對於分佈式事務處理以及微服務環境中的事務處理,有過深刻的研究。apache

導讀

相比於數據分片方案的逐漸成熟,集性能、透明化、自動化、強一致、並能適用於各類應用場景於一體的分佈式事務解決方案則顯得百裏挑一。基於兩(三)階段提交的分佈式事務的性能瓶頸以及柔性事務的業務改造問題,使得分佈式事務至今依然是令架構師們頭疼的問題。編程

Apache ShardingSphere(Incubating)不失時機的在2019年初,提供了一個剛柔並濟的一體化分佈式事務解決方案。若是您的應用系統正在受到這方面的困擾,不妨倒上一杯咖啡,花十分鐘閱讀此文,說不定會有些收穫呢?後端

背景

數據庫事務須要知足ACID(原子性、一致性、隔離性、持久性)4個特性。api

  • 原子性(Atomicity)指事務做爲總體來執行,要麼所有執行,要麼全不執行。
  • 一致性(Consistency)指事務應確保數據從一個一致的狀態轉變爲另外一個一致的狀態。
  • 隔離性(Isolation)指多個事務併發執行時,一個事務的執行不該影響其餘事務的執行。
  • 持久性(Durability)指已提交的事務修改數據會被持久保存。

在單一數據節點中,事務僅限於對單一數據庫資源的訪問控制,稱之爲本地事務。幾乎全部的成熟的關係型數據庫都提供了對本地事務的原生支持。 可是在基於微服務的分佈式應用環境下,愈來愈多的應用場景要求對多個服務的訪問及其相對應的多個數據庫資源能歸入到同一個事務當中,分佈式事務應運而生。服務器

關係型數據庫雖然對本地事務提供了完美的ACID原生支持。 但在分佈式的場景下,它卻成爲系統性能的桎梏。如何讓數據庫在分佈式場景下知足ACID的特性或找尋相應的替代方案,是分佈式事務的重點工做。

本地事務

在不開啓任何分佈式事務管理器的前提下,讓每一個數據節點各自管理本身的事務。 它們之間沒有協調以及通訊的能力,也並不互相知曉其餘數據節點事務的成功與否。 本地事務在性能方面無任何損耗,但在強一致性以及最終一致性方面則力不從心。

兩階段提交

XA協議最先的分佈式事務模型是由X/Open國際聯盟提出的X/Open Distributed Transaction Processing(DTP)模型,簡稱XA協議。

基於XA協議實現的分佈式事務對業務侵入很小。 它最大的優點就是對使用方透明,用戶能夠像使用本地事務同樣使用基於XA協議的分佈式事務。 XA協議可以嚴格保障事務ACID特性。

嚴格保障事務ACID特性是一把雙刃劍。 事務執行在過程當中須要將所需資源所有鎖定,它更加適用於執行時間肯定的短事務。 對於長事務來講,整個事務進行期間對數據的獨佔,將致使對熱點數據依賴的業務系統併發性能衰退明顯。 所以,在高併發的性能至上場景中,基於XA協議兩階段提交類型的分佈式事務並非最佳選擇。

柔性事務

若是將實現了ACID的事務要素的事務稱爲剛性事務的話,那麼基於BASE事務要素的事務則稱爲柔性事務。 BASE是基本可用、柔性狀態和最終一致性這3個要素的縮寫。

  • 基本可用(Basically Available)保證分佈式事務參與方不必定同時在線。
  • 柔性狀態(Soft state)則容許系統狀態更新有必定的延時,這個延時對客戶來講不必定可以察覺。
  • 最終一致性(Eventually consistent)一般是經過消息傳遞的方式保證系統的最終一致性。

在ACID事務中對一致性和隔離性的要求很高,在事務執行過程當中,必須將全部的資源佔用。 柔性事務的理念則是經過業務邏輯將互斥鎖操做從資源層面上移至業務層面。經過放寬對強一致性和隔離性的要求,只要求當整個事務最終結束的時候,數據是一致的。而在事務執行期間,任何讀取操做獲得的數據都有可能被改變。這種弱一致性的設計能夠用來換取系統吞吐量的提高。

Saga是典型的柔性事務管理器。Sagas這個概念來源於三十多年前的一篇數據庫論文[http://www.cs.cornell.edu/and...] ,一個Saga事務是一個有多個短時事務組成的長時的事務。 在分佈式事務場景下,咱們把一個Saga分佈式事務看作是一個由多個本地事務組成的事務,每一個本地事務都有一個與之對應的補償事務。在Saga事務的執行過程當中,若是某一步執行出現異常,Saga事務會被終止,同時會調用對應的補償事務完成相關的恢復操做,這樣保證Saga相關的本地事務要麼都是執行成功,要麼經過補償恢復成爲事務執行以前的狀態。

TCC(Try-Cancel/Confirm實現)是另外一種柔性事務的協調實現。TCC藉助兩階段提交協議提供了一種比較完美的恢復方式。在TCC方式下,cancel補償顯然是在第二階段須要執行業務邏輯來取消第一階段產生的後果。Try是在第一階段執行相關的業務操做,完成相關業務資源的佔用,例如預先分配票務資源,或者檢查並刷新用戶帳戶信用額度。 在取消階段釋放相關的業務資源,例如釋放預先分配的票務資源或者恢復以前佔用的用戶信用額度。 那咱們爲何還要加入確認操做呢?這須要從業務資源的使用生命週期來入手。在try過程當中,咱們只是佔用的業務資源,相關的執行操做只是出於待定狀態,只有在確認操做執行完畢以後,業務資源才能真正被確認。

基於ACID的強一致性事務和基於BASE的最終一致性事務都不是銀彈,只有在最適合的場景中才能發揮它們的最大長處。可經過下表詳細對比它們之間的區別,以幫助開發者進行技術選型。

挑戰

因爲應用的場景不一樣,須要開發者可以合理的在性能與功能之間權衡各類分佈式事務。

兩階段提交與柔性事務的API和功能並不徹底相同,在它們之間並不能作到自由的透明切換。在開發決策階段,就不得不在兩階段提交的事務和柔性事務之間抉擇,使得設計和開發成本被大幅增長。

基於XA的兩階段提交事務使用相對簡單,可是沒法很好的應對互聯網的高併發或複雜系統的長事務場景;柔性事務則須要開發者對應用進行改造,接入成本很是高,而且須要開發者自行實現資源佔用和反向補償。

ShardingSphere的分佈式事務

整合現有的成熟事務方案,爲本地事務、兩階段提交和柔性事務提供統一的分佈式事務接口,並彌補當前方案的不足,提供一站式的分佈式事務解決方案是Apache ShardingSphere(Incubating)分佈式事務模塊的主要設計目標。該模塊的名稱是sharding-transaction。能夠用剛柔並濟、自動化和透明化這3個關鍵詞來歸納sharding-transaction模塊的設計理念和功能呈現。

1.剛柔並濟

同時提供基於XA的兩階段提交事務與基於Saga的柔性事務解決方案,而且可以一塊兒配合使用。

2.自動化

XA事務和Saga事務都經過自動化的方式完成,使用方無感知。XA事務無需使用XADataSource接口以及JTA事務管理器;Saga事務也無需用戶自行實現補償接口。

3.透明化

在Apache ShardingSphere(Incubating)的兩個接入端——Sharding-JDBC和Sharding-Proxy中,分別提供了面向本地事務接口的封裝。使用方徹底能夠將被ShardingSphere管理的水平分片的多個數據源當成一個數據庫使用,經過本地事務API便可實現徹底的分佈式事務的能力。用戶能夠透明地在應用中任意切換事務類型。

sharding-transaction模塊由sharding-transaction-core,sharding-transaction-2pc和sharding-transaction-base這3個子模塊組成。

  • sharding-transaction-core:

提供了面向使用者的API與面向開發者的SPI。

  • sharding-transaction-2pc:

兩階段提交事務父模塊。目前只有sharding-transaction-xa模塊,提供了XA協議的支持。將來會引入更多的基於兩階段提交的事務類型,如:percolator,參見:

[https://storage.googleapis.co...]。

  • sharding-transaction-base:

柔性事務父模塊。目前只有sharding-transaction-saga模塊,採用Apache ServiceComb Saga Actuator提供的Saga執行器提供柔性事務支持,並在其基礎之上提供了反向SQL和快照的能力,並由此實現自動逆向補償功能。

下面將對ShardingSphere的XA和Saga事務模塊的功能亮點進行說明。

XA事務——三大XA事務管理器共護航

成熟的XA事務管理器很是多,Apache ShardingSphere(Incubating)並未選擇從新造輪子,而是寄望於打造一個生態,將合適的輪子有機地整合在一塊兒,提供成熟穩定的分佈式事務處理能力。它的主要功能以下:

1.複用成熟引擎,自動切換底層實現

Sharding-transaction-xa模塊進一步定義了面向XA事務管理器開發者的SPI,開發者僅需實現SPI定義的接口,便可自動加入至Apache ShardingSphere(Incubating)生態,做爲其XA事務管理器。

Apache ShardingSphere(Incubating)官方目前實現了基於Atomikos和Bitronix的SPI,而且邀請了Radhat JBoss的XA事務引擎Narayana [https://github.com/jbosstm/na...] 開發團隊實現了JBoss的SPI。用戶能夠自行的在Atomikos,Bitronix和Narayana間選擇本身喜歡的XA事務管理器。

受限於Apache基金會項目License的緣由,Apache ShardingSphere(Incubating)將採用Apache協議的Atomikos做爲其默認實現,關於基於LGPL協議的Bitronix和基於LGPL協議的Narayana,用戶能夠自行引用相應jar包至項目的classpath便可。

若是這3個XA事務管理器仍未知足用戶需求,開發者則可經過擴展SPI來實現定製化的XA事務管理器。

2.數據源透明化自動接入

Apache ShardingSphere(Incubating)可以自動將XADataSource做爲數據庫驅動的數據源接入XA事務管理器。而針對於使用DataSource做爲數據庫驅動的應用,用戶也無需改變其編碼以及配置,Apache ShardingSphere(Incubating)經過自動適配的方式,在中間件內部將其轉化爲支持XA協議的XADataSource和XAConnection,並將其做爲XA資源註冊到底層的XA事務管理器中。

XA模塊的架構圖以下:

Saga事務—跨越柔性事務限制,實現自動補償

在柔性事務中,每一次對數據庫的更新操做都將數據真正的提交至數據庫,以達到高併發系統中最佳資源釋放的效果。當數據出現問題須要回滾時,經過柔性事務管理器保持數據的最終一致性以及隔離行爲。Apache ShardingSphere(Incubating)採用Apache ServiceComb Saga Actuator [https://github.com/apache/ser...] 做爲Saga事務管理器,它的主要功能以下:

  1. 自動反向補償

Saga定義了一個事務中的每一個子事務都有一個與之對應的反向補償操做。由Saga事務管理器根據程序執行結果生成一張有向無環圖,並在須要執行回滾操做時,根據該圖依次按照相反的順序調用反向補償操做。Saga事務管理器只用於控制什麼時候重試,合適補償,並不負責補償的內容,補償的具體操做須要由開發者自行提供。

另外一個柔性事務管理器TCC與Saga理念類似,均須要由使用方開發者提供補償操做。除了補償,TCC還提供了資源佔用的能力,但也須要由使用方開發者提供資源佔用操做。雖然功能上強於Saga,但TCC的使用成本較之Saga也更高。

由使用方開發者提供資源佔用和補償操做,這就使得柔性事務的解決方案始終難於大規模的在業務系統中落地。而且因爲業務系統的介入,使得柔性事務框架的使用範疇始終定位於服務而非數據庫,數據庫可以直接使用的成熟的柔性事務管理器目前還很少見。

Apache ShardingSphere(Incubating)採用反向SQL技術,將對數據庫進行更新操做的SQL自動生成數據快照以及反向SQL,並交由Apache ServiceComb Saga Actuator執行,使用方則無需再關注如何實現補償方法,將柔性事務管理器的應用範疇成功的定位回了事務的本源——數據庫層面。

對於可以處理複雜查詢語句的Apache ShardingSphere(Incubating)SQL解析引擎來講,插入/更新/刪除等語句解析難度則要小不少;ShardingSphere是經過攔截用戶執行的SQL進行數據分片的,全部的SQL都可以被其直接管控。所以將反向SQL和補償能力與Apache ServiceComb Saga Actuator相結合,達到了自動化柔性事務的能力,是數據分片和柔性事務結合的典範。

Saga模塊的架構圖以下:

接入端—面向原生事務接口的分佈式事務

Apache ShardingSphere(Incubating)的目標是像使用一個數據庫同樣使用分片後的多數據庫,在事務模塊,這個目標依然適用。不管被ShardingSphere所管理的數據庫如何分片,面向開發者的邏輯數據庫始終只有一個。所以,ShardingSphere的事務接口依然是原生的本地事務接口,即JDBC的java.sql.Connection的setAutoCommit, commit和rollback方法;以及面向數據庫事務管理器的begin, commit和rollback語句。在用戶調用原生本地事務接口的同時,ShardingSphere則經過sharding-transaction模塊保證後端分片數據庫的分佈式事務。

因爲原生的事務接口並不支持事務類型,所以ShardingSphere提供了3種方式供使用者切換事務類型。

1.經過SCTL(sharding-ctl,即ShardingSphere提供的數據庫管理命令)切換當前事務類型。以SQL執行的方式輸入便可,適用於Sharding-JDBC和Sharding-Proxy。例如:SCTL:SET TRANSACTION_TYPE=BASE

2.經過Threadlocal切換當前事務類型,適用於Sharding-JDBC。例如:TransactionTypeHolder.set (TransactionType.XA)

3.經過元註解,並與Spring配合使用切換當前事務類型,適用於Sharding-JDBC和Sharding-Proxy。例如:@ShardingTransactionType (TransactionType.BASE)

線路規劃

分佈式事務模塊在github的開發分支 [https://github.com/apache/inc...] 已經基本可用,將隨着4.0.0.M1的版本發佈,這也將是ShardingSphere進入Apache基金會孵化器以後的第一個發佈版本。分佈式事務是數據分片以及微服務架構的重要組成部分,也是Apache ShardingSphere(Incubating)的關注重心,發佈以後仍將繼續完善,線路規劃以下。

事務隔離引擎

在SQL反向引擎穩定以後,柔性事務的重點將放在打造事務隔離之上。因爲事務的隔離性並不是Saga所規劃的範疇,所以Apache ShardingSphere(Incubating)會在Saga以外將其完善,與SQL反向引擎一塊兒做爲整個柔性事務的組成部分。

Apache ShardingSphere(Incubating)將經過樂觀鎖、悲觀鎖、無隔離等幾種策略,作到讀已提交、讀未提交、可重複讀以及序列化等隔離級別的一一支持。並經過多版本快照進一步提高系統的併發度。

對外XA事務接口

Apache ShardingSphere(Incubating)的兩個接入端Sharding-JDBC和Sharding-Proxy在支持自身的內部事務問題以後,將提供融入與其餘數據源一塊兒做爲被JTA等分佈式事務管理器管理的能力。

實現對外XA事務接口以後,Sharding-JDBC的DataSource將實現XADataSource接口,提供與其餘數據源共同加入到一個XA事務的可能;Sharding-Proxy的數據庫協議也將實現基於XA的兩階段提交協議;使其能夠成爲被XA所加載的資源管理器。

除此以外,ShardingSphere還會實現XA協議的recovery部分,即在事務處理器出現崩潰的狀況時,能夠有能力提供in-doubt transactions來實現事務恢復。

總結

Apache ShardingSphere(Incubating)提供的分佈式事務能力能夠經過下表總結一下,讀者不妨與文章開始時的表格對比一下,看看ShardingSphere的分佈式事務模塊所帶來的變化。

在高速發展的Apache ShardingSphere(Incubating)中,分佈式事務的雛形已成,咱們會盡快將其打造爲可用的產品,並持續爲社區提供優質解決方案。對於一篇不算短的文章,閱讀完此文的您,相信必定對這個領域有必定興趣。不妨先嚐試一下,是否知足您的預期?或者乾脆加入咱們的社區,一塊兒打造更完善的分佈式事務方案。

相關文章
相關標籤/搜索