SQL 能力全面加強,Apache ShardingSphere 5.0.0-beta 內核揭祕

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

本次 5.0.0-beta 版除了提供 DistSQL (後續將針對 DistSQL 進行深度解讀)這樣的新特性外,對 ShardingSphere 內核也進行了加強,主要體如今 SQL 基礎解析能力加強SQL 標準路由能力提高SQL 分佈式查詢能力加強這三方面。經過這三方面優化,不只進一步提升了對 MySQL,PostgreSQL,SQLServer 和 Oracle 數據庫的基礎 SQL 解析能力,並且大幅度提升了對用戶 SQL 的支持度,特別針對跨數據庫實例的關聯 SQL 進行了更有針對性的優化。本文將帶領你們一塊兒,探祕 5.0.0-beta 版內核加強特性。數據庫

本文是 ShardingSphere 5.0.0-beta 深度解讀系列文章第一篇,後續請你們多多關注!apache

做者:端正強數組

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 安全且高效地發送到底層數據源執行;post

  • 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 中,海外同窗作出了較大貢獻。

在衆多社區貢獻者的努力之下,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 支持度,不斷完善內核功能,努力爲社區提供更多強大的功能,歡迎持續關注並積極參與社區任務,同時歡迎點擊「連接」下載使用。

相關文章
相關標籤/搜索