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。