Categories
程式開發

我們是怎樣打造一款分佈式數據庫的


關係型數據庫在過去數十年的數據庫領域一直佔據著絕對主導的地位,它所帶來的穩定性、安全性和易用性,成為了構建現代化系統的基石。隨著的互聯網高速發展,構架於單機系統的數據庫已無法滿足越來越高的並發請求和越來越大的數據存儲需求,因此,分佈式數據庫被愈加廣泛的採用。

一直以來,數據庫領域均由西方的科技公司和社區所主導。而今,越來越多的國產數據庫解決方案以分佈式為支點,逐漸地在此領域有所建樹。 Apache ShardingSphere是其中的一個分佈式數據庫解決方案,也是目前Apache軟件基金會中唯一的數據庫中間件。

背景

全面兼容面向傳統關係型數據庫的SQL和事務,並且對分佈式的天然友好,是分佈式數據庫解決方案的設計目標。它的核心功能主要集中在以下幾點:

  • 分佈式存儲:數據存儲不受單機磁盤容量限制,可通過增加數據服務器的數量提升存儲能力;

  • 計算存儲分離:計算節點無狀態,可通過水平擴展增加算力。存儲節點和計算節點能夠分層優化;

  • 分佈式事務:高性能、完全支持本地事務ACID原義的分佈式事務處理引擎;

  • 彈性伸縮:可以隨時隨地的在不影響現有應用的情況下,動態對數據存儲節點擴容和縮容;

  • 多數據副本:自動將數據以強一致、高性能的方式複制至跨機房的多個副本,以保證數據的絕對安全;

  • HTAP:採用同一套產品混合處理OLTP的事務型操作和OLAP的分析型操作。

分佈式數據庫的實現方案可以劃分為進取型和穩定型。進取型實現方案是指開發全新架構的NewSQL。這類產品以追求更高性能換取穩定性的缺失和運維經驗的不足;穩定型的實現方案是指在現有數據庫的基礎上提供增量能力的中間件。這類產品則以犧牲部分性能以保證數據庫的穩定性和運維經驗的複用。

架構

Apache ShardingSphere是一套開源的分佈式數據庫中間件解決方案組成的生態圈,它由Sharding-JDBC、Sharding-Proxy和Sharding-Sidecar(計劃中)這3款相互獨立的產品組成。它們均提供標準化的數據分片、分佈式事務和分佈式治理等功能,可適用於如Java同構、異構語言、雲原生等各種多樣化的應用場景。隨著Apache ShardingSphere在查詢優化器和分佈式事務引擎的不斷探索,它已漸漸地打破了實現方案的產品邊界,向集進取型和穩定型於一身的平台級解決方案演進。

Sharding-JDBC

定位為輕量級Java框架,在Java的JDBC層提供的額外服務。它使用客戶端直連數據庫,以jar包形式提供服務,無需額外部署和依賴,可理解為增強版的JDBC驅動,完全兼容JDBC和各種ORM框架。

我們是怎樣打造一款分佈式數據庫的 1

Sharding-Proxy

定位為透明化的數據庫代理端,提供封裝了數據庫二進制協議的服務端版本,用於完成對異構語言的支持。目前已提供MySQL和PostgreSQL版本,它可以使用任何兼容MySQL和PostgreSQL協議的訪問客戶端(如:MySQL Command Client, MySQL Workbench, Navicat等)操作數據,對DBA更加友好。

我們是怎樣打造一款分佈式數據庫的 2

Sharding-Sidecar(規劃中)

定位為Kubernetes的雲原生數據庫代理,以Sidecar的形式代理所有對數據庫的訪問。通過無中心、零侵入的方案提供與數據庫交互的的嚙合層,即Database Mesh,又可稱數據庫網格。

我們是怎樣打造一款分佈式數據庫的 3

計算存儲分離的混合架構

Sharding-JDBC採用無中心化架構,適用於Java開發的高性能的輕量級OLTP應用;Sharding-Proxy提供靜態入口以及異構語言的支持,適用於OLAP應用以及對分片數據庫進行管理和運維的場景。

每種架構方案都有其各自的優缺點,下面表格對比了各種架構模型的在不同場景下的優劣:

我們是怎樣打造一款分佈式數據庫的 4

Apache ShardingSphere是多接入端共同組成的生態圈。通過混合使用Sharding-JDBC和Sharding-Proxy,並採用同一配置中心統一配置分片策略,能夠靈活的搭建適用於各種場景的應用系統,使得架構師更加自由的調整適合與當前業務的最佳系統架構。

我們是怎樣打造一款分佈式數據庫的 5

Apache ShardingSphere採用Share Nothing架構,它的JDBC和Proxy接入端均採用無狀態設計。作為計算節點,Apache ShardingSphere負責對獲取的數據進行最終的計算匯總。由於本身並不存儲數據,因此Apache ShardingSphere可以將計算下推至數據節點,以充分利用數據庫自身的計算能力。 Apache ShardingSphere可以通過增加部署節點數量來增加計算能力;增加數據庫節點數量來增加存儲能力。

核心功能

數據分片、分佈式事務、彈性伸縮和分佈式治理是Apache ShardingSphere目前階段的4個最核心功能。

數據分片

分而治之是Apache ShardingSphere用於處理海量數據的方案。 Apache ShardingSphere通過數據分片方案,使數據庫具備分佈式存儲能力。

它可以將SQL根據用戶預置的分片算法自動路由至相應的數據節點,以達到操作多個數據庫的目的。用戶可以像使用單機數據庫一樣使用被Apache ShardingSphere所管理的多個數據庫。目前支持MySQL、PostgreSQL、Oracle、SQLServer以及任何支持SQL92標準和JDBC標準協議的數據庫。數據分片的內核流程見下圖:

我們是怎樣打造一款分佈式數據庫的 6

主要流程如下:

1、通過解析數據庫協議包或JDBC驅動獲取用戶輸入的SQL和參數;

2、根據詞法分析器和語法分析器將SQL解析為AST(抽象語法樹),並提取分片所需信息;

3、根據用戶預置算法匹配分片鍵,併計算路由路徑;

4、將SQL改寫為分佈式可執行SQL;

5、向各數據節點並行發送SQL,執行引擎負責連接池與內存資源的平衡;

6、根據AST執行流式或全量內存結果集歸併計算;

7、封裝數據庫協議包或JDBC結果集,並返回至客戶端。

分佈式事務

事務是數據庫系統的最核心功能。分佈式的不確定和事務的複雜性,決定了分佈式事務領域無法出現放之四海而皆準的方案。

面對百花齊放的現狀,Apache ShardingSphere提供高度開放的方案,採用標準接口統一整合開發者自主選擇的第三方分佈式事務框架,以滿足各種場景的應用需求。除此之外,Apache ShardingSphere還提供了全新的分佈式事務解決方案JDTX,來彌補現有方案的缺失。

標準化整合接口

Apache ShardingSphere為本地事務、兩階段事務和柔性事務提供了統一的適配接口,並對接了大量的現有第三方的成熟解決方案。通過標準接口,開發者可以輕鬆的將其他整合方案融入到Apache ShardingSphere平台中。

我們是怎樣打造一款分佈式數據庫的 7

然而,融合大量第三方解決方案,卻不能覆蓋所有分佈式事務需求分支。各種解決方案均有各自的適合及不適合場景。各解決方案間是互斥的,無法將它們的優點疊加使用。針對於當前最常見2PC(兩階段提交)和柔性事務,分別存在著以下的優勢和不足:

  • 兩階段提交:基於XA協議實現的兩階段分佈式事務對業務侵入很小。它最大的優勢是對使用方透明,開發者可以像本地事務一樣使用基於XA協議的分佈式事務。 XA協議能夠嚴格保障事務ACID特性,但這也是一把雙刃劍。事務執行在過程中需要將所需資源全部鎖定,它更加適用於執行時間確定的短事務。對於長事務來說,整個事務進行期間對資源的獨占,將導致對熱點數據依賴的業務系統並發性能衰退明顯。因此,在高並發的性能至上場景中,基於XA協議兩階段提交類型的分佈式事務並不是最佳選擇。

  • 柔性事務:如果將實現了ACID的事務要素的事務稱為剛性事務的話,那麼基於BASE事務要素的事務則稱為柔性事務。 BASE是基本可用、柔性狀態和最終一致性這3個要素的縮寫。在ACID事務中對一致性和隔離性的要求很高,在事務執行過程中,必須將所有的資源佔用。柔性事務的理念則是通過業務邏輯將互斥鎖操作從資源層面上移至業務層面。通過放寬對強一致性和隔離性的要求,只要求當整個事務最終結束的時候,數據是一致的。而在事務執行期間,任何讀取操作得到的數據都有可能被改變。這種弱一致性的設計可以用來換取系統吞吐量的提升。

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

我們是怎樣打造一款分佈式數據庫的 8

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

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

新一代分佈式事務中間件JDTX

JDTX是京東數科自研的分佈式事務中間件,尚未開源。它的設計目標是強一致(支持ACID的事務原義)、高性能(不低於本地事務性能)、1PC(完全摒棄兩階段提交和兩階段鎖)的完全分佈式事務中間件,目前可用於關係型數據庫。它採用完全開放SPI的設計方式,提供與NoSQL對接的可能,未來能夠將多元異構數據維持在同一事務中。

JDTX通過完全自研的事務處理引擎,將SQL操作的事務中數據轉化為KV(鍵值對),並在其基礎上實現了MVCC(多版本快照)的事務可見性引擎,以及與數據庫設計理念類似的WAL(預寫日誌系統)存儲引擎。可以通過下面的架構圖來了解一下JDTX的構成:

我們是怎樣打造一款分佈式數據庫的 9

它的設計特點是將在事務中的數據(稱之為活躍數據)和不在事務中的數據(稱之為落盤數據)分離。活躍數據在落盤至WAL之後,再以KV的形態保存至MVCC內存引擎中。落盤數據則是通過異步刷盤的方式,將WAL中的REDO日誌,以流量可控的方式同步至最終的存儲介質中(如:關係型數據庫)。事務內存查詢引擎負責使用SQL從KV格式的活躍數據中檢索到相關數據,與落盤數據合併,並根據事務隔離級別獲取符合當前事務可見的數據版本。

JDTX以全新的架構重新詮釋了數據庫的事務模型,主要亮點有:

1、內化分佈式事務為本地事務

JDTX的 MVCC引擎是一個集中式緩存。它能夠將兩階段提交內化至一階段提交,以維持單一節點中數據的原子性和一致性,即將分佈式事務的範疇縮減到本地事務的範疇。 JDTX通過保證所有對事務數據的訪問都通過MVCC引擎的活躍數據 + 最終數據端的落盤數據的合併的方式,以保證事務數據的原子性和一致性。

2、無損的事務隔離機制

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

3、高性能

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

與數據庫的WAL系統類似,JDTX的WAL也採用順序日誌追加的方式,因此可以簡單的理解為JDTX的WAL耗時 = 數據庫系統的WAL耗時。而MVCC引擎則採用KV數據結構,其寫入耗時小於維護BTree索引的數據庫。因此,JDTX的數據更新性能的上限甚至可以高於不開啟事務。

4、高可用

WAL和MVCC引擎均可以通過主備 + 分片的方式維持高可用和水平擴展的能力。在MVCC引擎完全不可用的情況下,可通過恢復模式將WAL中的數據同步至數據庫,以保證數據的完整性。

5、跨多元數據庫事務

將事務活躍數據和落盤數據分離的設計方案,使其落盤數據存儲端無任何限制。由於事務活躍數據通過異步的落盤執行器存儲至後端存儲介質,因此後端是否為同構數據庫,其實並無影響。使用JDTX能夠保證跨多元存儲端(如:MySQL、PostgreSQL,甚至是MongoDB、Redis等NoSQL)的分佈式事務維持在同一事務語義之中。

通過Apache ShardingSphere提供的分佈式事務統一適配接口,可以將JDTX像其他第三方分佈式事務解決方案一樣輕鬆地融入Apache ShardingSphere生態,將數據分片與分佈式事務無縫結合,使它們具備組成分佈式數據庫基礎設施的能力。架設在產品最前端的Apache ShardingSphere用於SQL解析、數據庫協議和數據分片;位於中層的JDTX用於通過KV和MVCC的方式處理事務活躍數據;最底層的數據庫則僅作為最終的數據存儲端。下圖是ShardingSphere + JDTX的架構圖。

我們是怎樣打造一款分佈式數據庫的 10

可以說,JDTX的存在,使得Apache ShardingSphere打破了穩定型的數據庫中間件的定位,在保持穩定的同時,逐步向進取型NewSQL發展。

彈性伸縮

與無狀態的服務化應用不同,數據節點中均持有不可丟失的重要用戶數據。當數據節點的容量不足以承擔快速增長的業務時,數據節點的擴容則在所難免。根據用戶預置的分片策略不同,擴容的策略也會隨之不同。

彈性伸縮可以讓被Apache ShardingSphere所管理的數據庫在不停止對外服務的情況下進行擴容和縮容。彈性伸縮分為彈性遷移和範圍擴容兩個組件,目前它們均在孵化中。

彈性遷移

數據遷移是面向用戶定制分片策略的標準擴縮容方案。在遷移過程中,需要準備兩套數據節點。原數據節點在繼續提供服務的同時,將數據以存量和增量的方式,分別寫入新數據節點。整個遷移過程無需停止對外服務,可以平順的過渡新舊數據節點。 Apache ShardingSphere還將提供工作流界面,讓遷移過程完全自主可控。
彈性遷移的架構圖如下:

我們是怎樣打造一款分佈式數據庫的 11

具體流程如下:

1、通過配置中心修改數據分片配置,以觸發遷移流程。

2、記錄當前遷移數據開啟前的位點之後,開啟歷史遷移作業,分批遷移全量數據。

3、開啟Binlog訂閱作業,遷移位點之後的增量數據。

4、根據採樣率設置比對數據。

5、設置原數據源只讀,確保實時數據遷移完成。

6、將應用連接切換至新數據源。

7、舊數據源下線。

遷移時長根據數據量的大小可能是幾分鐘至幾週不等。遷移過程中可以隨時回退或重新遷移。整個遷移流程完全自主可控,降低遷移過程中的風險;並且通過自動化工具完全屏蔽人工操作,避免繁瑣的操作帶來的巨大工作量。

範圍擴容

如果彈性遷移稱之為硬伸縮的話,那麼範圍擴容則稱之為軟伸縮。 Apache ShardingSphere的範圍擴容不涉及內核改造,也無需遷移數據,它只需通過優化範圍分片策略,即可達到自動擴(縮)容的目標。使用範圍擴容,用戶無需感知分片策略和分片鍵等分庫分錶方案中必要概念,讓Apache ShardingSphere更加接近一體化的分佈式數據庫。

使用範圍擴容的用戶,只需向Apache ShardingSphere提供數據庫資源池。容量巡檢器會在表容量到達閾值時,從資源池中依次尋找下一個數據節點,並在新數據節點創建新表之後,修改分片策略的範圍元數據。當資源池中沒有新數據節點後,Apache ShardingSphere會按照同樣的順序,在已經創建過表的數據庫中增加新表。
當表數據大量刪除時,之前的數據節點的數據將不再緊湊,垃圾回收器會定時壓縮表範圍,以釋放更多的碎片空間。範圍擴容的結構如下:

我們是怎樣打造一款分佈式數據庫的 12

Apache ShardingSphere為不同的應用場景,提供了更加靈活的彈性伸縮策略。目前仍在孵化中的兩個彈性伸縮相關的項目,也力爭盡快提供試用版本。

分佈式治理

治理模塊的設計目標是為了更好管理和使用分佈式數據庫。

數據庫治理

與所有的分佈式系統的設計理念一脈相承,分而治之同樣是分佈式數據庫的指導方針。數據庫治理能力的存在,能夠讓管理成本不隨著數據庫實例數目的增長而提升。

配置動態化

Apache ShardingSphere使用配置中心來管理配置,可以在配置修改後的極短時間內傳播到所有的接入端實例。配置中心採用開放的SPI方式,能夠充分利用配置中心自身的能力,如配置多版本變更等。

高可用

Apache ShardingSphere使用註冊中心管理接入端實例和數據庫實例的運行狀態。註冊中心同樣採用配置中心的開放SPI方式。部分註冊中心的實現可以涵蓋配置中心的能力,因此用戶可以疊加使用註冊中心和配置中心的能力。

Apache ShardingSphere提供了數據庫實例禁用和接入端熔斷的能力,分別用於處理數據庫實例不可用和接入端被大流量衝擊的場景。

Apache ShardingSphere目前正在孵化高可用的SPI,讓用戶能夠復用數據庫自身提供的高可用方案。目前正在對接MySQL的MGR高可用方案。 Apache ShardingSphere可以通過自動探知MGR的選舉變化并快速傳播至所有的應用實例。

可觀察性

大量數據庫和接入端實例,使得DBA和運維人員無法迅速感知當前系統的狀況。 Apache ShardingSphere通過對OpenTracing協議的實現,將監控數據發送至實現其協議的第三方APM系統中;除此之外,Apache ShardingSphere還提供了Apache SkyWalking的自動探針,可以讓使用它作為可觀察性產品的用戶直接觀測到Apache ShardingSphere的性能、調用鏈關係以及系統的整體拓撲圖。

數據治理

得益於Apache ShardingSphere對SQL靈活的處理能力和對數據庫協議的高度兼容性,數據相關的治理能力也被很方便的加入到了產品生態中。

脫敏

Apache ShardingSphere可以讓用戶在無需修改代碼的情況下,自動將指定的數據列加密後存儲至數據庫,並在應用程序獲取數據時解密,以保證數據的安全。當數據庫的數據被不慎洩露時,敏感數據信息由於被完全加密,從而不會造成更大的安全隱患。

影子庫表

Apache ShardingSphere可以在系統進行全鏈路壓測時,自動將用戶標記的數據路由至影子庫(表)。影子庫(表)壓測功能可以讓線上壓測成為常態,用戶無需在關心壓測數據的清理。此項功能也正在高速的孵化中。

線路規劃

如您所見,Apache ShardingSphere正處於高速發展的軌道中,越來越多與“分庫分錶”這條曾經主線並無強關聯的功能被加入其中。但這些產品功能卻並不突兀,它們反而能助力Apache ShardingSphere成為更加多元化的分佈式數據庫解決方案。 Apache ShardingSphere未來的線路主要會集中在以下幾點。

可插拔平台

越來越多的零散功能需要進一步梳理。 Apache ShardingSphere現有的架構還不足以完全吸收如此廣泛的產品功能。彈性化的功能可插拔平台是Apache ShardingSphere未來架構的調整方向。

可插拔平台會將Apache ShardingSphere從技術和功能兩方面完全拆開。 Apache ShardingSphere的全景圖如下所示:

我們是怎樣打造一款分佈式數據庫的 13

Apache ShardingSphere會根據技術架構橫向分為4層,分別是接入層、SQL解析層、內核處理層和存儲訪問層;並且將功能以可插拔的形態融入至4層架構中。

Apache ShardingSphere對數據庫類型的支持將完全開放,除了關係型數據庫,NoSQL也會完全開放支持,數據庫方言互不影響,完全解耦。在功能方面,Apache ShardingSphere採用疊加式架構模型,使各個功能可以靈活的組合使用。每個功能模塊只需關注自身的核心功能,由Apache ShardingSphere架構負責功能的疊加組合使用。即使沒有任何功能,Apache ShardingSphere也可以作為一個空白的接入端直接啟動,為開發者的定制化開發提供腳手架以及SQL解析等基礎設施。融入Apache ShardingSphere生態的數據庫,將直接獲得平台提供的所有基礎能力;在Apache ShardingSphere平台上開發的功能,也將直接獲得已接入平台的數據庫類型的全部支持。數據庫類型和功能類型將以相乘的方式排列組合,基礎設施 + 樂高的組合,將為Apache ShardingSphere提供各種想像和提升的空間。

查詢引擎

目前Apache ShardingSphere只是將SQL通過正確的路由和改寫,分發至相應的數據庫以操作數據。計算下發能夠充分利用的數據庫的查詢引擎,但無法有效的支持複雜關聯查詢和子查詢。基於關係代數實現的SQL on KV查詢引擎隨著JDTX的開發日臻成熟,將其積累的經驗反哺於SQL查詢引擎,能夠讓Apache ShardingSphere更好的支持子查詢和跨庫關聯查詢等複雜查詢。

多數據副本

分佈式數據庫所需要的多數據副本能力目前的Apache ShardingSphere還未具備。未來Apache ShardingSphere將提供基於Raft的多副本寫入能力。

Database Mesh

上文中提到的Sharding-Sidecar接入端,是Apache ShardingSphere未來的第三個接入端形態,旨在更好的與Kubernetes配合,打造雲原生數據庫。

Database Mesh的關注重點在於如何將分佈式的數據訪問應用與數據庫有機串聯起來,它更加關注的是交互,是將雜亂無章的應用與數據庫之間的交互有效的梳理。使用Database Mesh,訪問數據庫的應用和數據庫終將形成一個巨大的網格體系,應用和數據庫只需在網格體系中對號入座即可,它們都是被嚙合層所治理的對象。

Data Federation

支持更多的數據庫類型之後,Apache ShardingSphere會將工作重點放在多元異構的數據庫類型的統一查詢引擎之上。除此之外,Apache ShardingSphere還將配合JDTX,將更加多元的數據存儲介質納入到同一事務中。

開源與社區

Apache ShardingSphere在2016年1月17日在GitHub平台首次開源,開源項目的初始名稱是Sharding-JDBC。在2018年11月10日,ShardingSphere改名並正式進入Apache軟件基金會的孵化器。

在開源至今走過的4年里程中,Apache ShardingSphere的架構模型在不斷的演進的同時,整體產品的功能範圍也在急速地擴張。它從開源之初的分庫分錶Java開發框架,逐漸演化為分佈式數據庫解決方案。

隨著Apache ShardingSphere的生態圈的擴張,由少數開發者掌控項目的狀態早已被打破。目前的Apache ShardingSphere有近百名貢獻者,以及近20名核心提交者,他們共同打造著這個遵循著Apache Way的社區。 Apache ShardingSphere是一個標準的Apa​​che軟件基金會開源項目,並不受某一商業公司或某幾位核心開發者掌控。

目前有超過100家公司明確的聲明他們在使用Apache ShardingSphere,讀者可以從官方網站找到採用公司的用戶牆。

隨著社區的成熟,Apache ShardingSphere的成長也越來越迅速。我們誠邀感興趣的開發者一同參與到Apache ShardingSphere社區中,完善不斷擴大的生態。

項目地址:

https://github.com/apache/incubator-shardingsphere

作者介紹:

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

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

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