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

本文涉及的产品
云原生数据库 PolarDB 分布式版,标准版 2核8GB
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: DRDS (阿里云分布式关系型数据库服务,https://www.aliyun.com/product/drds)于 4 月 30 号发布了 5.3 版本,年度更新,具备众多新特性,欢迎品鉴。

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

相关实践学习
Polardb-x 弹性伸缩实验
本实验主要介绍如何对PolarDB-X进行手动收缩扩容,了解PolarDB-X 中各个节点的含义,以及如何对不同配置的PolarDB-x 进行压测。
目录
相关文章
|
3月前
|
SQL 存储 分布式计算
统一sql引擎Quicksql
统一sql引擎Quicksql
|
3月前
|
存储 边缘计算 人工智能
云计算与分布式系统架构:驱动数字化时代的创新引擎
本文将探讨云计算与分布式系统架构在数字化时代中的重要性,介绍其基本概念和原理,并探讨其在推动技术创新、提升企业效率和满足用户需求方面的作用。同时,还将提出未来发展的趋势和挑战,为读者提供对云计算与分布式系统架构的深入理解。
|
4月前
|
SQL 消息中间件 Apache
Apache Calcite—sql执行和解析引擎
Apache Calcite—sql执行和解析引擎
54 0
|
3月前
|
消息中间件 算法 Java
【亿级数据专题】「分布式消息引擎」 盘点本年度我们探索服务的保障容量的三大关键方案实现
尽管经过了上一篇文章 《【亿级数据专题】「分布式消息引擎」 盘点本年度我们探索服务的低延迟可用性机制方案实现》有了低延迟的优化保障,消息引擎仍需精心规划其容量。为了提供无与伦比的流畅体验,消息引擎必须实施有效的容量管理策略。
52 2
【亿级数据专题】「分布式消息引擎」 盘点本年度我们探索服务的保障容量的三大关键方案实现
|
2月前
|
消息中间件 存储 负载均衡
【亿级数据专题】「分布式消息引擎」 盘点本年度我们探索服务的HA高可用解决方案
昔之善战者,先为不可胜,以待敌之可胜。不可胜在己,可胜在敌。故善战者,能为不可胜,不能使敌之必可胜。故曰:胜可知,而不可为。
80 2
【亿级数据专题】「分布式消息引擎」 盘点本年度我们探索服务的HA高可用解决方案
|
3月前
|
消息中间件 存储 Java
【亿级数据专题】「分布式消息引擎」 盘点本年度我们探索服务的低延迟可用性机制方案实现
在充满挑战的2023年度,我们不可避免地面对了一系列棘手的问题,例如响应速度缓慢、系统陷入雪崩状态、用户遭受不佳的体验以及交易量的下滑。这些问题的出现,严重影响了我们的业务运行和用户满意度,为了应对这些问题,我们所在团队进行了大量的研究和实践,提出了低延迟高可用的解决方案,并在分布式存储领域广泛应用。
43 2
【亿级数据专题】「分布式消息引擎」 盘点本年度我们探索服务的低延迟可用性机制方案实现
|
1月前
|
SQL 分布式计算 HIVE
基于 Kyuubi 实现分布式 Flink SQL 网关
本文整理自网易互娱资深开发工程师、Apache Kyuubi Committer 林小铂的《基于 Kyuubi 实现分布式 Flink SQL 网关》分享。
104456 64
基于 Kyuubi 实现分布式 Flink SQL 网关
|
2月前
|
SQL 搜索推荐 数据库
分布式搜索引擎_学习笔记_3
分布式搜索引擎_学习笔记_3
20 1
|
4月前
|
SQL 分布式计算 Java
Note_Spark_Day08:Spark SQL(Dataset是什么、外部数据源、UDF定义和分布式SQL引擎)
Note_Spark_Day08:Spark SQL(Dataset是什么、外部数据源、UDF定义和分布式SQL引擎)
46 0
|
4月前
|
SQL 关系型数据库 MySQL
Presto【基础 01】简介+架构+数据源+数据模型+特点(一篇即可入门支持到PB字节的分布式SQL查询引擎Presto)
Presto【基础 01】简介+架构+数据源+数据模型+特点(一篇即可入门支持到PB字节的分布式SQL查询引擎Presto)
56 0