本文将为您介绍半托管形态 EMR 的 Doris 集群的基本使用说明。
说明
EMR Serverless 实例的 Doris 集群的使用指导请参见:EMR Serverless 实例-Doris 最佳实践。更推荐您使用 EMR Serverless 实例,免运维、更省心。
Doris 兼容 MySQL 协议,可使用 MySQL Client 直接连接 FE 进行相关 SQL 操作。
说明
不同 EMR 版本中节点的域名命名方式可能不同,所以上方“emr-master-1主机名称”可参考 EMR 的域名规则做相应调整。
mysql -h 127.0.0.1 -P9030 -u root -p
SET PASSWORD FOR 'root' = PASSWORD('my_root_password');
后续可以使用有权限的用户创建子用户, 详细用户权限参考 开源文档
EMR Doris 完全兼容开源 Doris 语法,以下对基本的库表操作做一个示例,其他详细指南可以参考 开源Doris使用示例。
下文以 MySQL Client 方式为例, 进行样例 SQL 执行。
通过下面的命令创建一个普通用户:
CREATE USER 'test_user' IDENTIFIED BY 'test_user_passwd';
后续登录时即可通过如下连接命令登录:
mysql -h 127.0.0.1 -P9030 -u test_user -ptest_user_passwd
新创建的普通用户默认没有任何权限。
初始可通过 root用户创建数据库,命令如下:
CREATE DATABASE test_db;
数据库创建完成后,可以通过 SHOW DATABASES; 查看数据库信息。
MySQL> SHOW DATABASES; +--------------------+ | Database | +--------------------+ | example_db | | information_schema | +--------------------+ 3 rows in set (0.00 sec)
information_schema 是为了兼容 MySQL 协议而存在,实际中信息可能不是很准确,所以关于具体数据库的信息建议通过直接查询相应数据库而获得。
example_db 创建完成后,可通过 root 账户将 example_db 读写权限授权给之前创建的用户:test_user。授权后,即可通过 test_user 账户登录并操作 example_db 数据库。
-- 授权test_user在example_db的全部权限 GRANT ALL ON example_db TO test_user; -- 只授权test_user在example_db的SELECT在\权限 GRANT SELECT_PRIV ON example_db TO test_user;
此处及后面,您可以切换用户为:test_user账号来登录 Doris。
使用 CREATE TABLE 命令建立一个表(Table) ,更多详细参数访问 官网文档 查看详细信息。
切换数据库命令如下:
USE example_db;
Doris 支持单分区和复合分区两种建表方式。
下面以聚合模型为例,分别演示两种分区的建表语句。
建立一个名字为 table1 的逻辑表。分桶列为 siteid,桶数为 10。
这个表的 schema 如下:
字段名 | 说明 |
|---|---|
siteid | 类型是INT(4字节),默认值为10。 |
citycode | 类型是 SMALLINT(2字节)。 |
username | 类型是 VARCHAR,最大长度为32,默认值为空字符串。 |
pv | 类型是 BIGINT(8字节),默认值是0; |
建表语句如下:
CREATE TABLE table1 ( siteid INT DEFAULT '10', citycode SMALLINT, username VARCHAR(32) DEFAULT '', pv BIGINT SUM DEFAULT '0' ) AGGREGATE KEY(siteid, citycode, username) DISTRIBUTED BY HASH(siteid) BUCKETS 10
建立一个名字为 table2 的逻辑表。
这个表的 schema 如下:
字段名 | 说明 |
|---|---|
event_day | 类型是DATE,无默认值。 |
siteid | 类型是 INT(4字节),默认值为10。 |
citycode | 类型是 SMALLINT(2字节)。 |
username | 类型是 VARCHAR,最大长度为32,默认值为空字符串。 |
pv | 类型是BIGINT(8字节),默认值是0。 |
另外我们使用 event_day 列作为分区列,建立3个分区: p201706, p201707, p201708:
注意区间为左闭右开。
每个分区使用 siteid 进行哈希分桶,桶数为10
建表语句如下:
CREATE TABLE table2 ( event_day DATE, siteid INT DEFAULT '10', citycode SMALLINT, username VARCHAR(32) DEFAULT '', pv BIGINT SUM DEFAULT '0' ) AGGREGATE KEY(event_day, siteid, citycode, username) PARTITION BY RANGE(event_day) ( PARTITION p201706 VALUES LESS THAN ('2017-07-01'), PARTITION p201707 VALUES LESS THAN ('2017-08-01'), PARTITION p201708 VALUES LESS THAN ('2017-09-01') ) DISTRIBUTED BY HASH(siteid) BUCKETS 10 PROPERTIES("replication_num" = "1");
表建完之后,可以查看 example_db 中表的信息:
MySQL> SHOW TABLES; +----------------------+ | Tables_in_example_db | +----------------------+ | table1 | | table2 | +----------------------+ 2 rows in set (0.01 sec) MySQL> DESC table1; +----------+-------------+------+-------+---------+-------+ | Field | Type | Null | Key | Default | Extra | +----------+-------------+------+-------+---------+-------+ | siteid | int(11) | Yes | true | 10 | | | citycode | smallint(6) | Yes | true | N/A | | | username | varchar(32) | Yes | true | | | | pv | bigint(20) | Yes | false | 0 | SUM | +----------+-------------+------+-------+---------+-------+ 4 rows in set (0.00 sec) MySQL> DESC table2; +-----------+-------------+------+-------+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-----------+-------------+------+-------+---------+-------+ | event_day | date | Yes | true | N/A | | | siteid | int(11) | Yes | true | 10 | | | citycode | smallint(6) | Yes | true | N/A | | | username | varchar(32) | Yes | true | | | | pv | bigint(20) | Yes | false | 0 | SUM | +-----------+-------------+------+-------+---------+-------+ 5 rows in set (0.00 sec)
说明
关于 Insert 使用的更多详细语法及最佳实践,请参阅 Insert 命令手册。
Insert Into 语句的使用方式和 MySQL 等数据库中 Insert Into 语句的使用方式类似。但在 Doris 中,所有的数据写入都是一个独立的导入作业。所以这里将 Insert Into 也作为一种导入方式介绍。
主要的 Insert Into 命令包含以下两种;
Insert Into 命令需要通过 MySQL 协议提交,创建导入请求会同步返回导入结果。
语法参考:
INSERT INTO table_name [partition_info] [WITH LABEL label] [col_list] [query_stmt] [VALUES];
label 为用户指定的 label 或自动生成的 label。Label 是该 Insert Into 导入作业的标识。每个导入作业,都有一个在单 database 内部唯一的 Label。
示例:
INSERT INTO tbl2 WITH LABEL label1 SELECT * FROM tbl3; INSERT INTO tbl1 VALUES ("qweasdzxcqweasdzxc"),("a");
注意:
当需要使用 CTE(Common Table Expressions) 作为 insert 操作中的查询部分时,必须指定 WITH LABEL 和 column list 部分。示例
INSERT INTO tbl1 WITH LABEL label1 WITH cte1 AS (SELECT * FROM tbl1), cte2 AS (SELECT * FROM tbl2) SELECT k1 FROM cte1 JOIN cte2 WHERE cte1.k1 = 1; INSERT INTO tbl1 (k1) WITH cte1 AS (SELECT * FROM tbl1), cte2 AS (SELECT * FROM tbl2) SELECT k1 FROM cte1 JOIN cte2 WHERE cte1.k1 = 1;
Insert Into 本身就是一个 SQL 命令,其返回结果会根据执行结果的不同,分为以下几种:
ERROR 1064 (HY000),则表示导入失败。Query OK,则表示执行成功。
rows affected 为 0,表示结果集为空,没有数据被导入。rows affected大于 0:
status 为 committed,表示数据还不可见。需要通过 show transaction 语句查看状态直到 visiblestatus 为 visible,表示数据导入成功。warnings 大于 0,表示有数据被过滤,可以通过 show load 语句获取 url 查看被过滤的行。更多详细说明,请参阅 Insert 命令手册。
Doris 支持多种数据导入方式。这里我们使用流式导入 (Stream-Load) 和 Broker-Load 导入做示例。
1. Stream-Load
说明
关于 Stream-Load 使用的更多详细语法及最佳实践,请参阅 Stream-Load 命令手册。
流式导入通过 HTTP 协议向 Doris 传输数据,可以不依赖其他系统或组件直接导入本地数据。详细语法帮助可以参阅: HELP STREAM LOAD。
示例1:
以 "table1_20170707" 为 Label,使用本地文件 table1_data 导入 table1 表。
curl --location-trusted -u test:test_passwd -H "label:table1_20170707" -H "column_separator:," -T table1_data http://FE_HOST:8030/api/example_db/table1/_stream_load
本地文件 table1_data 以 , 作为数据之间的分隔,具体内容如下:
1,1,jim,2 2,1,grace,2 3,2,tom,2 4,3,bush,3 5,3,helen,3
示例2:
以 "table2_20170707" 为 Label,使用本地文件 table2_data 导入 table2 表。
curl --location-trusted -u test:test -H "label:table2_20170707" -H "column_separator:|" -T table2_data http://127.0.0.1:8030/api/example_db/table2/_stream_load
本地文件 table2_data 以 | 作为数据之间的分隔,具体内容如下:
2017-07-03|1|1|jim|2 2017-07-05|2|1|grace|2 2017-07-12|3|2|tom|2 2017-07-15|4|3|bush|3 2017-07-12|5|3|helen|3
注意
2. Broker-Load
Broker 导入通过部署的 Broker 进程,读取外部存储上的数据进行导入。
注意
关于 Broker Load 使用的更多详细语法及最佳实践,请参阅 Broker Load 命令手册,你也可以在 MySql 客户端命令行下输入:HELP BROKER LOAD 获取更多帮助信息。
示例:
以 "table1_20170708" 为 Label,将 HDFS 上的文件导入 table1 表
LOAD LABEL table1_20170708 ( DATA INFILE("hdfs://your.namenode.host:port/dir/table1_data") INTO TABLE table1 ) WITH BROKER hdfs ( "username"="hdfs_user", "password"="hdfs_password" );
Broker 导入是异步命令。以上命令执行成功只表示提交任务成功。导入是否成功需要通过 SHOW LOAD; 查看。如:
SHOW LOAD WHERE LABEL = "table1_20170708";
返回结果中,State 字段为 FINISHED 则表示导入成功。
关于 SHOW LOAD 的更多说明,可以参阅 HELP SHOW LOAD;
异步的导入任务在结束前可以取消:
CANCEL LOAD WHERE LABEL = "table1_20170708";
更详细信息可参与 社区文档
MySQL> SELECT * FROM table1 LIMIT 3; +--------+----------+----------+------+ | siteid | citycode | username | pv | +--------+----------+----------+------+ | 2 | 1 | 'grace' | 2 | | 5 | 3 | 'helen' | 3 | | 3 | 2 | 'tom' | 2 | +--------+----------+----------+------+ 3 rows in set (0.01 sec) MySQL> SELECT * FROM table1 ORDER BY citycode; +--------+----------+----------+------+ | siteid | citycode | username | pv | +--------+----------+----------+------+ | 2 | 1 | 'grace' | 2 | | 1 | 1 | 'jim' | 2 | | 3 | 2 | 'tom' | 2 | | 4 | 3 | 'bush' | 3 | | 5 | 3 | 'helen' | 3 | +--------+----------+----------+------+ 5 rows in set (0.01 sec)
MySQL> SELECT SUM(table1.pv) FROM table1 JOIN table2 WHERE table1.siteid = table2.siteid; +--------------------+ | sum(`table1`.`pv`) | +--------------------+ | 12 | +--------------------+ 1 row in set (0.20 sec)
MySQL> SELECT SUM(pv) FROM table2 WHERE siteid IN (SELECT siteid FROM table1 WHERE siteid > 2); +-----------+ | sum(`pv`) | +-----------+ | 8 | +-----------+ 1 row in set (0.13 sec)