SQL 居然還能在 Apache ShardingSphere 上實現這些功能?

SphereEx發表於2021-07-01

在去年 10 月 5.0.0-alpha 版本釋出之後,Apache ShardingSphere 經歷了長達 8 個多月的持續開發與最佳化,終於在 6 月 25 日正式迎來了 5.0.0-beta 版本的釋出。

本次 5.0.0-beta 版除了提供 DistSQL 這樣的新特性外,對 ShardingSphere 核心也進行了增強,主要體現在 SQL 基礎解析能力增強、SQL 標準路由能力提升和 SQL 分散式查詢能力增強這三方面。透過這三方面最佳化,不僅進一步提高了對 MySQL,PostgreSQL,SQLServer 和 Oracle 資料庫的基礎 SQL 解析能力,而且大幅度提高了對使用者 SQL 的支援度,特別針對跨資料庫例項的關聯 SQL 進行了更有針對性的最佳化。本文將帶領大家一起,探秘 5.0.0-beta 版核心增強特性。

作者:端正強

Apache ShardingSphere Committer,SphereEx Java 高階工程師。熱愛開源,樂於分享,目前專注於 Apache ShardingSphere 資料庫中介軟體開發。

核心原理

在探秘 5.0.0-beta 版核心增強之前,讓我們先來回顧下 ShardingSphere 的核心原理。如下圖所示,ShardingSphere 核心主要由解析引擎、路由引擎、改寫引擎、Standard 執行引擎、Federate 執行引擎、歸併引擎等組成。Federate 執行引擎是本次 5.0.0-beta 版本引入的新功能,用於增強分散式查詢能力。

  • 解析引擎:解析引擎負責進行 SQL 解析,具體可以分為詞法分析和語法分析。詞法分析負責將 SQL 語句拆分為一個個不可再分的單詞,然後語法分析器對 SQL 進行理解,並最終得到解析上下文。解析上下文包括表、選擇項、排序項、分組項、聚合函式、分頁資訊、查詢條件以及可能需要修改的佔位符標記;

  • 路由引擎:路由引擎根據解析上下文,匹配使用者配置的分片策略,並生成路由結果,目前支援分片路由和廣播路由;

  • 改寫引擎:改寫引擎負責將 SQL 改寫為在真實資料庫中可以正確執行的語句,SQL 改寫可以分為正確性改寫和最佳化改寫;

  • Standard 執行引擎:Standard 執行引擎負責將路由和改寫完成之後的真實 SQL 安全且高效地傳送到底層資料來源執行;

  • Federate 執行引擎:Federate 執行引擎負責處理跨多個資料庫例項的分散式查詢,底層使用的 Calcite 基於關係代數和 CBO 最佳化,透過最優執行計劃查詢出結果;

  • 歸併引擎:歸併引擎負責將從各個資料節點獲取的多資料結果集,組合成為一個結果集並正確的返回至請求客戶端。

在回顧了 ShardingSphere 核心原理後,下面讓我們來具體看看 5.0.0-beta 版核心增強。

SQL 基礎解析能力增強

SQL 解析引擎是 ShardingSphere 專案的基石,也是專案中最穩定的基礎設施。在 5.0.0-alpha 版中,我們將 SQL 解析引擎與主專案完全剝離,為開發者提供了一套獨立的 SQL 解析引擎元件,相比其他老牌 SQL 解析引擎,ShardingSphere SQL 解析引擎具有易於擴充套件和更完善的 SQL 方言支援等特性。目前,使用者可將 ShardingSphere SQL 解析引擎作為獨立解析器,進行 SQL 解析,詳見官網連結( https://shardingsphere.apache.org/document/current/cn/features/sharding/principle/parse/)。

在本次釋出的 5.0.0-beta 中,我們更加關注 SQL 解析引擎最重要的兩個衡量指標——效能和 SQL 支援度。對於效能問題,ShardingSphere 已透過快取將 SQL 解析的效能損耗降至最低。對於社群一直關注的 SQL 支援度問題,ShardingSphere 結合多個不同反饋渠道,在本次釋出的 5.0.0-beta 版中進行了大量的 SQL 解析最佳化和支援度提升。

首先是 ShardingSphere 社群透過協議層反推過來的 SQL 最佳化,在 SQL 支援度提升的同時,Proxy 接入端也越來越穩定,特別是 ShardingSphere-Proxy PostgreSQL 5.0.0-beta 版,在各個方面都有較大提升,歡迎大家下載使用。此外,針對 MySQL,PostgreSQL,openGauss 資料庫的 Proxy 接入端介紹,也會在後續為大家帶來技術分享。

其次是 SphereEx 效能測試團隊,在使用 sysbench 和 tpcc 進行壓測過程中,反饋了很多測試用例中不支援的 SQL。針對 SphereEx 效能測試團隊反饋的 SQL 不支援項,我們在 5.0.0-beta 版進行了針對性最佳化,目前已經全部支援。

針對社群反饋問題較多的 PostgreSQL,SQLServer 和 Oracle 等資料庫中的 SQL 支援度問題,ShardingSphere 社群透過核心團隊成員領導支援、社群同學大規模參與的方式進行提升。特別是在本次作為 Apache 優秀社群參加的 Google Summer Code 中,海外同學做出了較大貢獻。

SQL 居然還能在 Apache ShardingSphere 上實現這些功能?


SQL 居然還能在 Apache ShardingSphere 上實現這些功能?

在眾多社群貢獻者的努力之下,ShardingSphere 5.0.0-beta 版的 SQL 支援度取得了大幅度提升。為了打造更好的專案基石,我們會持續提升最佳化 SQL 支援度,期待有更多的貢獻者可以參與到這項工作中來,一起提升 SQL 支援度。

SQL 標準路由能力提升

在 SQL 支援度提升的基礎上,ShardingSphere 5.0.0-beta 版也對 SQL 路由邏輯進行了增強,重點最佳化了 DDL 語句 和 DQL 語句的路由邏輯。

在 5.0.0-beta 版最佳化 DDL 語句路由邏輯前,路由引擎只能處理 DDL 語句中單表的路由,對於包含多表的場景,路由處理並不是很完善。

以 ALTER TABLE 語句為例,假設 t_order 和 t_order_item 為分片表,並且未設定為繫結表關係。在最佳化前執行如下 SQL 會丟擲 Table t_order_item does not exist. 異常,路由邏輯只會針對 t_order 表進行路由,忽視了 t_order_item 表的資料分佈情況。

ALTER TABLE t_order ADD CONSTRAINT t_order_fk FOREIGN KEY (order_id) REFERENCES t_order_item (order_id);

想要支援 DDL 語句多表組合路由,需要考慮許多複雜的組合場景。按照 ShardingSphere 中對於表的分類,我們可以將表劃分為分片表(sharding table)、廣播表(broadcast table)和單表(single table),分片表又可以組成繫結表(binding table)。關於表的詳細概念可以參考下面的說明。

  • 分片表(sharding table):又叫邏輯表,水平拆分的資料庫(表)的相同邏輯和資料結構表的總稱。例:訂單資料根據主鍵尾數拆分為 10 張表,分別是 t_order_0 到 t_order_9,他們的邏輯表名為 t_order;

  • 繫結表(binding table):指分片規則一致的主表和子表。例如:t_order 表和 t_order_item 表,均按照 order_id 分片,則此兩張表互為繫結表關係;

  • 廣播表(broadcast table):指所有的分片資料來源中都存在的表,表結構和表中的資料在每個資料庫中均完全一致。適用於資料量不大且需要與海量資料的表進行關聯查詢的場景,例如:字典表;

  • 單表(single table):指所有的分片資料來源中只存在唯一一張的表。適用於資料量不大且不需要做任何分片操作的場景。

對於以上三種主要型別的表進行排列組合,可以得到如下 9 種組合場景:

針對這 9 種表的組合場景,ShardingSphere 5.0.0-beta 版對 ShardingTableBroadcastRoutingEngine 路由引擎進行了增強,完全支援分片表/廣播表和其他型別表的組合路由。當 SQL 語句中包含的表都為分片表,並且都是繫結表關係時,會按照原有主表驅動路由的方式進行處理。當 SQL 語句中包含的表都為分片表,但不是繫結表關係時,或者 SQL 語句中的部分表為分片表時,路由引擎會按照表所屬的資料來源先取交集,然後再對同資料來源的物理表計算笛卡爾積,得到最終的路由結果。

由於表的組合關係複雜,路由結果也存在多種情況。當分片表只配置了單個資料節點,並且分佈在同一資料來源時,DDL 語句多表組合的笛卡爾積路由結果是合法的,而當分片表配置了多個資料節點時,笛卡爾積路由結果往往是非法的。路由引擎需要能夠判斷出合法路由結果和非法路由結果,對於非法的路由結果,路由引擎需要丟擲合適的異常資訊。

為了保證使用者使用 ShardingSphere 的安全性,針對不支援的 SQL 或非法 SQL,ShardingSphere 引入了前置校驗(pre validate)和後置校驗(post validate)。前置校驗主要用於校驗 SQL 語句的基本資訊是否合法,如:表是否存在、索引是否存在、多個單表是否存在於同一個資料來源中。後置校驗主要用於校驗路由的結果是否合法,如:在 ALTER TABLE 語句中新增外來鍵約束時,我們認為所有的主表(primary table)都成功新增外來鍵約束為合法路由結果,否則將丟擲異常資訊。

對於 DQL 語句路由邏輯的最佳化,主要是針對跨資料庫例項 JOIN 及子查詢進行的。路由引擎在處理 DQL 語句時,如果當前語句中的表跨多個資料庫例項,則會使用 ShardingTableBroadcastRoutingEngine 路由引擎來處理。在下面一個部分,將會對 SQL 分散式查詢能力增強進行介紹。

SQL 分散式查詢能力增強

在 ShardingSphere 5.0.0-beta 版前,跨資料庫例項進行 JOIN 及子查詢一直是令使用者頭疼的問題。在同時使用多個資料庫例項時,業務研發人員需要時刻注意查詢 SQL 的使用範疇,儘量避免跨資料庫例項進行 JOIN 及子查詢,這使得業務層面的功能受到了資料庫限制。

在 ShardingSphere 5.0.0-beta 版中,藉助於 Apache Calcite 和 ShardingSphere 自身的解析、路由和執行能力,透過路由引擎進行判斷,將跨資料例項的分散式查詢 SQL,交由 Federate 執行引擎處理,完美支援了跨資料庫例項的 JOIN 及子查詢。

同時,針對 ShardingSphere 尚不支援的一些複雜查詢語句,我們也在最新的 master 分支進行了嘗試,使用 Federate 執行引擎進行處理,目前已經取得了良好的效果。例如:查詢語句使用 Having 過濾,子查詢使用聚合函式,多聚合函式組合查詢等語句,已經得到了支援,支援的 SQL 樣例如下。

SELECT user_id, SUM(order_id) FROM t_order GROUP BY user_id HAVING SUM(order_id) > 10; SELECT (SELECT MAX(user_id) FROM t_order) a, order_id FROM t_order; SELECT COUNT(DISTINCT user_id), SUM(order_id) FROM t_order;

ShardingSphere 最新 SQL 語句支援情況可以參考官方文件( https://shardingsphere.apache.org/document/current/cn/features/sharding/use-norms/sql/)。5.0.0-beta 版對於分散式查詢能力的增強是一個良好的開端,未來 ShardingSphere 將持續最佳化,不斷增強分散式查詢能力。

結語

Apache ShardingSphere 專案仍然在快速發展中,在後續的版本中,我們將持續提升各種資料庫的 SQL 支援度,不斷完善核心功能,努力為社群提供更多強大的功能,歡迎持續關注並積極參與社群任務,也歡迎點選“ 連結”下載使用。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70001955/viewspace-2779178/,如需轉載,請註明出處,否則將追究法律責任。

相關文章