1 产品架构
分析型数据库MySQL版是基于MPP架构并融合了分布式检索技术的分布式实时计算系统,构建在飞天操作系统之上。分析型数据库MySQL版的主体部分主要由底层依赖、计算集群、控制集群和外围模块组成,具体如下图所示。
1.1 底层依赖
飞天操作系统:用于资源虚拟化隔离、数据持久化存储、构建数据结构和索引。
MetaStore:阿里云RDS关系数据库或阿里云表格存储,用于存储分析型数据库MySQL版的各类元数据(注意并不是实际参与计算用的数据)。
开源Apache ZooKeeper模块:用于对各个组件进行分布式协调。
1.2 计算集群
计算集群是计算资源实际包括的内容,均可进行横向扩展。计算集群运行在飞天操作系统上,通过在线资源调度模块来调度计算资源。计算集群包括:
- FRONTNODE:用于处理用户连接接入认证、鉴权,查询路由和分发路由,以及提供元数据查询管理服务。
- COMPUTENODE:用于进行实际的数据存储与计算 。
- BUFFERNODE:用于处理数据实时更新、数据缓冲和实时数据写入版本控制。
1.3 控制集群
控制集群(即资源管理器RM)用于控制计算集群中数据库资源分配、数据库内数据和计算资源的分布、飞天集群上的计算节点管理、数据库后台运行的任务管理等。控制集群实际上由多个模块组成,一个控制集群可以同时管理部署于不同机房的多套计算集群。
1.4 外围模块
外围模块主要包括:
- 阿里云负载均衡:用于管理FrontNode的分组和负载均衡。
- 阿里云DNS系统:用于发布数据库域名。
- 阿里云账号系统。
- 分析型数据库MySQL版控制台(Admin Console)。
- 用户控制台(DMS for Analytic DB)。
外围模块与外部系统交互如下图所示。
- 支持从MaxCompute批量导入数据,也支持快速批量导出海量数据到MaxCompute。
- 支持实时的将(D)RDS的数据同步到分析型数据库MySQL版中(需借助外部同步工具)。
- 支持从OSS批量导入数据,也支持快速批量导出海量数据到OSS。
分析型数据库MySQL版主要支持的客户端、驱动、编程语言和中间件如下:
- 客户端和驱动:支持MySQL 5.1/5.5/5.6系列协议的客户端和驱动,如MySQL 5.1.x jdbc driver、MySQL 5.3.x odbc connector(driver)、MySQL 5.1.x/5.5.x/5.6.x 客户端。
- 编程语言:JAVA、Python、C/C++、Node.js、PHP、R(RMySQL)。
- 中间件:Websphere Application Server 8.5、Apache Tomcat、JBoss。
2 事实表逻辑存储
ADB的事实表支持二级分区策略,一级分区采用 HASH 算法,二级分区采用 LIST 算法。通过二级分区策略,ADB可将表数据分布到不同的节点。
在 ADB中,事实表的逻辑存储示例图如下:
如上图所示,事实表按 ID 进行一级分区,并通过 CRC32 算法将不同 ID 值分布到不同的节点;按日期(bigint 类型)进行二级分区。二级分区可按天、周、月、年来划分。单个二级分区的数据记录数不可过小,如果按天划分二级分区,一个二级分区的数据量过小,则您可延长时间周期(例如:按周、月、年)来提高一个二级分区存储的数据量。建议每个二级分区的记录数维持在300万条到2000万条之间(如果只有一级分区数,则按每个一级分区计算)。
例如:某数据表有32个一级分区, 现在需要设计二级分区。如果每天有2000万新增数据(每个一级分区每天新增记录数:2000万/32 = 62万),则建议按周划分二级分区(每个二级分区的总记录数:62万*7天 = 434万)。如果每天有300万新增数据,则建议按月划分二级分区。
3 分区存储物理示意图
在ADB中,数据表的分区存储示意图如下:
- 图例中的数据库有 m 个 LocalNode ,LocalNode 即ADB的本地计算节点,又名 ComupteNode(简称 CN)。
- 图例中数据库包含一个二级分区数据表,表有 I 个一级分区(分区_0、分区_1…分区_I-2、分区_I-1),每个一级分区又包含90个二级分区,每个二级分区保存一天的数据,而且每个二级分区都保存了该表一天的所有列(col1、col2…coln)。
- 图例中每个 CN 存储 [n/m] 或 [n/m]+1 个一级分区。
在ADB中,设置一级分区的目的是将数据均匀分散到多个 CN 节点当中,以便充分发挥ADB分布式计算的能力。设置二级分区的目的是将数据分散到不同的存储文件上,与传统数据库的分区相似。
4 一级分区的规划和设计
4.1 一级分区列选择
基本原理:ADB的表一级分区采用 HASH 分区,可指定任意一列(不支持多列)作为分区列。HASH 分区通过标准 CRC 算法计算出 CRC 值,并将 CRC 值与分区数作模计算,得出每条记录的分区号。空值的 HASH 值与字符串-1的 HASH 值相同。
在ADB中,调度模块会将同一个表组下所有表的相同分区分配在同一个计算节点上。因此,当多表使用分区列进行 JOIN 时,单计算节点内部直接计算,避免跨机计算。
在ADB中,一级分区列的选择依据(按优先级从高到低排序)如下:
- 如果是多个事实表(不包括维度表)
JOIN
,则选择参与JOIN
的列作为分区列。如果是多列JOIN
,则根据查询重要程度或查询性能要求(例如:某 SQL 的查询频率特别高)来选择分区列,以保证基于分区列的 JOIN 具有较好的查询性能。 - 选择
GROUP BY
或DISTINCT
包含的列作为分区列。 - 选择值分布均匀的列作为分区列,请勿选择分区倾斜的列作为分区列。
- 如果常用的 SQL 包含某列的等值或
IN
查询条件,则选择该列作为分区列。
4.2 一级分区个数
基本原理:ADB的 LM 计算引擎是大部分查询所使用的计算引擎,它会在每个分区并行计算,每个分区计算使用一个线程
,分区计算结果汇总到 FRONTNODE 。因此,如果分区数过小,则会导致并发低、单查询 RT时间长;如果分区数过多,则会导致计算结果数过多、增加FRONTNODE压力,并且容易产生长尾效应。
实际进行一级分区时,您需要根据资源配置和查询特点,选择合适的分区数。一级分区个数选择依据如下:
注意一级分区数不可修改。如需修改,必须删表重建。
- 参与快速
JOIN
的所有事实表的分区数必须相同。 - 每个一级分区的数据记录数建议为300万条到2000万之间。如果有二级分区,则保证一级分区下的每个二级分区的记录数在300万条到2000万条之间。
- 一级分区数应该大于
ECU数量 * 6
,同时需要考虑到后续的扩容需求。例如:某数据库资源是8个 C8,则分区数需要大于8 * 6 = 48
。但分区数也要小于一定的值,实际分区时,也容易出现划分一级分区过多的情况,例如:两个 ECU 的情况下,设置了128个一级分区。 - 单表一级分区数最大值为256。如果需要设置成更大,请联系技术支持人员。
- 单计算节点的分区数(包括二级分区)不能超过10000。
注意
设置一级分区数时,除以上依据外,您还需要特别注意以下问题:
- 一级分区数过多,例如:某数据库只有8个节点,但表的一级分区设置为了256,此情况一般出现在开发环境中。实际划分一级分区时,您需要根据实际环境的节点个数来规划一级分区数。
- 一级分区数过小,例如:某数据库有32个节点,但一级分区数设置为了8。如果数据库中有一个超过一亿记录数的表,则表数据会集中在8节点上,容易导致这8个节点出现存储空间不足、查询慢等问题。
6 二级分区的规划和设计
一般情况下,每个一级分区下会包含多个二级分区。二级分区主要用于解决数据表需要按固定时间周期(例如:天、周、月、年)增加数据的问题,同时二级分区还考虑了保留一定时间范围的历史数据。
二级分区采用 LIST 分区,不同值的个数即为二级分区数。二级分区列是数据表中的一个 bigint 类型的列,通常为 bigint 类型的日期,例如:2017091210。
二级分区的语法形式如下:
SUBPARTITION BY LIST KEY (biz_date)
SUBPARTITION OPTIONS (available_partition_num = 30)
其中 biz_date 为二级分区列,是一个 bigint 类型的列,分区数为30个。
**二级分区适用场景:**一般情况下,当一级分区数据量随时间增大到超过单个一级分区记录数最佳推荐值(2000万~3000万)时,需要考虑设计二级分区。二级分区可以理解为按队列方式管理分区个数,当超过最大定义数,最小值分区自动删除,循环使用空间,所以二级分区支持自动清除历史数据。
在数据查询过程中,计算引擎能够根据查询条件自动筛选出满足条件的二级分区,并对每个符合条件的二级分区执行计算。在分析型数据库MySQL版中,每个二级分区作为独立查询单元,如果二级分区过多,则会导致多次索引查询、性能下降。每个二级分区均有独立的 meta,如果二级分区过多,则会占用更多的内存。如果二级分区过少,则用户导入数据的频率会降低,从而影响数据的实时性。实际划分二级分区时,您需要根据实际情况综合评估,以给出合理的二级分区更新间隔和保留个数。
**最佳实践:**单表二级分区数小于等于90,同时每个计算节点上总的二级分区个数不超过10 000个。每个一级分区下的二级分区包含的数据条数在300万到2000万之间。
一般情况下,如果单个分区每日增量数据超过300万,则推荐按天进行二级分区;如需要存储的时间范围更长,则可按周、月进行规划。
**二级分区调整:**分析型数据库MySQL版支持动态调整二级分区。当数据存储时间周期发生变化时,您需要动态调整二级分区个数,同时还需要调整二级分区的时间间隔(按日、周、月、年分区)。在调整二级分区个数和时间周期时,您需要同时考虑 SQL 查询的 WHERE 子句中二级分区条件的平滑过渡。
例如:设置二级分区字段(bigint 类型)存储的日期位数一致:yyyymmdd。查询条件:where pt between yyyymmdd and yyyymmdd;
。当您从按日分区改为按周(月或年)分区时,查询条件仍适用。二级分区的时间间隔示例如下:
- 按日分区:存储日期,例如:20180101、20180102、20180103、…
- 按周分区:存储每周一的日期,例如:20180101、20180108、20180115、…
- 按月分区:存储每月1号的日期,例如:20180101、20180201、20180301、…
- 按年分区:存储每年的1月1日,例如:20180101、20190101、20200101、…
7 二级分区与数据自动清除
在ADB中,二级分区采用 LIST 算法实现单节点数据的二次分表,最终实现大数据表存储容量的扩展。二级分区键采用 bigint 数据类型,键值一般采用业务数据对应的值,例如:按日存储,数据字段为data_time=2017-01-01
,则对应的二级分区键值为pt=20170101
。二级分区个数即 select count(distinct pt) from table_name;
的返回值。
二级分区支持自动清除历史数据。ADB内部会定期检查表的二级分区个数,当对表进行 optimize
(自动或手工方式)操作时,如果表的二级分区数超过设定的值,则按二级分区键值大小排序来删除最早的二级分区。
二级分区自动清除数据的示例如下:
在示例图中,表按日进行二级分区存储,二级分区数为90,存储90天的数据。当新增2017-04-01日期的数据时,自动扩展一个新二级分区20170401。当触发 optimize
操作时,根据二级分区键值的大小排序,如果 count(discint pt)> 90
,则删除最小的二级分区(历史分区20170101)。
注意在使用ADB的过程中,您必须防止垃圾数据自动清除有效数据。当误删有效数据时,请立即联系ADB的技术支持来恢复数据。
AanlyticDB 内部采用 LIST 算法来划分二级分区,会自动删除多余的分区。在某些情况下,业务数据异常或手工插入了新二级分区数据,会导致已有的分区被清空,从而出现严重数据问题。
例如:在某表中 insert
五条新的测试数据。
insert into table_name(.,....., pt) values(,,,,20300401);
insert into table_name(.,....., pt) values(,,,,20300402);
insert into table_name(.,....., pt) values(,,,,20300403);
insert into table_name(.,....., pt) values(,,,,20300404);
insert into table_name(.,....., pt) values(,,,,20300405);
insert
这五条新数据时,表的二级分区变化如下图所示。
insert
五条新数据时,表自动扩展出五个新的分区20300401~20300405。由于这五个新分区都是较大的值,当对表进行optimize
操作时,将自动删除20170101~20170105的这五个历史分区。
8 部分限制及实践
ADB当前版本存在一些使用限制,您需要进行合理的设计以规避这些限制。
数据表限制
当前ADB各限制项的上限数如下:
限制项 | 最大值 | 说明及实践 |
---|---|---|
一级分区数 | 256 | 记录数非常多的表,建议采用二级分区方案。 |
二级分区数 | 1000 | 建议小于90。查询二级分区表时,需要在 where 子句中增加二级分区条件。 |
单表最大列数 | 1024 | 超过1024列时,建议拆分为两个或者多个表。 |
varchar长度 | 8 KB | 超过8 KB 时,建议使用 clob 存储。 |
处理能力实践
单个ADB数据库的处理能力与所分配的资源数量有关。ADB具有良好的线性扩展能力,当可用资源不足时,您可以进行资源扩容,相关说明及实践如下:
- 实时表每日更新二级分区上限: 建议低于3,最大不超过30。对于需要更新历史二级分区数据的表,您需要设置合理的二级分区,以尽量减少每日更新的数据跨越过多的二级分区。在补录历史数据时,建议您分批次逐天进行补录。
- 表/分区单次导入最大数据量: 建议小于 ECU 个数 * diskSize * 0.2 ,其中 diskSize 为对应的 ECU 磁盘容量大小。
9 聚集列
的选择和设置
物理
顺序存储
在ADB中,数据存储支持按一列或多列进行排序(先按第一列排序,第一列相同情况下,使用第二列排序),以保证该列中值相同或相近的数据保存在磁盘同一位置,这样的列我们称之为聚集列。
当以聚集列为查询条件时,由于查询结果保存在磁盘同一位置,所以可以减少输入/输出I/O(Input/Output)次数。由于主聚集列只有一列,因此您需要选择最合适的列作为主聚集列。
选择依据
聚集列的选择依据如下:
- 主要或大多数的查询条件中均包括某一列,且该查询条件具有较高的筛选率,则选择该列作为聚集列。
- Join 子句中的等值条件列(通常是一级分区列)作为聚集列。
应用示例
现有一张数据表,其一级分区键和聚集列均为 org_code,示例如下。
说明您可以通过 DMS 管理工具修改表的聚集列。实时更新表修改后,新插入(INSERT)的数据在 optimize 后才会生效。
CREATE TABLE t_fact_mail_status (
mail_id varchar COMMENT '',
scan_timestamp timestamp COMMENT '',
biz_date bigint COMMENT '',
org_code varchar COMMENT '',
org_name varchar COMMENT '',
dlv_person_name varchar COMMENT '',
receiver_name varchar COMMENT '',
receiver_phone varchar COMMENT '',
receiver_addr varchar COMMENT '',
product_no varchar COMMENT '',
mag_no varchar COMMENT '',
PRIMARY KEY (mail_id,org_code,biz_date)
)
PARTITION BY HASH KEY (org_code) PARTITION NUM 128
SUBPARTITION BY LIST KEY (biz_date)
SUBPARTITION OPTIONS (available_partition_num = 30)
CLUSTERED BY (org_code)
TABLEGROUP ads_demo
OPTIONS (UPDATETYPE='realtime')
COMMENT '';
设置了 CLUSTERED BY(org_code)
后,org_code 记录会按一级分区规则分布在某一个计算节点 CN 上,并尽可能的存储在同一个数据块上。当以聚集列为查询条件时,相比与未设置聚集列的查询,如下 SQL 语句的访问 I/O 将减少数百倍。
select mail_id,biz_date,org_code,org_name
from t_fact_mail_status
where org_code='203202'
and bz_date=20171221;
假设共有10万个不同的 org_code,每个 org_code 每天有100条~5000条不等记录。如果 org_code = 203202 的记录为1000条,则按以上方案设置一级分区和聚集列后,这1000条记录会存储在连续的几个数据块上。当您通过以上 SQL 语句查询数据时,SQL 语句只需要扫描这几个数据块即可。
10 列类型选择
基本原理: 在ADB中,数值类型的处理性能远高于字符串类型,其原因如下:
- 数值类型的值定长、占用内存少、存储空间小。
- 数值类型计算更快,尤其是 JOIN 查询时。
因此,建议您在选择列的数据类型时尽可能使用数值类型,减少使用字符串类型。以下场景中,您可将字符串转换为数值类型:
- 包含字符前缀或后缀的字符串值(例如:E12345、E12346等),则可直接去掉前缀或将前缀映射为数字,。
- 某列只有少数几个字符串值(例如:国家名),则可对每个国家进行编码以使每个国家对应一个唯一数字。
- 对于时间/日期类型的数据,建议您尽量使用 date、timestamp 或 int 类型进行存储,避免使用varchar 类型。
对于地理经度、纬度,您需要采用 double 数据类型(因为地理函数要求经度、纬度为 double 数据类型)。
ADB中列支持的数据类型,以及与 MySQL 的差异如下:
ADB数据类型 | MySQL数据类型 | 差异 |
---|---|---|
boolean | bool、boolean | 一致 |
tinyint | tinyint | 一致 |
smallint | smallint | 一致 |
int | int、integer | 一致 |
bigint | bigint | 一致 |
float | float[(m,d)] | ADB不支持自定义 m和 d,MySQL 支持。 |
double | double[(m,d)] | ADB不支持自定义 m和 d,MySQL 支持。 |
varchar | varchar | 一致 |
date | date | 一致 |
timestamp | timestamp | ADB支持到精确到毫秒,MySQL 支持自定义。 |
multivalue | 不涉及 | ADB特有,MySQL 无此类型。 |
11 主键
在ADB中,实时更新表必须包含主键字段。实时更新表在插入/删除(INSERT/DELETE
)数据时,可通过主键来判断相同记录,以确定唯一记录。
主键组成: 业务 ID + 一级分区键 + 二级分区键
某些情况下,业务 ID 会与一级分区键相同。如果表记录数特别大,从存储空间和 INSERT
性能考虑,一定要减少主键的字段数。
12 表设计案例:物流快递
业务场景和要求
本例中简化的业务场景:实时监控和更新邮件包裹状态,包裹从订单、收单、装车、…、投递分为不同的状态。
业务要求:每个机构实时统计当前不同处理状态邮件数量。
业务性能要求:
- 实时统计新增数据,并且要求一秒以内返回结果(即 RT < 1s)。
- 查询并发量:QPS > 300 。
表的逻辑设计
邮件状态表(t_fact_mail_status)
要求:单日数据量约一亿记录;有15万机构或快递员,每个机构的邮件量为100到3000不等;存储30天的数据。
为满足高 QPS,从设计上采用大宽表、冗余字段,并且避免表关联。
字段名 | 字段类型 | 说明 |
---|---|---|
mail_id | varchar | 邮件订单唯一码 |
scan_timestamp | timestamp | 收件时间 |
biz_date | bigint | 日期(二级分区) |
org_code | varchar | 机构编码 |
org_name | varchar | 机构名称 |
dlv_person_name | varchar | 投递员名称 |
receiver_name | varchar | 收件人名 |
receiver_phone | varchar | 收件人电话 |
receiver_addr | varchar | 收件人地址 |
product_no | varchar | 产品编码 |
mag_no | varchar | 包裹编号 |
op_1_timestamp | bigint | 状态1操作时间 |
op_2_timestamp | bigint | 状态2操作时间 |
op_3_timestamp | bigint | 状态3操作时间 |
op_4_timestamp | bigint | 状态4操作时间 |
op_5_timestamp | bigint | 状态5操作时间 |
表的物理设计
创建邮件状态表 t_fact_mail_status ,需要规划表的一级分区、二级分区,需要考虑业务查询主要按机构进行查询,QPS 要求高。综上所述, 我们选择按 org_code 进行一级分区。
CREATE TABLE t_fact_mail_status (
mail_id varchar COMMENT '',
scan_timestamp timestamp COMMENT '',
biz_date bigint COMMENT '',
org_code varchar COMMENT '',
org_name varchar COMMENT '',
dlv_person_name varchar COMMENT '',
receiver_name varchar COMMENT '',
receiver_phone varchar COMMENT '',
receiver_addr varchar COMMENT '',
product_no varchar COMMENT '',
mag_no varchar COMMENT '',
op_1_timestamp bigint COMMENT '',
op_2_timestamp bigint COMMENT '',
op_3_timestamp bigint COMMENT '',
op_4_timestamp bigint COMMENT '',
op_5_timestamp bigint COMMENT '',
PRIMARY KEY (mail_id,org_code,biz_date)
)
PARTITION BY HASH KEY (org_code) PARTITION NUM 128
SUBPARTITION BY LIST KEY (biz_date)
SUBPARTITION OPTIONS (available_partition_num = 30)
TABLEGROUP ads_demo
OPTIONS (UPDATETYPE='realtime')
COMMENT '';
查询SQL
要求:查询当天某机构号、不同状态的邮件数据量,核查需要操作的邮件量,要求 RT < 1s 并且高 QPS。
综上所述,我们必须利用分区裁剪,以使单个查询在不同的节点上运行。SQL 语句示例如下:
select sum(case when t.op_1_timestamp >= 20171128000000 and t.op_1_timestamp <= 20171128235900
and(( t.op_2_timestamp is null or t.op_2_timestamp > 20171128235900 or t.op_2_timestamp < 20171128000000)
and( t.op_3_timestamp is null or t.op_3_timestamp > 20171128235900 or t.op_3_timestamp < 20171128000000)
and( t.op_4_timestamp is null or t.op_4_timestamp > 20171128235900 or t.op_4_timestamp < 20171128000000))
then 1 else 0 end ) as cn
from t_fact_mail_status t
where t.org_code = '21111101' and t.biz_date = 20171128;
13 优化
optimize table
在ADB中查询数据时,提前进行 optimize table
操作,可提升查询性能。
在ADB中,optimize table
是对实时写入的数据进行索引构建,并生成高度优化的文件结构的过程。
分析型数据库MySQL版只为实时写入的数据建立了简单的索引,但optimize table
后,则会建立相对复杂、功能更强、性能更佳的索引。所以在适当时候进行 optimize table
是提升查询性能的好方法。
目前ADB提供两种optimize table
方式:
- 自动
optimize table
:ADB每天会自动进行一次optimize table
操作,一般在每晚20:00开始。 - 手动
optimize table
:分析型数据库MySQL版提供了optimize
命令,用户可以手动强制进行optimize table
操作, 命令格式如下:
optimize table tabname;
Hint(待整理)
概述
企业版312支持为 SQL 指定 Hint 来执行特定的优化指令。
分析型数据库MySQL版支持的 Hint 如下:
- 强制使用 LM 计算引擎 :
/*+engine=COMPUTENODE*/ SELECT ...
- 强制使用 MPP 计算引擎:
/*+engine=MPP*/ SELECT ...
/*+no-index=[b.aa2]*/ SELECT a1, a2, COUNT(DISTINCT a3) rs
FROM a JOIN b ON a.a1 = b.a1 AND b.a4 IN ('110', '120') AND a.aa3 = 1003
AND b.aa2 <= 201503 GROUP BY a1, a2;
/*+no-cache=[colname]*/ SELECT ...
- 多个 Hint 组合:
/*+engine=COMPUTENODE,
batchio=true,
no-index=[tabname.capture_time],
blockcache=false,prefetch-step=4*/
no-index
在 SQL 查询中,如果您不想对某些列使用索引,则可通过no-index
来指定这些列。
当查询语句中有一个或两个条件筛选率非常低时,这将导致索引装载时间很长,此时去掉这些条件的索引可提高查询效率。no-index 一般用于有多个 WHERE 过滤条件的查询中。
在使用 no-index 时,建议您先进行 SQL 语句的性能对比测试,以确保使用 no-index 的 SQL 语句查询性能更高。查询条件值由客户端应用赋值时,某些情况下您必须使用索引,不可使用no-index ,否则查询语句会以顺序扫描的方式进行查询,当记录数特别大时,顺序扫描的性能极低。
SQL 示例:
SELECT a1, a2, count(distict a3) rs
FROM a JOIN b ON a.a1 = b.a1
where b.a4 IN ('110', '120') AND a.aa3 = 1003 AND b.aa2 <= 201503
GROUP BY a1, a2;
本例中 aa2 筛选率很差,增加 no-index Hint 可提高查询性能,示例如下:
/*+no-index=[b.aa2]*/
SELECT a1, a2, COUNT(DISTINCT a3) rs
FROM a JOIN b ON a.a1 = b.a1
where b.a4 IN ('110', '120') AND a.aa3 = 1003 AND b.aa2 <= 201803
GROUP BY a1, a2;
no-cache
在 SQL 查询中,如果有某些列不适合进入缓存,则您可通过 no-cache
Hint 指定这些列不入缓存。
no-cache 语法:
/*+no-cache=[colname]*/ SELECT ...
计算引擎
本节介绍ADB支持的 Local-Merge(简称 LM)和 Full MPP Mode(简称 MPP)计算引擎,以及如何管理 MPP 查询任务。
分析型数据库MySQL版支持以下两套计算引擎:
计算引擎 | 描述 |
---|---|
LM | LM 是原有计算引擎,计算性能好、并发能力强,但不支持部分跨一级分区列的计算。 强制使用 LM:/+engine=COMPUTENODE/ SELECT … |
MPP | MPP 是新增的计算引擎,计算功能全面,支持跨一级分区列的计算。 MPP 计算引擎拥有较丰富的数学函数、字符串处理函数、窗口函数等支持。 MPP 的计算性能和计算并发能力不如 LM 。 强制使用 MPP:/+engine=MPP/ SELECT … |
当开启 MPP 引擎时,分析型数据库MySQL版自动对查询(Query)进行路由,并将 LM 引擎不支持的查询路由到 MPP 引擎,以兼顾分析型数据库MySQL版的性能和通用性。目前有以下几种情况支持自动路由到 MPP 引擎。
函数类型 | 函数 |
---|---|
特定函数 | 如 ROW_NUMBER OVER 等,LM 模式不识别,捕获异常。 |
JOIN类 | 事实表 JOIN 事实表,JOIN KEY 全部在非分区列上。 不同表组的事实表 JOIN 事实表。 维度表在前,LETF JOIN 事实表。维度表在前,RIGHT JOIN 事实表。 事实表 JOIN 事实表,一级分区数不同。 |
GROUP BY、ORDER BY、HAVING类 | GROUP BY 仅含非分区列,外层套子查询。 GROUP BY 仅含非分区列,包括 ORDER BY。 GROUP BY 仅含非分区列,包括 HAVING。 |
其他 | UNION/INTERSECT/MINUS 不含分区列。 SELECT 复杂表达式,如 SUM/SUM,任何带聚合函数的计算表达式等。 COUNT DISTINCT 或 DISTINCT 非分区列。 |
MPP 查询任务管理
分析型数据库MySQL版有多个 FRONTNODE 实例节点,您可通过以下命令管理各 FRONTNODE 实例上运行的 MPP 查询任务。
如果想查询目前连接的 FRONTNODE 实例上运行 MPP 查询任务,可运行如下命令:
SHOW PROCESSLIST MPP
如果想查询跨 FRONTNODE 所有实例上正在运行的 MPP 查询任务,可运行如下命令:
/*+cross-frontnode=true*/SHOW PROCESSLIST MPP
每个 MPP 查询任务均有一个 Query ID,您可通过该 Query ID 来终止该 MPP 查询任务。您可通过 SHOW PROCESSLIST MPP
查看 MPP 查询任务的 Query ID。
如果想终止该 MPP 查询任务,可运行如下命令:
/*+cross-frontnode=true*/KILL MPP '$query_id'
如果想终止当前连接的 FRONTNODE 实例上正在运行的所有 MPP 查询任务,可运行如下命令:
KILL MPP ALL
如果想终止跨 FRONTNODE 所有实例上正在运行的所有 MPP 查询任务,可运行如下命令:
/*+cross-frontnode=true*/KILL MPP ALL
14 资源评估与ECU
14.1 概述
本节主要介绍需要从哪些维度进行专有云资源评估。
在新建ADB数据库前,您需要从数据量QPS(Query per Second)和性能 RT(Response Time)两个维度对数据库所要占用的资源进行评估,以给ADB数据库分配最合理的资源量。
数据量 QPS 评估:
ADB分为高性能和大存储两种机型,对单个物理机器的存储规格如下:
- 高性能模型:1 TB/物理机器。
- 大存储:10 TB/物理机器。
说明物理机型的规格不同,存储容量也不同。
性能 RT 评估:
对实际业务的数据量、查询 SQL 复杂度等进行压力测试,从而进行资源评估。如果业务要求高 QPS,则推荐高性能资源模型,同时要求单个 SQL 的 RT 时间小。
14.2 ECU
弹性计算单元 ECU(Elastic Computing Unit)是ADB中存储和计算资源最基本的分配单位。
ECU 定义了计算节点 ComputeNode(简称 CN)、接入节点 FrontNode(简称 FN)、缓存节点 BufferNode(简称 BN) 的 CPU 资源、内存、网络带宽、磁盘大小,以及 CN 与 FN、BN 的比例关系。
- CN:用于存储用户数据和进行计算。
- FN:用于接收用户的应用前端接入等工作。
- BN:用于实时数据的写入缓冲。
创建ADB数据库时,选择的是 ECU 型号和 CN 的数量,系统会根据 ECU 型号按内部设定的比例自动配备相应数量的 FN 和 BN。不同的 ECU 型号,其 CPU 核数、内存大小、磁盘空间大小也不同。ECU 的初始数量必须是偶数,至少两个,按偶数增加。ECU 的数量可以在使用中随时调整(扩容/缩容)。
ECU 主要对外展示的配置是 CN 的内存和磁盘。
- 内存容量:该 ECU 的内存大小。
- 磁盘容量:该 ECU 的磁盘容量。一个数据库中存储的物理数据总量不能超过该数据库全部的磁盘容量。
说明ADB存储数据时会将数据分布到每一个ECU中,如果数据倾斜导致单个ECU的磁盘空间占满,那么整个ADB也将无法再写入数据。ECU的磁盘使用情况可以在云监控中查看。
专有云系统中,ECU 要求网络必须是万兆网络。当前ADB提供的 ECU 的规格如ECU 规格所示。
ECU 规格
型号 | 内存 | SSD磁盘容量 | SATA磁盘容量 |
---|---|---|---|
c1 | 7.5GB | 60GB | N/A |
c8 | 45GB | 480GB | N/A |
s1 | 25GB | 250GB | 1536GB |
s8 | 60GB | 600GB | 6000GB |
高性能和大存储实例说明如下:
- 高性能实例:ECU 型号为 c 字母开头,在线计算全本地 SSD,高IOPS(高并发)、高 IO 吞吐、低延迟(RT 低),但存储成本高。高性能实例适用于并发量大,并且要求低延迟的业务场景。
- 大存储实例:ECU 型号为 s 字母开头,本地 SSD 缓存 + 远程 SATA ,IOPS 和 IO 吞吐均不如高性能实例,但存储成本低。大存储实例适用于海量历史库、无复杂计算并且以简单查询为主的场景。
您可以通过 DMS For AnalyticDB 界面的扩容/缩容功能,或相应 DDL 动态修改 ECU 数量,详细信息请参见扩容和缩容。
14.3 资源评估方法
本节介绍专有云中ADB的资源评估方法,包括资源评估维度、问卷调查、ECU 类型选择。同时本节还给出了一个资源评估的示例,以便您能更好的理解资源评估方法。
资源评估维度
资源评估的目的是选择正确的 ECU 类型以及数量,以确在保客户的业务得到满意支撑的同时,以最低的成本获取最优的性能。资源评估主要从以下维度进行考量:
- 磁盘 :考量数据量大小。
- 内存 :考量查询的并发度与复杂度。
- CPU :考量查询的并发度与复杂度。
问卷调查
为了能够有效的进行评估,必须先对以下问题进行问卷调查,以确认答案:
- 数据库总数据量大小?每日增量数据是多少?数据保留多久?
- 数据库最大的表有多少数据量?列宽是多少?预计多大?
- 数据库的查询并发度的峰值预计有多少?
- 数据库的典型性查询是什么?最复杂的查询是什么?单表查询占比多少?
- 数据库的每日写入数据量是多少?
ECU 类型选择
从存储角度评估:
如果ADB的数据量在百亿以上,物理机器在100台以上,则可以考虑选择大存储模式。但如果查询性能要求较高,则建议选择高性能模式。
从计算性能角度评估:
资源评估示例
从存储的角度进行评估是最常用的方法:
-
实例一: 客户数据库预计大小1 TB。
ECU 计算公式:c8 ECU 个数 >= (1024GB * 2(副本数) ) / ( 480GB(ECU) * 70% ) = 6 -
实例二: 客户数据库预计大小 100 TB。
ECU 计算公式:s8 ECU 个数 >= (100TB * 2(副本数) ) / ( 4TB(ECU) * 70% ) = 72 -
实例三: 客户数据库预计每日新增实时数据10亿条记录:
ECU 计算公式:ECU 个数 >= (20亿条记录 ) / ( 2亿条记录 ) = 10
说明
- 每个 CN 每日新增实时数据默认限制不得超过2亿条记录。
- 每个 CN 每日新增实时数据量默认限制不得超过100 GB。
计算资源估算:
计算资源(CPU、内存、网络带宽)是一个难以估算的值。估算计算资源时,您必须明确SQL 类型、查询并发和基准数据量,并且RT基线必须以 1/N 数据进行实测,然后再线性放大的方式进行评估,但内存有时不能线性计算。
依据QPS评估计算能力:
QPS 需要根据客户环境进行压力测试。不同的 SQL 业务场景(数据量、SQL复杂度),其 QPS 也不同,所以您需要根据实际业务场景进行并发 QPS 测试。考虑到测试环境的资源和生产环境存在差异,您可按线性比例对数据量规模和 QPS 进行测试。例如:假设16个节点(测试环境)支持 m TB 的数据量、QPS = 50,则64个节点时,您可按4倍进行扩展。