高级使用指南

这里我们介绍 Doris 的一些高级特性。

1 表结构变更

使用 ALTER TABLE 命令可以修改表的 Schema,包括如下修改:

  • 增加列
  • 删除列
  • 修改列类型
  • 改变列顺序

以下举例说明。

原表 table1 的 Schema 如下:

  1. +----------+-------------+------+-------+---------+-------+
  2. | Field | Type | Null | Key | Default | Extra |
  3. +----------+-------------+------+-------+---------+-------+
  4. | siteid | int(11) | No | true | 10 | |
  5. | citycode | smallint(6) | No | true | N/A | |
  6. | username | varchar(32) | No | true | | |
  7. | pv | bigint(20) | No | false | 0 | SUM |
  8. +----------+-------------+------+-------+---------+-------+

我们新增一列 uv,类型为 BIGINT,聚合类型为 SUM,默认值为 0:

ALTER TABLE table1 ADD COLUMN uv BIGINT SUM DEFAULT '0' after pv;

提交成功后,可以通过以下命令查看作业进度:

SHOW ALTER TABLE COLUMN;

当作业状态为 FINISHED,则表示作业完成。新的 Schema 已生效。

ALTER TABLE 完成之后, 可以通过 DESC TABLE 查看最新的 Schema。

  1. mysql> DESC table1;
  2. +----------+-------------+------+-------+---------+-------+
  3. | Field | Type | Null | Key | Default | Extra |
  4. +----------+-------------+------+-------+---------+-------+
  5. | siteid | int(11) | No | true | 10 | |
  6. | citycode | smallint(6) | No | true | N/A | |
  7. | username | varchar(32) | No | true | | |
  8. | pv | bigint(20) | No | false | 0 | SUM |
  9. | uv | bigint(20) | No | false | 0 | SUM |
  10. +----------+-------------+------+-------+---------+-------+
  11. 5 rows in set (0.00 sec)

可以使用以下命令取消当前正在执行的作业:

CANCEL ALTER TABLE COLUMN FROM table1

更多帮助,可以参阅 HELP ALTER TABLE

2 Rollup

Rollup 可以理解为 Table 的一个物化索引结构。物化 是因为其数据在物理上独立存储,而 索引 的意思是,Rollup可以调整列顺序以增加前缀索引的命中率,也可以减少key列以增加数据的聚合度。

以下举例说明。

原表table1的Schema如下:

  1. +----------+-------------+------+-------+---------+-------+
  2. | Field | Type | Null | Key | Default | Extra |
  3. +----------+-------------+------+-------+---------+-------+
  4. | siteid | int(11) | No | true | 10 | |
  5. | citycode | smallint(6) | No | true | N/A | |
  6. | username | varchar(32) | No | true | | |
  7. | pv | bigint(20) | No | false | 0 | SUM |
  8. | uv | bigint(20) | No | false | 0 | SUM |
  9. +----------+-------------+------+-------+---------+-------+

对于 table1 明细数据是 siteid, citycode, username 三者构成一组 key,从而对 pv 字段进行聚合;如果业务方经常有看城市 pv 总量的需求,可以建立一个只有 citycode, pv 的rollup。

ALTER TABLE table1 ADD ROLLUP rollup_city(citycode, pv);

提交成功后,可以通过以下命令查看作业进度:

SHOW ALTER TABLE ROLLUP;

当作业状态为 FINISHED,则表示作业完成。

Rollup 建立完成之后可以使用 DESC table1 ALL 查看表的 Rollup 信息。

  1. mysql> desc table1 all;
  2. +-------------+----------+-------------+------+-------+--------+-------+
  3. | IndexName | Field | Type | Null | Key | Default | Extra |
  4. +-------------+----------+-------------+------+-------+---------+-------+
  5. | table1 | siteid | int(11) | No | true | 10 | |
  6. | | citycode | smallint(6) | No | true | N/A | |
  7. | | username | varchar(32) | No | true | | |
  8. | | pv | bigint(20) | No | false | 0 | SUM |
  9. | | uv | bigint(20) | No | false | 0 | SUM |
  10. | | | | | | | |
  11. | rollup_city | citycode | smallint(6) | No | true | N/A | |
  12. | | pv | bigint(20) | No | false | 0 | SUM |
  13. +-------------+----------+-------------+------+-------+---------+-------+
  14. 8 rows in set (0.01 sec)

可以使用以下命令取消当前正在执行的作业:

CANCEL ALTER TABLE ROLLUP FROM table1;

Rollup 建立之后,查询不需要指定 Rollup 进行查询。还是指定原有表进行查询即可。程序会自动判断是否应该使用 Rollup。是否命中 Rollup可以通过 EXPLAIN your_sql; 命令进行查看。

更多帮助,可以参阅 HELP ALTER TABLE

2 数据表的查询

2.1 内存限制

为了防止用户的一个查询可能因为消耗内存过大。查询进行了内存控制,一个查询任务,在单个 BE 节点上默认使用不超过 2GB 内存。

用户在使用时,如果发现报 Memory limit exceeded 错误,一般是超过内存限制了。

遇到内存超限时,用户应该尽量通过优化自己的 sql 语句来解决。

如果确切发现2GB内存不能满足,可以手动设置内存参数。

显示查询内存限制:

  1. mysql> SHOW VARIABLES LIKE "%mem_limit%";
  2. +---------------+------------+
  3. | Variable_name | Value |
  4. +---------------+------------+
  5. | exec_mem_limit| 2147483648 |
  6. +---------------+------------+
  7. 1 row in set (0.00 sec)

exec_mem_limit 的单位是 byte,可以通过 SET 命令改变 exec_mem_limit 的值。如改为 8GB。

SET exec_mem_limit = 8589934592;

  1. mysql> SHOW VARIABLES LIKE "%mem_limit%";
  2. +---------------+------------+
  3. | Variable_name | Value |
  4. +---------------+------------+
  5. | exec_mem_limit| 8589934592 |
  6. +---------------+------------+
  7. 1 row in set (0.00 sec)
  • 以上该修改为 session 级别,仅在当前连接 session 内有效。断开重连则会变回默认值。
  • 如果需要修改全局变量,可以这样设置:SET GLOBAL exec_mem_limit = 8589934592;。设置完成后,断开 session 重新登录,参数将永久生效。

2.2 查询超时

当前默认查询时间设置为最长为 300 秒,如果一个查询在 300 秒内没有完成,则查询会被 Doris 系统 cancel 掉。用户可以通过这个参数来定制自己应用的超时时间,实现类似 wait(timeout) 的阻塞方式。

查看当前超时设置:

  1. mysql> SHOW VARIABLES LIKE "%query_timeout%";
  2. +---------------+-------+
  3. | Variable_name | Value |
  4. +---------------+-------+
  5. | QUERY_TIMEOUT | 300 |
  6. +---------------+-------+
  7. 1 row in set (0.00 sec)

修改超时时间到1分钟:

SET query_timeout = 60;

  • 当前超时的检查间隔为 5 秒,所以小于 5 秒的超时不会太准确。
  • 以上修改同样为 session 级别。可以通过 SET GLOBAL 修改全局有效。

2.3 Broadcast/Shuffle Join

系统默认实现 Join 的方式,是将小表进行条件过滤后,将其广播到大表所在的各个节点上,形成一个内存 Hash 表,然后流式读出大表的数据进行Hash Join。但是如果当小表过滤后的数据量无法放入内存的话,此时 Join 将无法完成,通常的报错应该是首先造成内存超限。

如果遇到上述情况,建议显式指定 Shuffle Join,也被称作 Partitioned Join。即将小表和大表都按照 Join 的 key 进行 Hash,然后进行分布式的 Join。这个对内存的消耗就会分摊到集群的所有计算节点上。

Doris会自动尝试进行 Broadcast Join,如果预估小表过大则会自动切换至 Shuffle Join。注意,如果此时显式指定了 Broadcast Join 也会自动切换至 Shuffle Join。

使用 Broadcast Join(默认):

  1. mysql> select sum(table1.pv) from table1 join table2 where table1.siteid = 2;
  2. +--------------------+
  3. | sum(`table1`.`pv`) |
  4. +--------------------+
  5. | 10 |
  6. +--------------------+
  7. 1 row in set (0.20 sec)

使用 Broadcast Join(显式指定):

  1. mysql> select sum(table1.pv) from table1 join [broadcast] table2 where table1.siteid = 2;
  2. +--------------------+
  3. | sum(`table1`.`pv`) |
  4. +--------------------+
  5. | 10 |
  6. +--------------------+
  7. 1 row in set (0.20 sec)

使用 Shuffle Join:

  1. mysql> select sum(table1.pv) from table1 join [shuffle] table2 where table1.siteid = 2;
  2. +--------------------+
  3. | sum(`table1`.`pv`) |
  4. +--------------------+
  5. | 10 |
  6. +--------------------+
  7. 1 row in set (0.15 sec)

2.4 查询重试和高可用

当部署多个 FE 节点时,用户可以在多个 FE 之上部署负载均衡层来实现 Doris 的高可用。

以下提供一些高可用的方案:

第一种

自己在应用层代码进行重试和负载均衡。比如发现一个连接挂掉,就自动在其他连接上进行重试。应用层代码重试需要应用自己配置多个doris前端节点地址。

第二种

如果使用 mysql jdbc connector 来连接Doris,可以使用 jdbc 的自动重试机制:

  1. jdbc:mysql://[host1][:port1],[host2][:port2][,[host3][:port3]]...[/[database]][?propertyName1=propertyValue1[&propertyName2=propertyValue2]...]

第三种

应用可以连接到和应用部署到同一机器上的 MySQL Proxy,通过配置 MySQL Proxy 的 Failover 和 Load Balance 功能来达到目的。

http://dev.mysql.com/doc/refman/5.6/en/mysql-proxy-using.html