刚柔并济的开源分布式事务解决方案
導讀
相比于數據分片方案的逐漸成熟,集性能、透明化、自動化、強一致、并能適用于各種應用場景于一體的分布式事務解決方案則顯得鳳毛麟角?;趦?#xff08;三)階段提交的分布式事務的性能瓶頸以及柔性事務的業務改造問題,使得分布式事務至今依然是令架構師們頭疼的問題。
Apache ShardingSphere(Incubating)不失時機的在2019年初,提供了一個剛柔并濟的一體化分布式事務解決方案。如果您的應用系統正在受到這方面的困擾,不妨倒上一杯咖啡,花十分鐘閱讀此文,說不定會有些收獲呢?
?
背景
數據庫事務需要滿足ACID(原子性、一致性、隔離性、持久性)4個特性。
-
原子性(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/andru/cs711/2002fa/reading/sagas.pdf] ,一個Saga事務是一個有多個短時事務組成的長時的事務。 在分布式事務場景下,我們把一個Saga分布式事務看做是一個由多個本地事務組成的事務,每個本地事務都有一個與之對應的補償事務。在Saga事務的執行過程中,如果某一步執行出現異常,Saga事務會被終止,同時會調用對應的補償事務完成相關的恢復操作,這樣保證Saga相關的本地事務要么都是執行成功,要么通過補償恢復成為事務執行之前的狀態。
TCC(Try-Cancel/Confirm實現)是另一種柔性事務的協調實現。TCC借助兩階段提交協議提供了一種比較完美的恢復方式。在TCC方式下,cancel補償顯然是在第二階段需要執行業務邏輯來取消第一階段產生的后果。Try是在第一階段執行相關的業務操作,完成相關業務資源的占用,例如預先分配票務資源,或者檢查并刷新用戶賬戶信用額度。 在取消階段釋放相關的業務資源,例如釋放預先分配的票務資源或者恢復之前占用的用戶信用額度。 那我們為什么還要加入確認操作呢?這需要從業務資源的使用生命周期來入手。在try過程中,我們只是占用的業務資源,相關的執行操作只是出于待定狀態,只有在確認操作執行完畢之后,業務資源才能真正被確認。
基于ACID的強一致性事務和基于BASE的最終一致性事務都不是銀彈,只有在最適合的場景中才能發揮它們的最大長處。可通過下表詳細對比它們之間的區別,以幫助開發者進行技術選型。
| ? | 本地事務 | 兩階段提交 | 柔性事務 |
| 業務改造 | 無 | 無 | 實現相關接口 |
| 一致性 | 不支持 | 支持 | 最終一致 |
| 隔離性 | 不支持 | 支持 | 業務方保證 |
| 并發性能 | 無影響 | 嚴重衰退 | 略微衰退 |
| 適合場景 | 業務方處理不一致 | 短事務 & 低并發 | 長事務 & 高并發 |
?
★挑戰★
由于應用的場景不同,需要開發者能夠合理的在性能與功能之間權衡各種分布式事務。
兩階段提交與柔性事務的API和功能并不完全相同,在它們之間并不能做到自由的透明切換。在開發決策階段,就不得不在兩階段提交的事務和柔性事務之間抉擇,使得設計和開發成本被大幅增加。
基于XA的兩階段提交事務使用相對簡單,但是無法很好的應對互聯網的高并發或復雜系統的長事務場景;柔性事務則需要開發者對應用進行改造,接入成本非常高,并且需要開發者自行實現資源占用和反向補償。
?
ShardingSphere的分布式事務
整合現有的成熟事務方案,為本地事務、兩階段提交和柔性事務提供統一的分布式事務接口,并彌補當前方案的不足,提供一站式的分布式事務解決方案是Apache ShardingSphere(Incubating)分布式事務模塊的主要設計目標。該模塊的名稱是sharding-transaction??梢杂?strong>剛柔并濟、自動化和透明化這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.com/pub-tools-public-publication-data/pdf/36726.pdf]。
-
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/narayana] 開發團隊實現了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/servicecomb-saga-actuator] 作為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/incubator-shardingsphere] 已經基本可用,將隨著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)中,分布式事務的雛形已成,我們會盡快將其打造為可用的產品,并持續為社區提供優質解決方案。對于一篇不算短的文章,閱讀完此文的您,相信一定對這個領域有一定興趣。不妨先嘗試一下,是否滿足您的預期?或者干脆加入我們的社區,一起打造更完善的分布式事務方案。?
?
END
Apache ShardingSphere(Incubating)自2016開源以來,不斷精進、不斷發展,被越來越多的企業和個人認可:Github上收獲6000+的stars,70+公司企業的成功案例。此外,越來越多的企業和個人也加入到Apache ShardingSphere(Incubating)的開源項目中,為它的成長和發展貢獻了巨大力量。
我們從未停息過腳步,聆聽社區伙伴的需求和建議,不斷開發新的、強大的功能,不斷使其健壯可靠!
開源不易, 我們卻愿向著最終的目標,步履不停!
那么,正在閱讀的你,是否可以助我們一臂之力呢?分享、轉發、使用、交流,以及加入我們,都是對我們最大的鼓勵!
項目地址:
https://github.com/apache/incubator-shardingsphere
更多信息請瀏覽官網:
http://shardingsphere.apache.org/
總結
以上是生活随笔為你收集整理的刚柔并济的开源分布式事务解决方案的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JVM 总体概述
- 下一篇: 架构师口中的混沌工程,究竟用来解决什么问