DRDS (阿里雲分佈式關係型數據庫服務,https://www.aliyun.com/product/drds)於 4 月 30 號發佈了 5.3 版本,這是一個年度大更新。主要帶來了如下特性:html
DRDS 5.3,使用了 Plan Cache、協程、FastSQL 等技術,大幅提高了吞吐量,在同規格下,最大 QPS 提高到了以前的 300%。
例如,對於以前的版本,8C16G 的 DRDS 最大能夠提供 2W/s 的 QPS;對於 DRDS 5.3,8C16G 的 DRDS 最大能夠提供 6W+/s 的 QPS。java
1.實例規格爲入門版 8C16G
2.測試工具爲 sysbench
3.後端 RDS 不存在瓶頸
4.測試 SQL:單表拆分鍵上的等值查詢node
SELECT * FROM t1 WHERE partition_key=?
5.持續加大併發,直至 DRDS CPU 接近 100%,而且 rt 在5ms左右mysql
DRDS 5.3 中,引入了 Plan Cache,大幅下降了 SQL 解析與查詢優化的代價。DRDS 5.3 中,針對不一樣類型的 SQL,分紅了多級 Plan Cache,其中,性能最高的是命中了一級 Plan Cache 的 SQL。不管參數取值如何,必定能夠被下推到單分片執行的 SQL 會命中一級 Plan Cache,常見的形式有如下幾種:git
1.單表拆分鍵上的等值查詢,例如:github
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.拆分鍵上的等值關聯子查詢,而且其中內表或者外表帶了拆分鍵上的等值條件,例如:sql
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% 左右。後端
DRDS 5.3 中的 Parser 部分,換成了從 Druid(https://github.com/alibaba/druid)剝離出來的 FastSQL。相對於老的 Parser,FastSQL 在 SQL 解析方面,比 antlr、javacc 等自動生成的 Parser 快了數十倍至數百倍,相對 DRDS 老版本的 Parser 帶來了一倍的性能提高。FastSQL 近期會開源。
DRDS 5.3 提供原生的分佈式事務功能,有如下特色:
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 在提交與回滾階段始終加鎖,避免了事務結束前的髒讀和覆蓋,可是對性能有較大影響。
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=?
FORCE INDEX
爲特定的 SQL 指定須要選擇的索引:CREATE OUTLINE O2 ON SELECT * FROM T1 WHERE ID=? TO SELECT * FROM T1 FORCE INDEX(index_xxx) WHERE ID=?
CREATE OUTLINE O3 ON SELECT * FROM T1 WHERE ID=? TO SELECT /*+TDDL:node('0')*/ * FROM T1 WHERE ID=?
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
SQL 兼容性方面,DRDS 5.3 最大的特色在於明確了 SQL 的邊界,也即可以明確的說明哪些 SQL 支持、哪些 SQL 不支持。
DRDS 5.3 SQL 邊界文檔:https://help.aliyun.com/document_detail/71252.html。
一些重要的 SQL 類型:
KILL
與 SHOW PROCESSLIST
:https://help.aliyun.com/document_detail/71372.html。CREATE USER
建立更多用戶,並使用 GRANT
語句對用戶權限進行受權:https://help.aliyun.com/document_detail/71356.html。經過執行計劃能夠清晰的判斷出:
例如,針對如下 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)
LogicalView
算子):SELECT name
, COUNT(*) AS count(*)
FROM drds
GROUP BY name
ORDER BY name
。name
進行排序。因爲每一個分片上已經完成了 Order By 操做,所以分佈式層須要對各個分片的數據作歸併排序(MergeSort
算子)。Aggregate
算子)。MemSort
算子)。Project
算子)。更多關於 DRDS 5.3 執行計劃的介紹,請關注後續的文章。
歡迎你們持續關注 DRDS(阿里雲分佈式關係型數據庫服務),詳情:https://www.aliyun.com/product/drds。