Apache Doris是一个现代化的MPP分析型数据库产品。仅需亚秒级响应时间即可获得查询结果,有效地支持实时数据分析。Apache Doris的分布式架构非常简洁,易于运维,并且可以支持10PB以上的超大数据集。
Apache Doris可以满足多种数据分析需求,例如固定历史报表,实时数据分析,交互式数据分析和探索式数据分析等。令您的数据分析工作更加简单高效!
-
dorisFE启动与停止:
./start_fe.sh --daemon ./stop_fe.sh --daemon
-
查看Fe状态:
SHOW PROC '/frontends';
-
dorisBE停止:
./start_be.sh --daemon /start_fe.sh --daemon
-
查看Be状态
SHOW PROC '/backends';
-
doris Broker启动与停止
./start_broker.sh --daemon ./stop_broker.sh --daemon
-
查看Broker状态:
SHOW PROC "/brokers";
-
增加、删除Fe节点:
-
FE 扩容注意事项:
- Follower FE(包括 Leader)的数量必须为奇数,建议最多部署 3 个组成高可用(HA)模式即可。
- 当 FE 处于高可用部署时(1个 Leader,2个 Follower),我们建议通过增加 Observer FE 来扩展 FE 的读服务能力。当然也可以继续增加 Follower FE,但几乎是不必要的。
- 通常一个 FE 节点可以应对 10-20 台 BE 节点。建议总的 FE 节点数量在 10 个以下。而通常 3 个即可满足绝大部分需求。
- helper 不能指向 FE 自身,必须指向一个或多个已存在并且正常运行中的 Master/Follower FE。
# 添加 Follower ALTER SYSTEM ADD FOLLOWER "follower_host:edit_log_port"; # 添加 Observer ALTER SYSTEM ADD OBSERVER "observer_host:edit_log_port"; # 其中 follower_host和observer_host 为 Follower 或 Observer 所在节点 ip,edit_log_port 在其配置文件 fe.conf 中。 # 配置及启动 Follower 或 Observer。Follower 和 Observer 的配置同 Leader 的配置。第一次启动时,需执行以下命令: # ./bin/start_fe.sh --helper leader_fe_host:edit_log_port --daemon # 删除 FE 节点 ALTER SYSTEM DROP FOLLOWER[OBSERVER] "fe_host:edit_log_port";
FE 缩容注意事项:
- 删除 Follower FE 时,确保最终剩余的 Follower(包括 Leader)节点为奇数。
-
增加、删除 BE 节点:
BE 扩容注意事项:
- BE 扩容后,Doris 会自动根据负载情况,进行数据均衡,期间不影响使用。
# 增加be ALTER SYSTEM ADD BACKEND "be_host:heartbeat-service_port"; # 删除 BE 节点 ALTER SYSTEM DECOMMISSION BACKEND "be_host:be_heartbeat_service_port";
-
增加、删除Broker节点:
# 增加 ALTER SYSTEM ADD BROKER broker_name "broker_host1:broker_ipc_port1","broker_host2:broker_ipc_port2",...; # 删除 ALTER SYSTEM DROP BROKER broker_name "broker_host:broker_ipc_port"; ALTER SYSTEM DROP ALL BROKER broker_name;
-
创建用户:
# 登录 mysql -h FE_HOST -P9030 -uroot
# 修改root密码: SET PASSWORD FOR 'root' = PASSWORD('your_password'); # 创建新用户 CREATE USER 'test' IDENTIFIED BY 'test_passwd'; # 账户授权 # example_db 创建完成之后,可以通过 root/admin 账户将 example_db 读写权限授权给普通账户,如 test。授权之后采用 test 账 # 户登录就可以操作 example_db 数据库了。 GRANT ALL ON example_db TO test;
-
创建数据库
CREATE DATABASE example_db; # 查看数据库 SHOW DATABASES;
所有命令都可以使用 ‘HELP command;’ 查看到详细的语法帮助。如:
HELP CREATE DATABASE;
如果不清楚命令的全名,可以使用 “help 命令某一字段” 进行模糊查询。如键入 ‘HELP CREATE’,可以匹配到
CREATE DATABASE
,CREATE TABLE
,CREATE USER
等命令。 -
创建数据库表
HELP CREATE TABLE; # 切换数据库 USE example_db; # 单分区建表 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 PROPERTIES("replication_num" = "1"); # 多分区建表 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"); # 动态分区建表 # 需要开启配置 dynamic_partition.enable = ture # 动态分区只支持 Range 分区。 # 动态分区调度的单位。可指定为 HOUR、DAY、WEEK、MONTH。分别表示按天、按星期、按月进行分区创建或删除。 dynamic_partition.time_unit 动态分区调度的单位。可指定为 HOUR、DAY、WEEK、MONTH。分别表示按天、按星期、按月进行分区创建或删除。 当指定为 HOUR 时,动态创建的分区名后缀格式为 yyyyMMddHH,例如2020032501。小时为单位的分区列数据类型不能为 DATE。 当指定为 DAY 时,动态创建的分区名后缀格式为 yyyyMMdd,例如20200325。 当指定为 WEEK 时,动态创建的分区名后缀格式为yyyy_ww。即当前日期属于这一年的第几周,例如 2020-03-25 创建的分区名后缀为 2020_13, 表明目前为2020年第13周。 当指定为 MONTH 时,动态创建的分区名后缀格式为 yyyyMM,例如 202003。 # 动态分区的时区,如果不填写,则默认为当前机器的系统的时区,例如 Asia/Shanghai,如果想获取当前支持的时区设置,可以参考 https://en.wikipedia.org/wiki/List_of_tz_database_time_zones。 dynamic_partition.time_zone # 动态分区的起始偏移,为负数。根据 time_unit 属性的不同,以当天(星期/月)为基准,分区范围在此偏移之前的分区将会被删除。如果不填写,则默认为 -2147483648,即不删除历史分区。 dynamic_partition.start # 动态分区的结束偏移,为正数。根据 time_unit 属性的不同,以当天(星期/月)为基准,提前创建对应范围的分区。 dynamic_partition.end # 动态创建的分区名前缀。 dynamic_partition.prefix # 动态创建的分区所对应的分桶数量 dynamic_partition.buckets # 动态创建的分区所对应的副本数量,如果不填写,则默认为该表创建时指定的副本数量。 dynamic_partition.replication_num # 当 time_unit 为 WEEK 时,该参数用于指定每周的起始点。取值为 1 到 7。其中 1 表示周一,7 表示周日。默认为 1,即表示每周以周一为起始点。 namic_partition.start_day_of_week # 当 time_unit 为 MONTH 时,该参数用于指定每月的起始日期。取值为 1 到 28。其中 1 表示每月1号,28 表示每月28号。默认为 1,即表示每月以1号位起始点。暂不支持以29、30、31号为起始日,以避免因闰年或闰月带来的歧义。 dynamic_partition.start_day_of_month # 默认为 false。当置为 true 时,Doris 会自动创建所有分区,具体创建规则见下文。同时,FE 的参数 max_dynamic_partition_num 会限制总分区数量,以避免一次性创建过多分区。当期望创建的分区个数大于 max_dynamic_partition_num 值时,操作将被禁止.当不指定 start 属性时,该参数不生效。 dynamic_partition.create_history_partition # 当 create_history_partition 为 true 时,该参数用于指定创建历史分区数量。默认值为 -1, 即未设置 dynamic_partition.history_partition_num # 指定最新的多少个分区为热分区。对于热分区,系统会自动设置其 storage_medium 参数为SSD,并且设置 storage_cooldown_time。 dynamic_partition.hot_partition_num # 往前 n 天和未来所有分区 hot_partition_num # 需要保留的历史分区的时间范围。当dynamic_partition.time_unit 设置为 "DAY/WEEK/MONTH" 时,需要以 [yyyy-MM-dd,yyyy-MM-dd],[...,...] 格式进行设置。当dynamic_partition.time_unit 设置为 "HOUR" 时,需要以 [yyyy-MM-dd HH:mm:ss,yyyy-MM-dd HH:mm:ss],[...,...] 的格式来进行设置。如果不设置,默认为 "NULL" dynamic_partition.reserved_history_periods # 表 tbl1 分区列 k1 类型为 DATE,创建一个动态分区规则。按天分区,只保留最近7天的分区,并且预先创建未来3天的分区。 CREATE TABLE tbl1 ( k1 DATE, ... ) PARTITION BY RANGE(k1) () DISTRIBUTED BY HASH(k1) PROPERTIES ( "dynamic_partition.enable" = "true", "dynamic_partition.time_unit" = "DAY", "dynamic_partition.start" = "-7", "dynamic_partition.end" = "3", "dynamic_partition.prefix" = "p", "dynamic_partition.buckets" = "32" ); # 表 tbl1 分区列 k1 类型为 DATETIME,创建一个动态分区规则。按星期分区,只保留最近2个星期的分区,并且预先创建未来2个星期的分区。 CREATE TABLE tbl1 ( k1 DATETIME, ... ) PARTITION BY RANGE(k1) () DISTRIBUTED BY HASH(k1) PROPERTIES ( "dynamic_partition.enable" = "true", "dynamic_partition.time_unit" = "WEEK", "dynamic_partition.start" = "-2", "dynamic_partition.end" = "2", "dynamic_partition.prefix" = "p", "dynamic_partition.buckets" = "8" ); # 表 tbl1 分区列 k1 类型为 DATE,创建一个动态分区规则。按月分区,不删除历史分区,并且预先创建未来2个月的分区。同时设定以每月3号为起始日。 CREATE TABLE tbl1 ( k1 DATE, ... ) PARTITION BY RANGE(k1) () DISTRIBUTED BY HASH(k1) PROPERTIES ( "dynamic_partition.enable" = "true", "dynamic_partition.time_unit" = "MONTH", "dynamic_partition.end" = "2", "dynamic_partition.prefix" = "p", "dynamic_partition.buckets" = "8", "dynamic_partition.start_day_of_month" = "3" ); # 修改动态分区属性 ALTER TABLE tbl1 SET ( "dynamic_partition.prop1" = "value1", ... ); # 查看动态分区表调度情况 # 通过以下命令可以进一步查看当前数据库下,所有动态分区表的调度情况: SHOW DYNAMIC PARTITION TABLES; # LastUpdateTime: 最后一次修改动态分区属性的时间 # LastSchedulerTime: 最后一次执行动态分区调度的时间 # State: 最后一次执行动态分区调度的状态 # LastCreatePartitionMsg: 最后一次执行动态添加分区调度的错误信息 # LastDropPartitionMsg: 最后一次执行动态删除分区调度的错误信息 +-----------+--------+----------+-------------+------+--------+---------+-----------+----------------+---------------------+--------+------------------------+----------------------+-------------------------+ | TableName | Enable | TimeUnit | Start | End | Prefix | Buckets | StartOf | LastUpdateTime | LastSchedulerTime | State | LastCreatePartitionMsg | LastDropPartitionMsg | ReservedHistoryPeriods | +-----------+--------+----------+-------------+------+--------+---------+-----------+----------------+---------------------+--------+------------------------+----------------------+-------------------------+ | d3 | true | WEEK | -3 | 3 | p | 1 | MONDAY | N/A | 2020-05-25 14:29:24 | NORMAL | N/A | N/A | [2021-12-01,2021-12-31] | | d5 | true | DAY | -7 | 3 | p | 32 | N/A | N/A | 2020-05-25 14:29:24 | NORMAL | N/A | N/A | NULL | | d4 | true | WEEK | -3 | 3 | p | 1 | WEDNESDAY | N/A | 2020-05-25 14:29:24 | NORMAL | N/A | N/A | NULL | | d6 | true | MONTH | -2147483648 | 2 | p | 8 | 3rd | N/A | 2020-05-25 14:29:24 | NORMAL | N/A | N/A | NULL | | d2 | true | DAY | -3 | 3 | p | 32 | N/A | N/A | 2020-05-25 14:29:24 | NORMAL | N/A | N/A | NULL | | d7 | true | MONTH | -2147483648 | 5 | p | 8 | 24th | N/A | 2020-05-25 14:29:24 | NORMAL | N/A | N/A | NULL | +-----------+--------+----------+-------------+------+--------+---------+-----------+----------------+---------------------+--------+------------------------+----------------------+-------------------------+ 7 rows in set (0.02 sec) # 动态分区线程的执行频率,默认为600(10分钟),即每10分钟进行一次调度。可以通过修改 fe.conf 中的参数并重启 FE 生效。也可以在运行时执行以下命令修改: dynamic_partition_check_interval_seconds = "7200"
-
表结构变更
# 新增一列 uv,类型为 BIGINT,聚合类型为 SUM,默认值为 0: ALTER TABLE table1 ADD COLUMN uv BIGINT SUM DEFAULT '0' after pv; # 查看作业进度,当作业状态为 FINISHED,则表示作业完成。新的 Schema 已生效。 SHOW ALTER TABLE COLUMN; # 查看最新的 Schema DESC table1; # 可以使用以下命令取消当前正在执行的作业: CANCEL ALTER TABLE COLUMN FROM table1; # 更多 HELP ALTER TABLE;
-
添加Rollup
Rollup 可以理解为 Table 的一个物化索引结构。物化 是因为其数据在物理上独立存储,而 索引 的意思是,Rollup可以调整列顺序以增加前缀索引的命中率,也可以减少key列以增加数据的聚合度。
# 对于 table1 明细数据是 siteid, citycode, username 三者构成一组 key,从而对 pv 字段进行聚合;如果业务方经常有看城市 pv # 总量的需求,可以建立一个只有 citycode, pv 的rollup。 ALTER TABLE table1 ADD ROLLUP rollup_city(citycode, pv); # 查看Rollup作业进度:当作业状态为 FINISHED,则表示作业完成。 SHOW ALTER TABLE ROLLUP; # 取消当前正在执行的作业: CANCEL ALTER TABLE ROLLUP FROM table1; # 查看表的 Rollup 信息 DESC table1 ALL; # 查看sql是否命中rollup EXPLAIN your_sql; # 更多 HELP ALTER TABLE;
-
数据表的查询
内存限制:
# 为了防止用户的一个查询可能因为消耗内存过大。查询进行了内存控制,一个查询任务,在单个 BE 节点上默认使用不超过 2GB 内存。 # 用户在使用时,如果发现报 Memory limit exceeded 错误,一般是超过内存限制了。 # 显示查询内存限制 SHOW VARIABLES LIKE "%mem_limit%"; +---------------+------------+ | Variable_name | Value | +---------------+------------+ | exec_mem_limit| 2147483648 | +---------------+------------+ 1 row in set (0.00 sec) # exec_mem_limit 的单位是 byte,可以通过 SET 命令改变 exec_mem_limit 的值。如改为 8GB。 SET exec_mem_limit = 8589934592; +---------------+------------+ | Variable_name | Value | +---------------+------------+ | exec_mem_limit| 8589934592 | +---------------+------------+ 1 row in set (0.00 sec) # 以上该修改为 session 级别,仅在当前连接 session 内有效。断开重连则会变回默认值。 # 如果需要修改全局变量,可以这样设置:`SET GLOBAL exec_mem_limit = 8589934592;`。设置完成后,断开 session 重新登录,参数将永久生效。
查询超时:
SHOW VARIABLES LIKE "%query_timeout%"; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | QUERY_TIMEOUT | 300 | +---------------+-------+ 1 row in set (0.00 sec) # 修改超时时间到1分钟: SET query_timeout = 60;
Broadcast/Shuffle Join:
系统提供了两种Join的实现方式,broadcast join和shuffle join(partitioned Join)。
broadcast join是指将小表进行条件过滤后,将其广播到大表所在的各个节点上,形成一个内存 Hash 表,然后流式读出大表的数据进行Hash Join。
shuffle join是指将小表和大表都按照 Join 的 key 进行 Hash,然后进行分布式的 Join。
当小表的数据量较小时,broadcast join拥有更好的性能。反之,则shuffle join拥有更好的性能。
系统会自动尝试进行 Broadcast Join,也可以显式指定每个join算子的实现方式。系统提供了可配置的参数
auto_broadcast_join_threshold
,指定使用broadcast join时,hash table使用的内存占整体执行内存比例的上限,取值范围为0到1,默认值为0.8。当系统计算hash table使用的内存会超过此限制时,会自动转换为使用shuffle join。当
auto_broadcast_join_threshold
被设置为小于等于0时,所有的join都将使用shuffle join。自动选择join方式(默认):
select sum(table1.pv) from table1 join table2 where table1.siteid = 2; +--------------------+ | sum(`table1`.`pv`) | +--------------------+ | 10 | +--------------------+ 1 row in set (0.20 sec) 使用 Broadcast Join(显式指定): select sum(table1.pv) from table1 join [broadcast] table2 where table1.siteid = 2; +--------------------+ | sum(`table1`.`pv`) | +--------------------+ | 10 | +--------------------+ 1 row in set (0.20 sec) 使用 Shuffle Join: select sum(table1.pv) from table1 join [shuffle] table2 where table1.siteid = 2; +--------------------+ | sum(`table1`.`pv`) | +--------------------+ | 10 | +--------------------+ 1 row in set (0.15 sec)