天天看點

第三代DRDS分布式SQL引擎全新釋出 1. 性能 2. 原生分布式事務 3. Outline 4. SQL 支援 5. Optimizer 與執行計劃 What's NEXT

DRDS (阿裡雲分布式關系型資料庫服務, https://www.aliyun.com/product/drds )于 4 月 30 号釋出了 5.3 版本,這是一個年度大更新。主要帶來了以下特性:

  1. 性能提升 。在大多數場景下(拆分鍵上的等值查詢、讀寫分離等),同規格的吞吐量(最大 QPS)可以提升到之前的 300%
  2. 原生分布式事務 。無需額外付費或者開通,不依賴第三方元件,即可執行分布式事務。提供柔性事務與 XA 兩種實作。
  3. Outline 。在無需改動程式的情況下,即可通過建立 Outline 的形式改變 SQL 的執行計劃,例如指定索引、指定走主庫或者備庫等。
  4. 明确的 SQL 邊界文檔 。在 SQL 邊界内,進行了大量的随機測試,確定功能的穩定可靠。
  5. 更強大的分布式查詢優化器 。確定分布式 SQL 執行代價的最小化。
  6. 簡潔易讀的執行計劃 。提供一種新的執行計劃顯示格式,可以非常友善的看出 SQL 的執行政策。

1. 性能

DRDS 5.3,使用了 Plan Cache、協程、FastSQL 等技術,大幅提升了吞吐量,在同規格下,

最大 QPS 提升到了之前的 300%

例如,對于之前的版本,8C16G 的 DRDS 最大可以提供 2W/s 的 QPS;對于 DRDS 5.3,8C16G 的 DRDS 最大可以提供 6W+/s 的 QPS。

測試場景:

1.執行個體規格為入門版 8C16G

2.測試工具為 sysbench

3.後端 RDS 不存在瓶頸

4.測試 SQL:單表拆分鍵上的等值查詢

SELECT * FROM t1 WHERE partition_key=?           

5.持續加大并發,直至 DRDS CPU 接近 100%,并且 rt 在5ms左右

Plan Cache

DRDS 5.3 中,引入了 Plan Cache,大幅降低了 SQL 解析與查詢優化的代價。DRDS 5.3 中,針對不同類型的 SQL,分成了多級 Plan Cache,其中,性能最高的是命中了一級 Plan Cache 的 SQL。無論參數取值如何,一定可以被下推到單分片執行的 SQL 會命中一級 Plan Cache,常見的形式有以下幾種:

1.單表拆分鍵上的等值查詢,例如:

SELECT * FROM t1 WHERE partition_key=?           

2.拆分鍵上的等值 JOIN 查詢,并且至少其中一個表帶了拆分鍵上的等值條件,例如:

SELECT * FROM t1 JOIN t2 ON t1.partition_key = t2.partition_key WHERE t1.partition_key=?           

3.拆分鍵上的等值關聯子查詢,并且其中内表或者外表帶了拆分鍵上的等值條件,例如:

SELECT * FROM t1 WHERE EXSITS (SELECT 1 FROM t2 WHERE t1.partition_key = t2.partition_key) AND t1.partition_key=?           

在應用中,更多的使用能夠命中一級 Plan Cache 的 SQL,能更高的提升系統容量。

協程

DRDS 5.3 使用了 AliJDK 的 Wisp 協程。在業務邏輯相同的情況下,使用協程模型與使用線程模型相比,系統容量提升了 30% 左右。

更快的 Parser:FastSQL

DRDS 5.3 中的 Parser 部分,換成了從 Druid(

https://github.com/alibaba/druid

)剝離出來的 FastSQL。相對于老的 Parser,FastSQL 在 SQL 解析方面,比 antlr、javacc 等自動生成的 Parser 快了數十倍至數百倍,相對 DRDS 老版本的 Parser 帶來了一倍的性能提升。FastSQL 近期會開源。

2. 原生分布式事務

DRDS 5.3 提供原生的分布式事務功能,有以下特點:

  1. 提供 柔性事務 XA 事務 兩種事務方案供使用者在不同的場景下進行選擇。
  2. 不依賴任何第三方元件,能力內建在 DRDS Server 中,專有雲無需額外資源進行部署。
  3. 無熱點情況下性能線性可擴,無單點瓶頸。
  4. 無需額外開通,公有雲上購買的執行個體即可立即使用,不産生額外費用。

DRDS 5.3 提供柔性事務和 XA 事務兩種方案,一般情況下,當 DRDS 後端的 MySQL 為 5.7 及以上版本時,推薦使用 XA 事務。

DRDS 5.3 提供的最終一緻方式執行的分布式事務稱為柔性事務(Flexible Transactions)。

柔性事務放棄了隔離性,減小了事務中鎖的粒度,使得應用能夠更好的利用資料庫的并發性能,實作吞吐量的線性擴充。異步執行方式可以更好的适應分布式環境,在網絡抖動、節點故障的情況下能夠盡量保障服務的可用性(Availability)。

DRDS 5.3 中開啟柔性事務隻需要一行代碼:

SET drds_transaction_policy = 'flexible';

SHOW VARIABLES LIKE 'drds_transaction_policy'; 
+-------------------------+----------+
| VARIABLE_NAME           | VALUE    |
+-------------------------+----------+
| drds_transaction_policy | FLEXIBLE |
+-------------------------+----------+
1 row in set (0.07 sec)           

除此之外,DRDS 柔性事務的使用方法和普通事務完全相同:應用首先用

SET autocommit = 0

SET drds_transaction_policy = 'flexible'

開啟柔性事務;然後在同一個會話中執行事務的 SQL 語句 —— 最後當應用發起

commit

rollback

後,DRDS 将保證這些 SQL 語句執行的原子性:全部成功,或者全部失敗。

DRDS 5.3 也支援 XA 事務,在柔性事務的基礎上提供了強一緻能力。由于 MySQL XA 實作機制的限制,我們要求隻有在 DRDS 後端是 MySQL 5.7 版本以上才啟用 XA 事務功能。

SET drds_transaction_policy = 'XA';

SHOW VARIABLES LIKE 'drds_transaction_policy'; 
+-------------------------+-------+
| VARIABLE_NAME           | VALUE |
+-------------------------+-------+
| drds_transaction_policy | XA    |
+-------------------------+-------+
1 row in set (0.07 sec)           

DRDS XA 事務使用兩階段送出協定(XA Protocol)保護子事務的送出與復原,消除了柔性事務的異步復原問題。由于 XA Protocol 在送出與復原階段始終加鎖,避免了事務結束前的髒讀和覆寫,但是對性能有較大影響。

3. Outline

DRDS 5.3 提供 Outline 機制,允許使用者在不修改程式與 SQL 的情況下,對特定類型的 SQL 的行為進行定制。簡單說,Outline 可以将一個類型的源 SQL 在執行時動态的替換成另一個目标 SQL,目标 SQL 中可以帶一些 HINT。

一些典型的應用場景:

  • 使用

    SLAVE HINT

    将特定的SQL路由到隻讀執行個體執行:
CREATE OUTLINE O1 ON SELECT * FROM T1 WHERE ID=? TO SELECT /*+TDDL:SLAVE()*/ * FROM T1 WHERE ID=?               
  • 使用 MySQL 原生的

    FORCE INDEX

    為特定的 SQL 指定需要選擇的索引:
CREATE OUTLINE O2 ON SELECT * FROM T1 WHERE ID=? TO SELECT * FROM T1 FORCE INDEX(index_xxx) WHERE ID=?           
  • 使用 DRDS 的 HINT 将特定的 SQL 路由到指定分片上執行:
CREATE OUTLINE O3 ON SELECT * FROM T1 WHERE ID=? TO SELECT /*+TDDL:node('0')*/ * FROM T1 WHERE ID=?           
  • DRDS 中的 Outline,可以對參數化的 SQL 進行比對,也可以對特定參數的 SQL 進行比對。例如,對于 SQL:
SELECT * FROM T1 WHERE ID=?           

當 ID 取 1 時,需求到隻讀執行個體執行;當 ID 取其他值時,需求到主執行個體執行,則可以建立以下兩個 Outline:

CREATE OUTLINE O1 ON SELECT * FROM T1 WHERE ID=1 TO SELECT /*+TDDL:SLAVE()*/ * FROM T1 WHERE ID=1;
CREATE OUTLINE O2 ON SELECT * FROM T1 WHERE ID=? TO SELECT /*+TDDL:MASTER()*/ * FROM T1 WHERE ID=?;           

DRDS 會優先比對帶具體參數的 Outline。

DRDS Outline 的詳細說明:

https://help.aliyun.com/document_detail/71254.html

DRDS Hint 說明:

https://help.aliyun.com/document_detail/71287.html

4. SQL 支援

SQL 相容性方面,DRDS 5.3 最大的特點在于明确了 SQL 的邊界,也即能夠明确的說明哪些 SQL 支援、哪些 SQL 不支援。

DRDS 5.3 SQL 邊界文檔:

https://help.aliyun.com/document_detail/71252.html

一些重要的 SQL 類型:

  1. 子要查詢方面,支援 Correlated Subqueries(不要求關聯項一定是拆分鍵)、Derived Tables,暫不支援列子查詢。更多子查詢的支援範圍參考: https://help.aliyun.com/document_detail/71295.html
  2. 支援分布式 JOIN(不要求一定要帶拆分鍵,不要求必須是拆分鍵上的 JOIN),暫不支援 STRAIGHT_JOIN 和 NATURAL JOIN。
  3. 支援大部分 MySQL 函數,主要暫不支援的為:全文檢索函數、XML 函數、空間分析函數與 JSON 函數。
  4. UPDATE/DELETE 語句僅支援單表操作,不支援 UPDATE/DELETE 中包含 JOIN 以及子查詢。
  5. 聚合函數支援 COUNT/SUM/MAX/MIN/AVG,GROUP BY 不要求FULL_GROUP_BY( https://dev.mysql.com/doc/refman/8.0/en/sql-mode.html#sqlmode_only_full_group_by )。
  6. 支援邏輯 SQL 的

    KILL

    SHOW PROCESSLIST

    https://help.aliyun.com/document_detail/71372.html
  7. 支援

    CREATE USER

    建立更多使用者,并使用

    GRANT

    語句對使用者權限進行授權: https://help.aliyun.com/document_detail/71356.htm l。
  8. 支援 PREPARE 協定、多語句與壓縮協定。

5. Optimizer 與執行計劃

DRDS 5.3 中,提供了非常豐富的分布式 SQL 優化政策,一些重要的例如:

  1. 對 Filter 的上拉、下壓、推導等優化,確定 DRDS 可以準确的識别出 SQL 中可以下推的部分,這個能很大程度上提升 JOIN、子查詢的性能,避免應該能下推卻無法下推帶來的性能損耗。
  2. 子查詢的 SEMI-JOIN 優化。DRDS中,子查詢會被改寫為 SEMI-JOIN 進行優化,進而使其能夠複用大量針對的 JOIN 的優化政策,提升性能和功能穩定性。
  3. 提供了一系列 Hint,允許調整執行計劃的任意一個節點,結合 Outline 機制,達到不更改 SQL 也能對 SQL 進行性能優化的目的。
  4. 針對不同的場景,對排序與 Limit 進行優化,確定能将排序與 Limit 盡可能多的下推到存儲節點上,保證傳輸的資料量最小。

DRDS 5.3 設計了全新的執行計劃顯示格式,相對老版本,具有以下特征:

  1. 收縮了分片的顯示,執行計劃不會因為涉及多個分片而臃腫龐大。
  2. 執行計劃中包含了完整的執行政策,不存在二義性。
  3. 執行計劃使用了标準的算子的語義,易于将标準的資料庫知識應用到 DRDS 的查詢優化中。
  4. 執行計劃中将同時包含分布式執行計劃以及存儲分片上的執行計劃(此特性 6 月份上線)。
  5. 提供 Optimizer Tracing 功能,能一步一步的展示出執行計劃的優化過程,友善進行 SQL 調優。
  6. 通過執行計劃可以清晰的判斷出:
    • SQL 需要在哪些分片上執行,是否跨分片
    • JOIN、子查詢、聚合、排序等操作是否能夠下推
    • JOIN、排序等所使用的算法是什麼

例如,針對以下 SQL 的執行計劃:

mysql> explain SELECT count(*), name FROM drds GROUP BY name ORDER BY count(*);
+-----------------------------------------------------------------------------------------------------------------------------------------------------------+
| LOGICAL PLAN                                                                                                                                              |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------+
| Project(count(*)="count(*)", name="name")                                                                                                                 |
|   MemSort(sort="count(*) ASC")                                                                                                                            |
|     Aggregate(group="name", count(*)="SUM(count(*))")                                                                                                     |
|       MergeSort(sort="name ASC")                                                                                                                          |
|         LogicalView(tables="[00-03].drds", shardCount=4, sql="SELECT `name`, COUNT(*) AS `count(*)` FROM `drds` GROUP BY `name` ORDER BY `name`")         |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------+
5 rows in set (0.13 sec)           

從此執行計劃中,我們可以獲得以下資訊:

  1. 需要在 00-03 供 4 個分片上執行實體 SQL (

    LogicalView

    算子):SELECT

    name

    , COUNT(*) AS

    count(*)

    FROM

    drds

    GROUP BY

    name

    ORDER BY

    name

  2. Group By 操作基于排序實作,需要對

    name

    進行排序。由于每個分片上已經完成了 Order By 操作,是以分布式層需要對各個分片的資料做歸并排序(

    MergeSort

    算子)。
  3. 每個分組内,對 COUNT(*) 的結果做 SUM 操作,以彙總每個分片 COUNT(*) 的結果(

    Aggregate

  4. 使用記憶體排序,對 Aggregate 節點輸出的 count(*) 進行排序(

    MemSort

  5. 最終結果集輸出的是 count(*) 與 name 兩列(

    Project

更多關于 DRDS 5.3 執行計劃的介紹,請關注後續的文章。

What's NEXT

6 月底,DRDS 将釋出 5.3.2,将會提供以下特性:

  1. 帶計算能力的 DRDS 隻讀執行個體。可以直接在RDS主執行個體或者隻讀執行個體上,進行最高可提供 READ COMMITTED 級别的複雜 SQL(例如千萬級的表的 JOIN 等)執行能力,并且随規格的提升,響應時間能進行近線性的擴充。
  2. 資源回收筒,可對 DROP TABLE 操作進行閃回,友善在誤删表的場景下快速對資料進行恢複。
  3. 基于事務的廣播表寫入。廣播表将不再依賴任何第三方元件,可自行建立使用。
  4. 跨執行個體、機房、單元依然能保證全局唯一的主鍵服務。

歡迎大家持續關注 DRDS(阿裡雲分布式關系型資料庫服務),詳情: