1. 程式人生 > 其它 >ICDE 2022|Apache ShardingSphere:一個功能全面和可插拔的資料分片平臺

ICDE 2022|Apache ShardingSphere:一個功能全面和可插拔的資料分片平臺

相信大家在網上搶購時遇到過網頁無法正常訪問的情況,一部分原因可能是資料庫無法很好地應對不斷增加的併發訪問。如何有效地解決資料庫現有的這些缺陷呢?資料分片是一個可選的方案。本篇文章將為大家解讀由重慶大學和 SphereEx 實驗室合作的、發表在 CCF A 類資料庫頂級會議 ICDE 2022 上的論文《Apache ShardingSphere:A Holistic and Pluggable Platform for Data Sharding》。

01 問題背景

隨著資料量的不斷增加以及人們對資料需求的不斷增長,需要資料庫不僅能夠管理大量資料,還能夠支援高度併發的訪問。設計一種能夠應對這兩種要求的資料庫能夠提高使用者體驗,減少類似網購時網頁無法訪問的情況出現。

目前來看,關係型資料庫仍然是線上事務處理的主力,因為它們支援完整的事務。但是關係型資料庫設計初期是針對單臺機器的,資料量過大時往往可擴充套件性欠佳,而且不能很好地解決高併發的問題。儘管現在像 HBase 這種 NoSQL 資料庫可以支援高併發請求,但是他們不太適合線上事務的處理,還可能會出現資料不一致的問題。所以很多人開始關注 NewSQL,New 就意味著是從零開始開發的資料庫。雖然適合現在的應用場景,但它們還沒有很好地接受社會的檢驗,而且 NewSQL 的使用和維護人員還需要額外地學習相關新技術。

那麼在已有的資料庫和應用程式之間插入一個數據分片中介軟體,來連線和管理眾多已有的資料庫,是不是可行呢?答案自然是肯定的。如下圖 1 所示,資料分片中介軟體將使用者查詢分配到不同機器內的多個數據庫中,分別執行查詢後再將多個結果合併,最後返回到應用程式中,這有效地解決了單臺機器的限制。對於開發人員來說,資料分片中介軟體是透明的,使用更為方便。這麼看資料分片中介軟體十分友好且非常高效。

(圖 1:資料分片示例)

設計一個好的資料分片中介軟體存在很大挑戰。第一,在不同的場景下采用的底層資料庫不同,這些資料庫採用不同的資料庫協議和 SQL 語句,在一個統一的框架下支援多種資料庫並不簡單。此外,有許多 SQL 語句型別(從簡單的查詢到聚合再到多表 join 等),對不同 SQL 語句的路由方法以及合併策略也不相同。第二,多個數據庫之間協調事務比較困難,有時候單個事務型別可能不支援所有的場景。第三,資料分片中介軟體可能會遇到效率問題,因為轉發請求、合併結果影響需要消耗一些時間。第四,資料管理員需要逐個配置分片規則,這對他們不是很友好。

Apache ShardingSphere 作為 Apache 第一個頂級開源的資料庫分片專案,能夠解決了上面提到的所有挑戰。ShardingSphere 的主要目標就是要減少資料分片的影響,讓開發人員像使用單個數據庫一樣使用分片資料庫。它擁有以下幾個顯著的特點:

(1)功能完備。ShardingSphere 支援多種主流的關係型資料庫(實際上,任何滿足 SQL-92 標準的資料庫都支援)。它設計並實現了一個完整的 SQL 引擎,因此任何型別的 SQL 都能夠準確的被路由。此外,其提供了三種類型的分散式事務和其他豐富的功能。據作者所知,ShardingSphere 是第一個將資料分片、強一致性事務和柔性事務結合在一起的系統。

(2)高效。除了代理模式,ShardingSphere 還提供了 JDBC 的接入方式,這在大部分場景下能夠大幅提升效率。此外,ShardingSphere 提出了兩種執行模式,並提出了一種智慧的策略來選擇合適的執行模式和結果合併策略,這能夠很好地平衡資源和效率。

(3)可插拔和可擴充套件。ShardingSphere 基於 SPI(Service Provider Interface, 一種 Java 語言中的服務發現機制)和多種設計模式設計的。因此,更多型別的資料庫、功能、分片演算法都能夠非常方便地加入。此外,所有現有的功能都能夠移除或者自由組合。

(4)使用者友好。ShardingSphere 支援幾乎所有的 SQL 語句,同時隱藏了分散式事務的細節。因此,應用開發人員能夠在 ShardingSphere 的幫助下像使用單機版資料庫一樣使用分散式事務和分片後的資料庫叢集。ShardingSphere 還提出了一種新的 DistSQL 和 AutoTable 策略,能夠幫助資料庫管理員更方便地配置分片策略。

當前(截止到論文撰寫時期)有 170 多個公司宣佈在使用 ShardingSphere。本文基於 2021 年 11 月 10 日釋出的 ShardingSphere 5.0.0 版本。

02 系統框架和資料流

如圖 2 所示,ShardingSphere 一共分為五個模組,1)資料來源模組,整合多種資料庫來進行儲存。當前支援的資料來源有 MySQL,PostgreSQL,SQL Server,Oracle,MariaDB 和openGauss。2)功能模組,用來提供許多開箱即用的功能,也可以自由地新增、組合、刪除功能來滿足需求。3)調控器,主要用於配置管理和健康監測。4)SQL 引擎,設計並實現了一個完整的資料分片 SQL 引擎。所有功能都可以通過 SQL 引擎實現可插拔,並且任何功能都可以通過一條 SQL 語句實現。5)適配介面,可以支援不同的場景來使用。

(圖 2:ShardingSphere 框架)

圖 3 展示了 ShardingSphere 的資料流,主要分為兩種。第一種是對 JDBC 進行增強擴充套件,ShardingSphere-JDBC 可以和 Java 應用程式在同一個程序中執行。第二種是在資料來源和應用程式之間的程序 ShardingSphere-Proxy,可以支援使用任何程式語言的應用程式。此外,可以通過任何相容 MySQL 或 PostgreSQL 協議的終端(如 MySQL 命令客戶端、MySQL Workbench 等)直接連線到 ShardingSphere-Proxy,對資料庫管理員十分友好。調控器作為一個單獨的程序,用來監視資料來源並且維護 ShardingSphere-JDBC 和 ShardingSphere-Proxy 配置。

(圖 3:ShardingSphere 資料流)

接下來我們從圖 2 中的功能模組、調控器、SQL 引擎、適配介面進行細節講解。

03 功能模組

3.1 資料分割槽

資料分割槽是 ShardingSphere 中最重要的功能之一。它將資料拆分並根據一定的條件將其儲存在多個表或資料來源(這裡的資料來源即為邏輯資料庫,下同)中。ShardingSphere 提出表分片和資料來源分片,每種分片有水平和垂直兩種分片方法,下圖 4 給出四種類型分片的例子。圖 4(a)是原始資料庫及其內部表的結構和資料。圖 4(c)為垂直表分片、水平表分片、垂直資料來源分片以及水平資料來源分片四種分片方式。其中分片後的表格結構為 4(b)所示。垂直分片改變了結構,在應用時需要不時調整架構設計,無法很好地滿足網際網路業務快速變化的需求。相比之下,水平資料分片可以突破單臺機器儲存量的限制,並且可以更自由地擴充套件,本文主要對水平分片進行研究。

(圖 4:分片例項)

結合圖 1 和圖 4 我們來解釋資料分片中的一些概念:圖 1 中的 uid 用來確定資料分片的欄位,稱其為分片鍵。ShardingSphere 支援多欄位分片鍵。圖 1 中“uid%2”用來將資料記錄分配給不同的表,我們稱其為分片演算法。ShardingSphere 中包含十餘種內建分片演算法,使用者也可以通過介面進行自定義演算法。ShardingSphere 還為不同的資料分片需求提供了不同型別的表。例如上圖的 tuser,我們稱其為邏輯表,而 tuserh0,tuserh1 為實際表。真正儲存在資料庫中的表是實際表,但是應用程式開發人員所看到的表是未經分片的邏輯表。對於應用程式開發人員來說分片操作是透明的。如果在圖 4(c)中,如果 tuser 和 torder 採用相同的分片演算法、相同的資料來源、相同的分片鍵和相同的分片演算法,我們稱它們表為繫結表,這在關聯查詢時十分有用。此外,我們使用資料節點將邏輯表對映到實際表。它是分片的原子單位,由一個數據源名稱和一個實際的表名組成,例如,DS0.tuser_h1。

3.2 分散式事務

ShardingSphere 為不同的使用場景提供了三種類型的分散式事務。

XA 事務。原生 XA 事務共有三個角色:AP、RM、TM,開發人員如果要使用 XA 事務,會有較大的學習成本。ShardingSphere 扮演了 AP 和 TM 的角色,因此開發人員能夠像使用單機版事務一樣使用 XA 事務。如下圖 5,當應用程式向 ShardingSphere 傳送“提交”請求,ShardingSphere 將記錄日誌並啟動 2PC(兩階段提交)過程:第一階段,ShardingSphere 向所有資料來源傳送“準備”訊息,以檢查該事務是否可以提交。如果一個數據源確定可以提交它自己的事務,它會向 ShardingSphere 傳送一個“ok” ;否則,它會發送一個“no”,並回滾它所做的事情。若所有資料來源都“ok”,ShardingSphere 則向所有資料來源傳送“commit”,否則傳送“Rollback”通知回滾。資料來源根據命令進行操作。

(圖 5:XA 事務)

XA 事務保證了資料的 ACID 特性,但是因為會鎖定資源,不太適合長時間事務,ShardingSphere 提供了本地事務和 BASE 事務來解決此問題。

本地事務。如圖 6,當 ShardingSphere 接收來自使用者應用程式的“COMMIT”或“ROLLBACK”命令時,它會直接把該命令傳輸到所有資料來源。即使某些資料來源提交失敗,ShardingSphere 也會忽略它。因為 Local 事務沒有準備階段,故可以提高效率。

(圖 6:本地事務)

BASE 事務。BASE 事務可以接受短時間內的資料不一致。滿足基本可用、軟狀態和最終一致三個要求的事務稱為 BASE 事務。通常,BASE 事務可以從效能上改進系統,因為它們不需要很強的一致性,並且可以減少對共享資源的爭用。

(圖 7:BASE 事務模型)

ShardingSphere 封裝了 SEATA,因為 SEATA 提出了一種自動事務(AT)模式來自動生成補償操作。如圖 7 的灰色框所示,SEATA 中有三個角色:1)事務協調器(TC)維護全域性和分支事務的狀態,並驅動全域性提交或回滾;2)事務管理器(TM)定義全域性事務的範圍;以及 3)資源管理器(RM)管理資源並驅動分支事務提交或回滾。使用者應用程式只需要以標準的資料庫連線方式與 ShardingSphere 互動。ShardingSphere 中的 BASE 事務是 2PC 過程,其中 ShardingSphere 扮演 SEATA 中的 TM 和 RM 的角色,BASE 事務過程如圖 8 所示。

 (圖 8:BASE 事務過程)

當然除了資料分片和分散式事務,ShardingSphere 還提供了許多其他有用的功能,包括但不限於:讀寫拆分、加密、影子(即建立影子資料庫並將相應的測試 SQL 路由到它)、伸縮等等。所有這些功能對應用程式開發人員都是透明的,因為 ShardingSphere 可以智慧地從標準 SQL 語句中識別必要的資訊。而且我們可以根據使用場景自由新增、刪除或合併其他功能。更多資訊可在我們的使用者手冊中找到。

04 調控器

4.1 配置管理

配置資訊儲存在 Apache ZooKeeper 中,這是一個成熟而強大的分散式協調系統,提供高效的記憶體管理和分散式鎖服務。現在開發者習慣於通過 SQL 操作資料。為此,我們提出了一種新的 DistSQL(分散式 SQL),它允許使用者以使用資料庫的方式配置 ShardingSphere。DistSQL 分為資源和規則定義語言(RDL)、資源和規則查詢語言(RQL)和資源和規則管理語言(RAL):

(1)RDL:用來新增、更改或刪除資源和規則。例如:

其中我們提出了 AutoTable 的概念, 我們不需要手動設定分片規則,只需要告訴 ShardingSphere 分片的資料來源和應有多少分片,分片的細節就交給 ShardingSphere。

(2)RQL:用來查詢和顯示現有的資源和規則。例如:

(3)RAL:負責附加的管理員功能,如切換交易型別和擴充套件。例如:

可看出 DistSQL 和一般 SQL 十分相似,對開發人員很友好。更多資訊可參考使用者手冊。

4.2 健康檢測

為了保證高可用性,我們可以建立多個 ShardingSphere-Proxy 例項,並使用負載均衡工具保證負載均衡。調控器會啟動一個執行緒來定期檢查每個 ShardingSphere-Proxy 例項和底層資料庫的狀態,如果發現變化,調控器會自動更改配置,以確保系統仍能正常工作。

05 SQL 引擎

ShardingSphere 設計並實現了一個完整的 SQL 引擎,用於資料分片和其他功能。因此,ShardingSphere 中的所有功能都可以通過一條 SQL 語句實現。

當一條 SQL 語句到來時,通過 SQL 解析器將其解析成抽象語法樹。之後 SQL 路由器根據解析結果將邏輯 SQL 語句與資料節點進行匹配。但是上文我們提到開發人員看到的是邏輯表而不是實際表,所以為了在實際的資料來源中進行 SQL 操作,需要通過 SQL 重寫器將 SQL 語句重寫,重寫分為兩步,首先進行正確性重寫,將識別符號重寫為實際的識別符號(例如將 tuser 重寫為 tuser_h0)、派生後續合併所需要的列、修改來自不同資料來源的分頁、拆分含有批處理的插入語句。這樣保證 SQL 語句執行的正確性、避免資料重複。其中可以進行優化重寫,對於路由到單節點 SQL 可以只重寫識別符號不進行其餘重寫操作提高效率。SQL 執行器將重寫後的 SQL 語句傳送到底層資料來源執行相關操作。下文講解執行細節。從 SQL 執行器中得到的不同資料來源的多個結果進行結果合併,並將結果返回給使用者應用程式。

5.1 SQL 執行器

這部分不僅僅是簡單向底層資料來源轉發 SQL 語句,還需要關注資料來源連線、記憶體消耗和最大併發之間的平衡。

SQL Executor 提出了兩種連線模式來自動平衡資源控制和執行效率:1) 嚴格記憶體模式,它考慮了更多的記憶體使用,並且不限制一個操作的連線數。在這種模式下,我們更傾向於為每個資料節點維護一個獨立的連線,併發執行 SQL,將結果通過資料遊標來載入並進行流合併,以避免記憶體溢位或頻繁的垃圾回收;2) 嚴格連線模式,嚴格限制每次操作的連線消耗。此模式只能使用將所有結果資料載入到記憶體中進行合併的記憶體合併。

然而,對於使用者來說很難選擇合適的連線方式。此外,即使在相同的應用中,不同的查詢可能適合不同的模式。為了方便使用者我們設計了自動執行引擎,如下圖 9,分為兩個階段。

(圖 9:SQL 執行器)

準備階段。在此階段,我們首先按資料來源對路由和重寫結果進行分組。然後,我們根據每個資料來源的連線情況確定它們的連線方式。如果路由到資料來源的 SQL 數量大於資料來源用於查詢的最大連線數,就只能採用嚴格連線模式,否則,我們可以選擇嚴格記憶體模式。接下來,我們獲得所需的連線並建立執行單元。為了避免出現死鎖,我們向資料來源新增鎖來自動獲取查詢所需的所有連線。

執行階段。在此階段,將組中的執行單元一起傳送到對應的底層資料來源。資料來源並行執行 SQL,併為分散式事務或監視傳送事件訊息。

5.2 結果合併

結果合併將來自不同資料來源的多個結果集合併為一個,並將結果返回給使用者應用程式。上文提到流合併和記憶體合併兩種合併方式,對於不同的語句我們採用不同的合併方式。

對於迭代語句我們採用流合併的方式,只需要將結果按照資料庫遊標逐一合併。對於排序(Order by)語句而言,因為每個資料來源返回的結果集是有序的,我們採用流合併來使用多路合併演算法將這些結果集合併為一個結果集。如果語句同時包含 GROUP BY 和 ORDER BY,並且 GROUP BY 和 ORDER BY 的屬性相同,則可以使用流合併。因為組中的資料記錄都位於遊標所指向的第一位置,如圖 10,我們從左到右掃描指向的資料記錄(標記為橙色)並累積分數,直到名字不是“Jerry”,輸出“Jerry,185”後,調整資料庫遊標並重覆上述操作。其他情況我們需要使用記憶體合併。

(圖 10:GROUP BY 時流合併示例)

此外我們還可以將流合併和記憶體合併用於聚合語句以及分頁操作。

06 介面卡和應用程式

ShardingSphere 包含兩個介面卡:ShardingSphere-JDBC 和 ShardingSphere-Proxy。前者可以被視為增強的 JDBC 驅動程式。它封裝了整個 SQL 引擎和 ShardingSphere 提供的其他功能,可以在任何使用 JDBC 的地方使用。後者是一個代理伺服器,它將來自應用程式的請求轉發到資料來源。它提供了一個連線池,因此不同的應用程式和不同的查詢可以共享同一連線。ShardingSphere-Proxy 將自己偽裝成 MySQL 或 PostgreSQL 資料庫。所以它對應用程式開發人員是透明的,並且支援任何程式語言。

現在全世界已經有許多地方在使用 ShardingSphere 系統比如京東白條、中國電信翼支付等。ShardingSphere 提高了服務質量,降低了開發成本。

07 實驗

資料集:1)Sysbench,這是一個著名的資料庫基準測試工具,它提供了一個表格,允許使用者調整其資料量。2)TPCC,一個廣泛使用的 OLTP 基準,它模擬了商店經常使用的幾種交易型別。它的 10 個表按倉庫組織(每個倉庫約 600,000 個條目)。

對比方法:MySQL v5.7.26(MS);PostgreSQL v10.17(PG);Vitess v12.0.0;Citus v9.0.0;TiDB v5.2.0;CockroachDB v21.1.11(CRDB);Aurora MySQL v2.07.2;Aurora PostgreSQL v4.2。

我們在華為雲中使用了一個由 12 臺虛擬伺服器組成的叢集,每臺伺服器都配備了 CentOS 7.1 64 位、32-VCORE CPU、64 GB 記憶體和 1TB 磁碟。

對比實驗。使用 Sysbench 進行比較,如下表所示,基於 ShardingSphere 的系統在所有場景中總是表現最好的。

使用 TPCC 進行比較,TPCC 提供了五個場景,每個場景的比例是固定的,所以我們只給出整體表現。如圖 11 可看出 SSJ 效果最好。

(圖 11:不同分散式系統的比較)

可伸縮性實驗。接下來我們只與 TiDB 進行對比,因為它相比於別的系統性能最優。如圖 12,基於 SSJ 的系統總是執行得最好。

(圖 12:不同資料量)

不同的併發數,如圖 13 基於 SSJ 的系統在 TPS 方面表現最好。

 (圖 13:不同併發數)

不同的資料伺服器,如圖 14,TPS 先略有增加,然後在資料伺服器數量超過 3 臺時保持穩定。原因可能有兩個。首先,我們只使用一個代理伺服器,這可能是一個瓶頸。其次,隨著資料伺服器的增多,網路可能成為另一個瓶頸。

(圖 14:不同資料伺服器數量)

我們驗證的繫結表的有效性,圖中 Common 是沒有繫結關係的表查詢的效能,可明顯看出遠遠不如有繫結關係的繫結表的效率。

(圖 15:繫結表的效能)

我們測試了不同最大連線數 MaxCon 對效率的影響,如圖 16。

(圖 16:最大連線數的效率)

08 總結

本文介紹了開源資料分片系統 Apache ShardingSphere,它允許使用者像使用一個數據庫一樣使用分片資料庫。在兩個著名的基準測試工具上進行了廣泛的實驗,驗證了在我們的設定下, ShardingSphere 的效能在大多數情況下都優於其他分片系統和新架構的資料庫。越來越多的公司正在將 ShardingSphere 用於其關鍵的應用程式。在未來的工作中,我們將提供基於 ShardingSphere 的“資料庫+”產品,並構建一個具有更多可插拔功能的生態系統。

⏰ 歡迎點選下載論文。

歡迎新增社群經理微信(ss_assistant_1)加入交流群,與眾多 ShardingSphere 愛好者一同交流。