數據庫

干貨 | 揭秘京東數科強一致、高性能的分布式事務中間件JDTX

廣告
廣告

導讀:在分布式數據庫、云原生數據庫、NewSQL等名詞在數據庫領域層出不窮的當今,變革——在這個相對穩定的領域已愈加不可避免。相比于完全革新,漸進式增強的方案在擁有厚重沉淀的行業則更受青睞。

同所有分布式領域的解決方案相同,分而治之的透明化數據分片方案,是新一代數據庫解決海量數據的核心理念。水平拆分使得分布式事務的重要性,較之垂直拆分的業務系統進一步提升。另外,彈性擴(縮)容、HTAP等概念也是新一代數據庫的關注重點。京東數科開源的Apache ShardingSphere在數據分片方面已逐漸成熟,在此場景之上開發的分布式事務中間件JDTX與之共同組成了分布式數據庫的內核拼圖。

JDTX是由京東數科的數據研發團隊傾力打造的分布式事務中間件。本次分享是JDTX首次公開出現在大眾視野面前,分享內容涵蓋JDTX的核心設計理念及相關的技術實現難點,希望能為打造分布式事務解決方案的團隊提供一些思路。

背景

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

在單一數據節點中,事務僅限于對單一數據庫資源的訪問控制,稱之為本地事務。幾乎所有的成熟的關系型數據庫都提供了對本地事務的原生支持。但是在基于微服務的分布式應用環境下,越來越多的應用場景要求對多個服務的訪問及其相對應的多個數據庫資源能納入到同一個事務當中,分布式事務應運而生。

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

本地事務

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

兩階段提交

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

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

嚴格保障事務ACID特性是一把雙刃劍。事務執行在過程中需要將所需資源全部鎖定,它更加適用于執行時間確定的短事務。對于長事務來說,整個事務進行期間對數據的獨占,將導致對熱點數據依賴的業務系統并發性能衰退明顯。因此,在高并發的性能至上場景中,基于XA協議兩階段提交類型的分布式事務并不是最佳選擇。

柔性事務

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

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

結論

基于ACID的兩階段事務和基于BASE的最終一致性事務都不是銀彈,可通過下表詳細對比它們之間的區別。

兩階段提交柔性事務
業務改造實現相關接口
一致性支持最終一致
隔離性支持業務方保證
并發性能嚴重衰退略微衰退
適合場景短事務 & 低并發長事務 & 高并發

缺乏并發度保障的兩階段事務不能稱之為完善的分布式事務解決方案;而缺乏對ACID原義支持的柔性事務都甚至不能稱之為數據庫事務,它更適合服務層的事務處理。

放眼當前,實難找到無需權衡即可放之四海而皆準的分布式事務解決方案。

JDTX的分布式事務解決方案

JDTX的設計目標是強一致(支持ACID的事務原義)、高性能(甚至強于本地事務)、1PC(完全摒棄兩階段提交和兩階段鎖)的完全分布式事務中間件,目前可用于關系型數據庫。它采用完全開放SPI的設計方式,提供與NoSQL對接的可能,能夠將多元異構數據維持在同一事務中。

設計理念

首先通過一張架構圖來直觀的了解一下JDTX的構成。

JDTX由事務管理器(TM)和資源管理器(RM)組成。

事務管理器用于生成全局單調遞增的事務日志序列號(LSN),事務的提交和回滾等核心流程處理,以及未提交事務的本地元祖(Tuple)持有。

資源管理器用于管理活躍事務數據。JDTX的設計特點是將在事務中的數據(稱之為活躍數據)和不在事務中的數據(稱之為落盤數據)分離?;钴S數據在落盤至預寫日志系統(WAL)之后,并將數據保存至自研的多版本快照(MVCC)內存引擎中。落盤數據則是通過異步刷盤的方式,將MVCC引擎中的數據以流量可控的方式同步至最終的存儲介質中(如:關系型數據庫)。

事務內查詢會將落盤數據和活躍數據合并,并根據當前事務的隔離級別獲取出符合當前事務可見性的數據版本。

方案亮點

無損事務方案

JDTX采用WAL + MVCC引擎的方式實現了事務的ACID原義。

原子性&一致性支持

JDTX的 MVCC引擎可以看做是一個集中式緩存,可以將兩階段提交簡化至一階段提交。維持單一節點中數據的原子性和一致性,即將分布式事務的范疇縮減到本地事務的范疇。

MVCC引擎可以通過分片 + 主從同步的方式維持水平擴展和高可用的能力。JDTX保證所有對事務數據的訪問都通過MVCC引擎的活躍數據 + 最終數據端的落盤數據的合并的方式,以保證數據的原子性和一致性。

隔離性支持

JDTX以多版本快照的方式實現事務隔離性。目前完整的支持4種標準隔離級別中的讀已提交和可重復讀,已經可以滿足絕大部分需求。

持久性支持

JDTX將事務的活躍數據在存入MVCC引擎之前先落盤至WAL引擎,以保證服務器崩潰,內存數據丟失時,活躍數據依然能夠從WAL引擎中完全恢復。

高性能

JDTX采用將活躍數據異步刷盤至數據庫的方式極大的提高了數據寫入的性能上限。它的性能瓶頸從數據庫寫入耗時轉移到了落盤至WAL引擎和存儲至MVCC引擎的耗時。

與數據庫的WAL系統類似,JDTX的WAL也采用日志順序追加的方式,因此可以簡單的理解為JDTX的WAL耗時 = 數據庫系統的WAL耗時。而MVCC緩存則采用哈希數據結構,其寫入耗時小于需要維護BTree索引的數據庫寫入耗時。因此,采用JDTX的事務方案,其數據更新性能甚至強于不開啟事務。

另外,JDTX采取了無UNDO日志的事務回滾策略。未提交的數據并不會進入MVCC引擎,而是被事務管理器本地持有。因此,只要清理掉未提交數據即可完成事務回滾。無UNDO日志的設計進一步的提升了事務處理的性能。

高可用

WAL引擎和MVCC引擎均采用分片 + 主備的方式,以保證JDTX不會產生單點故障。在MVCC引擎完全不可用的情況下,可通過恢復模式將WAL中的數據同步至數據庫,以保證數據的完整性。

跨多元數據庫事務

JDTX將事務活躍數據和落盤數據分離的設計方案,使其落盤數據存儲端無任何限制。所有的事務活躍數據都會通過異步的落盤執行器存儲至后端數據庫,因此后端是否為同構數據庫,其實并無影響。

使用JDTX能夠保證跨多元存儲端(如:MySQL、PostgreSQL甚至是MongoDB、Redis等NoSQL)的分布式事務維持在同一事務語義之中。

實現難點

MVCC內核

事務隔離級別有兩種常見的實現方案,即鎖實現和MVCC實現。除了Infomix等少數數據庫,大部分關系型數據庫均采用MVCC實現。

讀未提交、讀已提交、可重復讀和可序列化這4種事務隔離級別的標準,是ANSI所定義的基于鎖實現的方式。事務的并行度隨著隔離級別的增加而衰減,除了并發度最低的可序列化,其他隔離級別都伴隨著對一致性的權衡和犧牲。

下表是基于鎖實現的隔離級別對照表。

隔離級別臟讀不可重復讀幻讀
讀未提交可能可能可能
讀已提交不可能可能可能
可重復讀不可能不可能可能
可序列化不可能不可能不可能

通過MVCC實現的隔離級別實際上只有SI(快照隔離)和SSI(可序列化快照隔離)這2種。SI和SSI與ANSI的4種隔離級別并不能完全對照。其中的讀未提交,與讀已提交在MVCC的實現中性能并無差別,可以忽略不計。因此SI可以對應為讀已提交和可重復讀這2種隔離級別。實際上,即使是幻讀,在SI隔離級別中也是不會出現的。

由于快照并發控制并不能真正意義上保證事務是“可串行化”的,所以事務間的并發操作依舊有可能引發數據異?,F象。但這里的異常不同于之前提到的臟讀、丟失更新的異常,而是一種業務數據間邏輯語義層面的異常,也可以說是由于未能滿足數據間的語義約束而產生的異常。這被稱之為寫偏序(Write skew),它的檢測可依據并發事務間讀寫依賴的多版本可串行化圖(The multiversion serialization graph)來實現,即SSI隔離級別。

下表是基于MVCC實現的隔離級別對照表。

自研MVCC引擎是JDTX的主要難點之一。JDTX采用與PostgreSQL類似的MVCC實現方案,通過xmin和xmax標記事務快照范圍,并在MVCC引擎中保存每個數據元祖(Tuple)的xmin和xmax的事務信息。同一數據的多版本以鏈表的數據結構存儲,通過其xmin和xmax來獲取數據的版本在當前事務快照中的可見性。

由于MySQL也并未實現SSI隔離級別,因此目前的JDTX只是實現了SI隔離級別,還并未實現SSI隔離級別。

MVCC數據的清理(vacuum)是另一技術難點。過長的事務會導致MVCC版本過多,導致占用大量存儲空間。尤其是JDTX是通過內存來存儲MVCC的活躍數據,因此對內存空間的釋放則更加敏感。由于JDTX的異步落盤機制,因此除了MVCC標準的垃圾回收邏輯之外,判斷數據是否落盤成為清理邏輯的額外規則。

SQL查詢引擎

通過SQL查詢事務的活躍數據,是JDTX的另一個技術實現難點。MVCC引擎并非關系型數據庫,并不能通過識別SQL來查詢相關數據。JDTX則通過之前Apache ShardingSphere所積累的SQL解析模塊及其抽象語法樹(AST)來實現對SQL的理解,以及查詢基于內存的MVCC引擎中的數據。

對于SPJ(select-project-join)的OLTP類型SQL,可以從SQL的查詢結果中獲取數據主鍵。JDTX將落盤數據從后端數據庫中取出作為最終展現數據的基礎,并在此之上從MVCC引擎中查詢出當前事務可見的活躍數據,并對其結果進行歸并。換句話說,每次事務內查詢都是由落盤數據+活躍數據歸并而成。歸并引擎部分參照了LSM Tree的設計思想。

對于非SPJ的OLAP類型SQL,JDTX則采用另外的查詢方式?;诰酆虾瘮岛头纸M的SQL無法通過主鍵直接將后端數據庫中的落盤數據和MVCC引擎中的鍵值數據直接匹配,因此采用以MVCC引擎中數據為主,并將SQL改寫為剔除活躍數據主鍵的新SQL,再從后端數據庫中查詢無重復的聚合數據進行歸并。

使用限制

分布式無銀彈,這是架構師們對現有的分布式系統比較公認的看法。雖然JDTX具備了很多優點,但仍然有一些使用限制。它的使用限制主要有以下3點。

  1. 需要通過JDTX訪問數據庫。JDTX通過其MVCC引擎控制事務的原子性、一致性和隔離性,并通過WAL控制事務的持久性。因此在使用JDTX的系統中,跨過事務中間件直接查詢數據庫,是得不到正確的事務數據的,修改數據庫則會導致數據紊亂。
  2. SQL支持需要持續完善。查詢MVCC引擎的SQL方言兼容則需要持續提升。相對于無損的ACID事務原義支持所帶來的優勢,SQL兼容度的下降,是JDTX帶來的權衡。
  3. 不支持無主鍵數據。JDTX需要通過主鍵來合并MVCC引擎和數據庫中的數據。因此無法處理沒有主鍵的記錄。

JDTX與Apache ShardingSphere

通過Apache ShardingSphere提供的JDBC接入端,可以使JDTX無縫的對接至Java應用。除了JDBC接入端,Apache ShardingSphere也提供了基于MySQL和PostgreSQL的Proxy接入端,使JDTX像一個單獨的數據庫一樣提供分布式事務的服務。Apache ShardingSphere將在未來將接入端剝離,使JDTX獨立使用成為可能。Apache ShardingSphere提供了分布式事務的統一SPI。JDTX通過實現ShardingSphere提供的SPI,可以很輕松的融入Apache ShardingSphere生態。結合Apache ShardingSphere與JDTX,可以將數據分片與分布式事務無縫結合。獨立使用Apache ShardingSphere或JDTX,可以靈活解耦,高度定制,可以看做是基礎組件的樂高積木。而將其聯合使用,則能夠產生化學變化,甚至使它們具備組成分布式數據庫基礎設施的能力。架設在產品最前端的Apache ShardingSphere用于SQL解析、數據庫協議和數據分片;位于中層的JDTX用于通過鍵值對和MVCC的方式處理事務活躍數據;最底層的數據庫則僅作為最終的數據存儲端。下圖是ShardingSphere + JDTX的架構圖。

最后附上MySQL架構圖,請讀者自行體會其相似之處。

JDTX的后續規劃

JDTX的自身目標是力爭將其打造成為一個分布式事務的標準解決方案。在事務核心流程、MVCC引擎、WAL引擎、高可用等核心功能打磨成熟后,JDTX會將主要精力投放在以下幾個方面:

  1. 提升SQL語句兼容性以及多元數據庫支持;
  2. 實現SSI隔離級別,提供完整的MVCC隔離級別解決方案;
  3. 完善管理端和監控端。

除了JDTX中間件自身,它也將與ShardingSphere等其他數據庫中間件更加一體化的提供分布式數據庫級別的服務;并將與Kubernetes等云原生平臺更加深度整合,為云原生數據庫提供服務。

作者簡介:張亮,京東數科數據研發負責人,Apache ShardingSphere發起人 & PPMC,JDTX負責人。

熱愛開源,主導開源項目ShardingSphere(原名Sharding-JDBC)和Elastic-Job。擅長以java為主分布式架構,推崇優雅代碼,對如何寫出具有展現力的代碼有較多研究。

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

于2019年3月出版書籍《未來架構——從服務化到云原生》。

GitHub: https://github.com/terrymanu,隨時歡迎技術交流和指正。

我還沒有學會寫個人說明!

在摸索中前進的中國CRM迎來了轉機?

上一篇

程序員相親圖鑒

下一篇

你也可能喜歡

干貨 | 揭秘京東數科強一致、高性能的分布式事務中間件JDTX

長按儲存圖像,分享給朋友

ITPUB 每周精要將以郵件的形式發放至您的郵箱


微信掃一掃

微信掃一掃
海天娱乐群 深圳配资公司有哪些 不用网络的单机麻将 香港股票交易规则 管家婆期期准免费资料彩图开奖结果 至尊国际棋牌官网下载 浙江20选5开状号码 北化股份股票 2018年永久平特肖公式 加拿大快乐8预测网 股票趋势公式