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 语句执行的原子性:全部成功,或者全部失败。

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 的 KILL 与 SHOW 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

第三代DRDS分布式SQL引擎全新发布的更多相关文章

  1. DRDS分布式SQL引擎—执行计划介绍

    摘要: 本文着重介绍 DRDS 执行计划中各个操作符的含义,以便用户通过查询计划了解 SQL 执行流程,从而有针对性的调优 SQL. DRDS分布式SQL引擎 — 执行计划介绍 前言 数据库系统中,执 ...

  2. Spark 分布式SQL引擎

    SparkSQL作为分布式查询引擎:两种方式 SparkSQL作为分布式查询引擎:Thrift JDBC/ODBC服务 SparkSQL作为分布式查询引擎:Thrift JDBC/ODBC服务 Spa ...

  3. Spark SQL概念学习系列之分布式SQL引擎

    不多说,直接上干货! parkSQL作为分布式查询引擎:两种方式 除了在Spark程序里使用Spark SQL,我们也可以把Spark SQL当作一个分布式查询引擎来使用,有以下两种使用方式: 1.T ...

  4. 重磅开源 KSQL:用于 Apache Kafka 的流数据 SQL 引擎 2017.8.29

    Kafka 的作者 Neha Narkhede 在 Confluent 上发表了一篇博文,介绍了Kafka 新引入的KSQL 引擎——一个基于流的SQL.推出KSQL 是为了降低流式处理的门槛,为处理 ...

  5. 探究Presto SQL引擎(4)-统计计数

    作者:vivo互联网用户运营开发团队 -  Shuai Guangying 本篇文章介绍了统计计数的基本原理以及Presto的实现思路,精确统计和近似统计的细节及各种优缺点,并给出了统计计数在具体业务 ...

  6. Presto: 可以处理PB级别数据的分布式SQL查询引擎

    2012年秋季Facebook启动了Presto,Presto的目的是在几百PB级别数据量上面进行准实时分析.在摒弃了一些外部项目以后,Facebook准备开发他们自己的分布式查询引擎.Presto的 ...

  7. 六大主流开源SQL引擎

    导读 本文涵盖了6个开源领导者:Hive.Impala.Spark SQL.Drill.HAWQ 以及Presto,还加上Calcite.Kylin.Phoenix.Tajo 和Trafodion.以 ...

  8. 六大主流开源SQL引擎总结

    本文涵盖了6个开源领导者:Hive.Impala.Spark SQL.Drill.HAWQ 以及Presto,还加上Calcite.Kylin.Phoenix.Tajo 和Trafodion.以及2个 ...

  9. 6大主流开源SQL引擎总结,遥遥领先的是谁?

    根据 O’Reilly 2016年数据科学薪资调查显示,SQL 是数据科学领域使用最广泛的语言.大部分项目都需要一些SQL 操作,甚至有一些只需要SQL.本文就带你来了解这些主流的开源SQL引擎!背景 ...

随机推荐

  1. Vue知识整理1:$watch方法的使用

    如下图所示:vue中,可以使用$watch方法显示变量的前面值和当前值,方便进行判断.使用方法: vm.$watch('a',function(newval,oldval){ ...... })

  2. numpy多维数组

    1 多维数组的切片用法 c = np.array([[[0,1,2],[4,5,6],[8,7,5],[10,11,12]],[[6,2,3],[9,8,34],[100,101,102],[110, ...

  3. c# thread4——lock,死锁,以及monitor关键字

    多线程的存在是提高系统效率,挖掘cpu性能的一种手段,那么控制它,能够协同多个线程不发生bug是关键. 首先我们来看一段不安全的多线程代码. public abstract class Calcula ...

  4. Java ——数组 选择排序 冒泡排序

    本节重点思维导图 数组 public static void main(String[] args) { int a ; a=3; int[] b; b = new int[3];//强制开辟内存空间 ...

  5. Python笔记(二十七)_魔法方法_容器

    定制容器 容器类型的协议: 定制不可变容器,只需要定义__len__()和__getitem__()方法 定制可变容器,需要定义__len__().__getitem__().__setitem__( ...

  6. ETROBOT——审题

    参加了比赛,但是总要理解比赛相关的东西,发现以前瞎写的东西有人看,并且还有挺多人看的,所以打算继续在这里面,做记录. 源: http://www.etrobo.jp/2018/gaiyou/intro ...

  7. SSM003/构建Maven单模块项目(二)

    一.Controller基础代码(mooc) 1.UserController.java /** *springmvc1-2:返回jsp页面 * 请求URL: /user/getUserById?us ...

  8. python中pycharm中.py文件调用一个.py文件的函数

    在相同文件夹内调用函数: file1.py def add(x,y): print('和为:%d'%(x+y)) file2.py import A A.add(1,2)

  9. Varint数值压缩存储方法

    coming from http://www.cnblogs.com/smark/archive/2012/05/03/2480034.html 在编写网络通讯的时候我们经常需要把一些数据存储到byt ...

  10. RESUful风格

    1.7 RESTful风格 1.7.1 RESTful风格介绍 RESTful是一种软件架构风格! RESTful架构风格规定,数据的元操作,即CRUD(create, read, update和de ...