第三代DRDS分散式SQL引擎全新發布

lyrewu發表於2018-05-25

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 = 0SET drds_transaction_policy = `flexible` 開啟柔性事務;然後在同一個會話中執行事務的 SQL 語句 —— 最後當應用發起 commitrollback 後,DRDS 將保證這些 SQL 語句執行的原子性:全部成功,或者全部失敗。

XA 事務

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 的 KILLSHOW PROCESSLISThttps://help.aliyun.com/document_detail/71372.html
  7. 支援 CREATE USER 建立更多使用者,並使用 GRANT 語句對使用者許可權進行授權:https://help.aliyun.com/document_detail/71356.html。
  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(阿里雲分散式關係型資料庫服務),詳情:https://www.aliyun.com/product/drds


相關文章