之前叫百度palo,2018年共享到apache社区,改名doris
亚秒级响应
架构非常简洁,易于运维
支持10pb以上的超大数据集
固定历史报表
实时数据分析
交互式数据分析
探索式数据分析
流批一体架构
doris架构设计简单,只设有FE(Frontend)、BE(Backend)两种角色、两个进程,不依赖于外部组件,方便部署和运维,FE、BE都可线形拓展。
存储、维护集群元数据;负责接收、解析查询请求,规划查询计划,调度查询执行,返回查询结果。三种角色:
(1)Leader和Follower:主要是用来达到元数据的高可用,保证单节点宕机的情况下,元数据能够实时的在线回复,而不影响整个服务。
(2)Observer:用来扩展查询节点,同时起到元数据备份的作用。如果在发现集群压力非常大的情况下,需要扩展整个查询的能力,那么可以加observer的节点。observer不参与任何的写入,只参与读取。
负责物理数据的存储和计算;依据FE生成的物理计划,分布式的执行查询。
数据的可靠性由BE保证,BE会对整个数据存储多副本或者三副本。副本数可根据需求动态调整。
Doris借助Mysql协议,用户使用任意MySQL的ODBC/JDBC以及MySQL的酷户端,可以直接访问Doris。
Broker为一个独立的无状态进程。封装了文件系统接口,提供Doris读取远端存储系统中文件的能力,例如HDFS,S3
mysql -h -u -p -P9030
create user 'test' identified by 'test'
create database test_db;
grant all on test_db to test;
在doris中,数据都以关系表(Table) 的形式进行逻辑上的描述。
一张表包含Row和Column。Row是用户一行数据。Column用于描述一行数据中不同的字段。
1)在默认的数据模型中,Column只分为排序列和非排序列。存储引擎会按照排序列对数据进行排序存储,并建立稀疏索引,以便在排序数据上进行快速查找。
2)而在聚合模型中,Column可以分为两大类:Key和Value。从业务角度看,Key和Value可以分别对应维度列和指标列。从聚合模型角度来说,key列相同的行聚合成一行。其中Value列的聚合方式由用户在建表时指定。
在 Doris 的存储引擎中,用户数据首先被划分成若干个分区(Partition),划分的规则通 常是按照用户指定的分区列进行范围划分,比如按时间划分。而在每个分区内,数据被进一 步的按照 Hash 的方式分桶,分桶的规则是要找用户指定的分桶列的值进行 Hash 后分桶。 每个分桶就是一个数据分片(Tablet),也是数据划分的最小逻辑单元。
1)Tablet 之间的数据是没有交集的,独立存储的。Tablet 也是数据移动、复制等操作 的最小物理存储单元。
2)Partition 可以视为是逻辑上最小的管理单元。数据的导入与删除,都可以或仅能针 对一个 Partition 进行。
使用 CREATE TABLE 命令建立一个表(Table)。更多详细参数可以查看:
HELP CREATE TABLE;
建表语法:
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] [database.]table_name
(column_definition1[, column_definition2, ...]
[, index_definition1[, index_definition12,]])
[ENGINE = [olap|mysql|broker|hive]]
[key_desc]
[COMMENT "table comment"];
[partition_desc]
[distribution_desc]
[rollup_index]
[PROPERTIES ("key"="value", ...)]
[BROKER PROPERTIES ("key"="value", ...)];
Doris 的建表是一个同步命令,命令返回成功,即表示建表成功。
Doris 支持支持单分区和复合分区两种建表方式。
1) 复合分区:既有分区也有分桶
第一级称为 Partition,即分区。用户可以指定某一维度列作为分区列(当前只支持整型和时间类型的列),并指定每个分区的取值范围。
第二级称为 Distribution,即分桶。用户可以指定一个或多个维度列以及桶数对数据进行 HASH 分布。
字段名 | 内存 | 范围 |
---|---|---|
TINYINT | 1 字节 | 范围:-2^7 + 1 ~ 2^7 - 1 |
SMALLINT | 2 字节 | 范围:-2^15 + 1 ~ 2^15 - 1 |
INT | 4 字节 | 范围:-2^31 + 1 ~ 2^31 - 1 |
BIGINT | 8 字节 | 范围:-2^63 + 1 ~ 2^63 - 1 |
LARGEINT | 16 字节 | 范围:-2^127 + 1 ~ 2^127 - 1 |
FLOAT | 4 字节 | 支持科学计数法 |
DOUBLE | 12 字节 | 支持科学计数法 |
DECIMAL[(precision, scale)] | 16 字节 | 保证精度的小数类型。默认是DECIMAL(10, 0),precision: 1 ~ 27,scale: 0 ~ 9,其中整数部分为 1 ~ 18不支持科学计数法 |
DATE | 3 字节 | 范围:0000-01-01 ~ 9999-12-31 |
DATETIME | 8 字节 | 范围:0000-01-01 00:00:00 ~ 9999-12-31 23:59:59 |
CHAR[(length)] | 定长字符串。长度范围:1 ~ 255。默认为 1 | |
VARCHAR[(length)] | 变长字符串。长度范围:1 ~ 65533 | |
BOOLEAN | 与 TINYINT 一样,0 代表 false,1 代表 true | |
HLL | 1~16385 个字节 | hll 列类型,不需要指定长度和默认值、长度根据数据的聚合程度系统内控制,并且 HLL 列只能通过 配 套 的 hll_union_agg 、Hll_cardinality、hll_hash 进行查询或使用 |
BITMAP | bitmap 列类型,不需要指定长度和默认值。表示整型的集合,元素最大支持到 2^64 - 1 | |
STRING | 变长字符串,0.15 版本支持,最大支持 2147483643 字节(2GB-4),长度还受 be 配置string_type_soft_limit ,实际能存储的最大长度取两者最小值。只能用在 value 列,不能用在 key列和分区、分桶列 |
注:聚合模型在定义字段类型后,可以指定字段的 agg_type 聚合类型,如果不指定,则该列为 key 列。否则,该列为 value 列, 类型包括:SUM、MAX、MIN、REPLACE。
我们以一个建表操作来说明Doris的数据划分。
CREATE TABLE IF NOT EXISTS example_db.expamle_range_tbl
(
`user_id` LARGEINT NOT NULL COMMENT "用户 id",
`date` DATE NOT NULL COMMENT "数据灌入日期时间",
`timestamp` DATETIME NOT NULL COMMENT "数据灌入的时间戳",
`city` VARCHAR(20) COMMENT "用户所在城市",
`age` SMALLINT COMMENT "用户年龄",
`sex` TINYINT COMMENT "用户性别",
`last_visit_date` DATETIME REPLACE DEFAULT "1970-01-01
00:00:00" COMMENT "用户最后一次访问时间",
`cost` BIGINT SUM DEFAULT "0" COMMENT "用户总消费",
`max_dwell_time` INT MAX DEFAULT "0" COMMENT "用户最大停留时间",
`min_dwell_time` INT MIN DEFAULT "99999" COMMENT "用户最小停留时
间"
)
ENGINE=olap
AGGREGATE KEY(`user_id`, `date`, `timestamp`, `city`, `age`, `sex`)
PARTITION BY RANGE(`date`)
(
PARTITION `p201701` VALUES LESS THAN ("2017-02-01"),
PARTITION `p201702` VALUES LESS THAN ("2017-03-01"),
PARTITION `p201703` VALUES LESS THAN ("2017-04-01")
)
DISTRIBUTED BY HASH(`user_id`) BUCKETS 16
PROPERTIES
(
"replication_num" = "3",
"storage_medium" = "SSD",
"storage_cooldown_time" = "2018-01-01 12:00:00"
);
CREATE TABLE IF NOT EXISTS example_db.expamle_list_tbl
(
`user_id` LARGEINT NOT NULL COMMENT "用户 id",
`date` DATE NOT NULL COMMENT "数据灌入日期时间",
`timestamp` DATETIME NOT NULL COMMENT "数据灌入的时间戳",
`city` VARCHAR(20) COMMENT "用户所在城市",
`age` SMALLINT COMMENT "用户年龄",
`sex` TINYINT COMMENT "用户性别",
`last_visit_date` DATETIME REPLACE DEFAULT "1970-01-01
00:00:00" COMMENT "用户最后一次访问时间",
`cost` BIGINT SUM DEFAULT "0" COMMENT "用户总消费",
`max_dwell_time` INT MAX DEFAULT "0" COMMENT "用户最大停留时间",
`min_dwell_time` INT MIN DEFAULT "99999" COMMENT "用户最小停留时
间"
)
ENGINE=olap
AGGREGATE KEY(`user_id`, `date`, `timestamp`, `city`, `age`, `sex`)
PARTITION BY LIST(`city`)
(
PARTITION `p_cn` VALUES IN ("Beijing", "Shanghai", "Hong Kong"),
PARTITION `p_usa` VALUES IN ("New York", "San Francisco"),
PARTITION `p_jp` VALUES IN ("Tokyo")
)
DISTRIBUTED BY HASH(`user_id`) BUCKETS 16
PROPERTIES
(
"replication_num" = "3",
"storage_medium" = "SSD",
"storage_cooldown_time" = "2018-01-01 12:00:00"
);
以上述表来理解
以 AGGREGATE KEY 数据模型为例进行说明。更多数据模型参阅 Doris 数据模型。
列的基本类型,可以通过在 mysql-client 中执行 HELP CREATE TABLE; 查看。
AGGREGATE KEY 数据模型中,所有没有指定聚合方式(SUM、REPLACE、MAX、MIN)的列视为 Key 列。而其余则为 Value 列。
定义列时,可参照如下建议:
Doris 支持两层的数据划分。第一层是 Partition,支持 Range 和 List 的划分方式。第二层是 Bucket(Tablet),仅支持 Hash 的划分方式。
也可以仅使用一层分区。使用一层分区时,只支持 Bucket 划分。
分区列通常为时间列,以方便的管理新旧数据。不可添加范围重叠的分区。
Partition 指定范围的方式:
当range分区进行增删操作时,容易出现空洞,会导致无法导入
分区列支持BOOLEAN, TINYINT, SMALLINT, INT, BIGINT, LARGEINT, DATE,DATETIME, CHAR, VARCHAR 数据类型,分区值为枚举值。只有当数据为目标分区枚举值其中之一时,才可以命中分区。不可添加范围重叠的分区。
以下场景推荐使用复合分区:
Doris 支持指定多列作为分区列,示例如下:
PARTITION BY RANGE(`date`, `id`)
(
PARTITION `p201701_1000` VALUES LESS THAN ("2017-02-01", "1000"),
PARTITION `p201702_2000` VALUES LESS THAN ("2017-03-01", "2000"),
PARTITION `p201703_all` VALUES LESS THAN ("2017-04-01")
)
最后一个分区没有设置id列,系统默认会补充一个MIN_VALUE
PARTITION BY LIST(`id`, `city`)
(
PARTITION `p1_city` VALUES IN (("1", "Beijing"), ("1",
"Shanghai")),
PARTITION `p2_city` VALUES IN (("2", "Beijing"), ("2",
"Shanghai")),
PARTITION `p3_city` VALUES IN (("3", "Beijing"), ("3",
"Shanghai"))
)
在建表语句的最后 PROPERTIES 中,可以指定以下两个参数:
每个 Tablet 的副本数量。默认为 3,建议保持默认即可。在建表语句中所有 Partition中的 Tablet 副本数量统一指定。而在增加新分区时,可以单独指定新分区中 Tablet 的副本数量。
副本数量可以在运行时修改。强烈建议保持奇数。
最大副本数量取决于集群中独立 IP 的数量(注意不是 BE 数量)。Doris 中副本分布的原则是,不允许同一个 Tablet 的副本分布在同一台物理机上,而识别物理机即通过 IP。所以,即使在同一台物理机上部署了 3 个或更多 BE 实例,如果这些 BE 的 IP 相同,则依然只能设置副本数为 1。
对于一些小,并且更新不频繁的维度表,可以考虑设置更多的副本数。这样在 Join 查询时,可以有更大的概率进行本地数据 Join。
BE 的数据存储目录可以显式的指定为 SSD 或者 HDD(通过 .SSD 或者 .HDD 后缀区分)。建表时,可以统一指定所有 Partition 初始存储的介质。注意,后缀作用是显式指定磁盘介质,而不会检查是否与实际介质类型相符。
默认初始存储介质可通过 fe 的配置文件 fe.conf 中指定 default_storage_medium=xxx,如果没有指定,则默认为 HDD。如果指定为 SSD,则数据初始存放在 SSD 上。
如果没有指定storage_cooldown_time,则默认 30 天后,数据会从 SSD 自动迁移到 HDD上。如果指定了 storage_cooldown_time,则在到达 storage_cooldown_time 时间后,数据才会迁移。
注意,当指定storage_medium时,如果FE参数enable_strict_storage_medium_check 为False 该参数只是一个“尽力而为”的设置。即使集群内没有设置SSD存储介质,也不会报错,而是自动存储在可用的数据目录中。 同样,如果SSD介质不可访问、空间不足,都可能导致数据初始直接存储在其他可用介质上。而数据到期迁移到 HDD 时,如果 HDD 介质不可访问 、 空间不足 ,也可能迁移失败(但是会不断尝试) 。 如果FE参数enable_strict_storage_medium_check 为 True 则当集群内没有设置 SSD 存储介质时,会报错Failed to find enough host in all backends with storage medium is SSD。
ENGIN默认是OLAP,只有OLAP是Doris负责管理数据和存储。
其他 ENGINE 类型,如 mysql、broker、es 等等,本质上只是对外部其他数据库或系统中的表的映射,以保证 Doris 可以读取这些数据。而Doris 本身并不创建、管理和存储任何非 OLAP ENGINE类型的表和数据。
Doris 的数据模型主要分为 3 类:Aggregate、Uniq、Duplicate
表中的列按照是否设置了 AggregationType,分为 Key(维度列)和 Value(指标列)。没有设置 AggregationType 的称为 Key,设置了AggregationType 的称为 Value。
当我们导入数据时,对于 Key 列相同的行会聚合成一行,而 Value 列会按照设置的AggregationType 进行聚合。AggregationType 目前有以下四种聚合方式:
数据聚合会发生在三个时间段
数据在不同时间,可能聚合的程度不一致。比如一批数据刚导入时,可能还未与之前已存在的数据进行聚合。但是对于用户而言,用户只能查询到聚合后的数据。即不同的聚合程度对于用户查询而言是透明的。用户需始终认为数据以最终的完成的聚合程度存在,而不应假设某些聚合还未发生。
CREATE TABLE IF NOT EXISTS test_db.example_site_visit
(
`user_id` LARGEINT NOT NULL COMMENT "用户 id",
`date` DATE NOT NULL COMMENT "数据灌入日期时间",
`city` VARCHAR(20) COMMENT "用户所在城市",
`age` SMALLINT COMMENT "用户年龄",
`sex` TINYINT COMMENT "用户性别",
`last_visit_date` DATETIME REPLACE DEFAULT "1970-01-01
00:00:00" COMMENT "用户最后一次访问时间",
`last_visit_date_not_null` DATETIME REPLACE_IF_NOT_NULL DEFAULT
"1970-01-01 00:00:00" COMMENT "用户最后一次访问时间",
`cost` BIGINT SUM DEFAULT "0" COMMENT "用户总消费",
`max_dwell_time` INT MAX DEFAULT "0" COMMENT "用户最大停留时间",
`min_dwell_time` INT MIN DEFAULT "99999" COMMENT "用户最小停留时
间"
)
AGGREGATE KEY(`user_id`, `date`, `city`, `age`, `sex`)
DISTRIBUTED BY HASH(`user_id`) BUCKETS 10;
insert into test_db.example_site_visit values\
(10000,'2017-10-01','北京',20,0,'2017-10-01 06:00:00','2017-10-01
06:00:00',20,10,10),\
(10000,'2017-10-01','北京',20,0,'2017-10-01 07:00:00','2017-10-01
07:00:00',15,2,2),\
(10001,'2017-10-01','北京',30,1,'2017-10-01 17:05:45','2017-10-01
07:00:00',2,22,22),\
(10002,'2017-10-02',' 上 海 ',20,1,'2017-10-02
12:59:12',null,200,5,5),\
(10003,'2017-10-02','广州',32,0,'2017-10-02 11:20:00','2017-10-02
11:20:00',30,11,11),\
(10004,'2017-10-01','深圳',35,0,'2017-10-01 10:00:15','2017-10-01
10:00:15',100,3,3),\
(10004,'2017-10-03','深圳',35,0,'2017-10-03 10:20:22','2017-10-0310:20:22',11,6,6);
Insert into 单条数据这种操作在 Doris 里只能演示不能在生产使用,会引发写阻塞。
select * from test_db.example_site_visit;
CREATE TABLE IF NOT EXISTS test_db.example_site_visit2
(
`user_id` LARGEINT NOT NULL COMMENT "用户 id",
`date` DATE NOT NULL COMMENT "数据灌入日期时间",
`timestamp` DATETIME COMMENT "数据灌入时间,精确到秒",
`city` VARCHAR(20) COMMENT "用户所在城市",
`age` SMALLINT COMMENT "用户年龄",
`sex` TINYINT COMMENT "用户性别",
`last_visit_date` DATETIME REPLACE DEFAULT "1970-01-01
00:00:00" COMMENT "用户最后一次访问时间",
`cost` BIGINT SUM DEFAULT "0" COMMENT "用户总消费",
`max_dwell_time` INT MAX DEFAULT "0" COMMENT "用户最大停留时间",
`min_dwell_time` INT MIN DEFAULT "99999" COMMENT "用户最小停留时
间"
)
AGGREGATE KEY(`user_id`, `date`, `timestamp`, `city`, `age`, `sex`)
DISTRIBUTED BY HASH(`user_id`) BUCKETS 10;
insert into test_db.example_site_visit2 values(10000,'2017-10-
01','2017-10-01 08:00:05',' 北 京 ',20,0,'2017-10-01
06:00:00',20,10,10),\
(10000,'2017-10-01','2017-10-01 09:00:05','北京',20,0,'2017-10-01
07:00:00',15,2,2),\
(10001,'2017-10-01','2017-10-01 18:12:10','北京',30,1,'2017-10-01
17:05:45',2,22,22),\
(10002,'2017-10-02','2017-10-02 13:10:00','上海',20,1,'2017-10-02
12:59:12',200,5,5),\
(10003,'2017-10-02','2017-10-02 13:15:00','广州',32,0,'2017-10-02
11:20:00',30,11,11),\
(10004,'2017-10-01','2017-10-01 12:12:48','深圳',35,0,'2017-10-01
10:00:15',100,3,3),\
(10004,'2017-10-03','2017-10-03 12:38:20','深圳',35,0,'2017-10-03
10:20:22',11,6,6);
select * from test_db.example_site_visit2;
insert into test_db.example_site_visit values(10004,'2017-10-03','深圳',35,0,'2017-10-03 11:22:00',null,44,19,19),\
(10005,'2017-10-03','长沙',29,1,'2017-10-03 18:11:02','2017-10-03
18:11:02',3,1,1);
select * from test_db.example_site_visit;
在某些多维分析场景下,用户更关注的是如何保证 Key 的唯一性,即如何获得 Primary Key 唯一性约束。因此,我们引入了 Uniq 的数据模型。该模型本质上是聚合模型的一个特例,也是一种简化的表结构表示方式。
CREATE TABLE IF NOT EXISTS test_db.user
(
`user_id` LARGEINT NOT NULL COMMENT "用户 id",
`username` VARCHAR(50) NOT NULL COMMENT "用户昵称",
`city` VARCHAR(20) COMMENT "用户所在城市",
`age` SMALLINT COMMENT "用户年龄",
`sex` TINYINT COMMENT "用户性别",
`phone` LARGEINT COMMENT "用户电话",
`address` VARCHAR(500) COMMENT "用户地址",
`register_time` DATETIME COMMENT "用户注册时间"
)
UNIQUE KEY(`user_id`, `username`)
DISTRIBUTED BY HASH(`user_id`) BUCKETS 10;
insert into test_db.user values\
(10000,'wuyanzu',' 北 京 ',18,0,12345678910,' 北 京 朝 阳 区 ','2017-10-01
07:00:00'),\
(10000,'wuyanzu',' 北 京 ',19,0,12345678910,' 北 京 朝 阳 区 ','2017-10-01
07:00:00'),\
(10000,'zhangsan','北京',20,0,12345678910,'北京海淀区','2017-11-15
06:10:20');
select * from test_db.user;
Uniq 模型完全可以用聚合模型中的 REPLACE 方式替代。其内部的实现方式和数据存储方式也完全一样。
在某些多维分析场景下,数据既没有主键,也没有聚合需求。Duplicate 数据模型可以满足这类需求。数据完全按照导入文件中的数据进行存储,不会有任何聚合。即使两行数据完全相同,也都会保留。 而在建表语句中指定的 DUPLICATE KEY,只是用来指明底层数据按照那些列进行排序。
CREATE TABLE IF NOT EXISTS test_db.example_log
(
`timestamp` DATETIME NOT NULL COMMENT "日志时间",
`type` INT NOT NULL COMMENT "日志类型",
`error_code` INT COMMENT "错误码",
`error_msg` VARCHAR(1024) COMMENT "错误详细信息",
`op_id` BIGINT COMMENT "负责人 id",
`op_time` DATETIME COMMENT "处理时间"
)
DUPLICATE KEY(`timestamp`, `type`)
DISTRIBUTED BY HASH(`timestamp`) BUCKETS 10;
insert into test_db.example_log values\
('2017-10-01 08:00:05',1,404,'not found page', 101, '2017-10-01
08:00:05'),\
('2017-10-01 08:00:05',1,404,'not found page', 101, '2017-10-01
08:00:05'),\
('2017-10-01 08:00:05',2,404,'not found page', 101, '2017-10-01
08:00:06'),\
('2017-10-01 08:00:06',2,404,'not found page', 101, '2017-10-01
08:00:07');
因为数据模型在建表时就已经确定,且无法修改。所以,选择一个合适的数据模型非常重要。
做一些计算类的操作需要判断 例如count sum之类的操作
动态分区在0.12加入,对表级别的分区做ttl,减少用户的操作负担
动态分区需要用户建表时设置动态分区的规则。FE会启动一个后台线程,根据用户指定的规则创建或删除分区。用户也可对运行时对现有规则进行变更。
建表
CREATE TABLE tbl1
(...)
PROPERTIES
(
"dynamic_partition.prop1" = "value1",
"dynamic_partition.prop2" = "value2",
...
)
运行时修改
ALTER TABLE tbl1 SET
(
"dynamic_partition.prop1" = "value1",
"dynamic_partition.prop2" = "value2",
...
)
动态分区规则参数都以dynamic_partition为前缀:
参数 | 注解 |
---|---|
dynamic_partition.enable | 是否开启动态分区特性,可指定 true 或 false,默认为 true600 |
dynamic_partition.time_unit | 动态分区调度的单位,可指定 HOUR、DAY、WEEK、MONTH。 HOUR,后缀格式为 yyyyMMddHH,分区列数据类型不能为DATE。DAY,后缀格式为 yyyyMMdd。WEEK,后缀格式为 yyyy_ww。即当前日期属于这一年的第几周。MONTH,后缀格式为 yyyyMM。 |
dynamic_partition.time_zone | 动态分区的时区,如果不填写,则默认为当前机器的系统的时区 |
dynamic_partition.start | 动态分区的起始偏移,为负数。根据 time_unit 属性的不同,以当天(星期/月)为基准,分区范围在此偏移之前的分区将会被删除。如果不填写默认值为 Interger.Min_VALUE 即-2147483648,即不删除历史分区 |
dynamic_partition.end | 动态分区的结束偏移,为正数。根据 time_unit 属性的不同,以当天(星期/月)为基准,提前创建对应范围的分区 |
dynamic_partition.prefix | 动态创建的分区名前缀 |
dynamic_partition.buckets | 动态创建的分区所对应分桶数量 |
dynamic_partition.replication_num | 动态创建的分区所对应的副本数量,如果不填写,则默认为该表创建时指定的副本数量。 |
dynamic_partition.start_day_of_week | 当 time_unit 为 WEEK 时,该参数用于指定每周的起始点。取值为 1 到 7。其中 1 表示周一,7 表示周日。默认为 1,即表示每周以周一为起始点 |
dynamic_partition.start_day_of_month | 当 time_unit 为 MONTH 时,该参数用于指定每月的起始日期。取值为 1 到 28。其中 1 表示每月 1 号,28 表示每月 28 号。默认为 1,即表示每月以 1 号位起始点。暂不支持以 29、30、31 号为起始日,以避免因闰年或闰月带来的歧义 |
默认为 false。当置为 true 时,Doris 会自动创建所有分区,当期望创建的分区个数大
于 max_dynamic_partition_num 值时,操作将被禁止。当不指定 start 属性时,该参数不生
效。
当 create_history_partition 为 true 时,该参数用于指定创建历史分区数量。默认值为 -
1, 即未设置。
指定最新的多少个分区为热分区。对于热分区,系统会自动设置其 storage_medium 参
数为 SSD,并且设置 storage_cooldown_time。
hot_partition_num 是往前 n 天和未来所有分区
需要保留的历史分区的时间范围。当 dynamic_partition.time_unit 设置为
"DAY/WEEK/MONTH" 时,需要以 [yyyy-MM-dd,yyyy-MM-dd],[...,...] 格式进行设置。当
dynamic_partition.time_unit 设置为 "HOUR" 时,需要以 [yyyy-MM-dd HH:mm:ss,yyyyMM-dd HH:mm:ss],[...,...] 的格式来进行设置。如果不设置,默认为 "NULL"。```
假设需要创建的历史分区数据为expect_create_partition_num,具体参数如下
假如某些情况导致start与end之间的分区丢失,之间的分区会删除重建,但是start之前的并不会重新创建
创建语句
create table student_dynamic_partition1
(id int,
time date,
name varchar(50),
age int
)
duplicate key(id,time)
PARTITION BY RANGE(time)()
DISTRIBUTED BY HASH(id) buckets 10
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" = "10",
"replication_num" = "1"
);
查看动态分区表调度情况
SHOW DYNAMIC PARTITION TABLES;
查看表分区
SHOW PARTITIONS FROM student_dynamic_partition1;
修改成对应时间
insert into student_dynamic_partition1 values(1,'2022-03-3111:00:00','name1',18);
设置创建历史分区
ALTER TABLE student_dynamic_partition1 SET
("dynamic_partition.create_history_partition" = "true");
查看分区情况
SHOW PARTITIONS FROM student_dynamic_partition1;
HELP ALTER TABLE
ALTER TABLE tbl_name SET ("dynamic_partition.enable" = "false")
假如从手动分区到动态分区,偏移量之前的分区会被删除
通常我们创建的doris表可以称为base 表,在base表之上,我们可以创建任意多个ROLLUP表。这些ROLLUP表的数据是基于base表产生,并且物理上是独立存储的。他主要是在base表基础上获取更粗粒度的一些聚合数据
Uniq算是Aggregate一种特殊模式
查看表结构
desc tablename all;
alter table tablename add rollup rollupname(colname,colname);
查看rollup完成情况
SHOW ALTER TABLE ROLLUP;
Duplicate模式中的ROLLUP
因为duplicate中没有聚合,rollup 失去了上卷的含义,只是单纯的对前缀索引做一个排序
我们将一行数据的前36字节作为这行数据前缀索引,当遇到varchar就会被截断,所以在建表需要考虑好列的顺序。
rollup最根本作用是做一些查询速率的优化,在源码中,将其命名为Materialized Index(物化索引)。
在查询操作时,并不能显示指定使用某个rollup,由系统决定。rollup数据独立存储,创建越多,占据存储越多,导入数据会变慢。但是查询成正比。rollup聚合方式与base表一致,无法改变。
物化视图是包含了查询结果的数据库对象,是预先存储查询结果的一种数据库对象。
对于那些经常重复的使用相同的子查询结果的查询性能大幅提升。
Doris 自动维护物化视图的数据,无论是新的导入,还是删除操作都能保证 base 表和物化视图表的数据一致性。无需任何额外的人工维护成本。
查询时,会自动匹配到最优物化视图,并直接从物化视图中读取数据。
自动维护物化视图的数据会造成一些维护开销
物化视图是后出的,之前物化视图的功能由rollup来做,物化视图弥补了rollup无法做明细数据的预聚合
ALTER TABLE ADD ROLLUP 的语句均可以通过CREATE MATERIALIZED VIEW 实现。
物化视图创建原则:
多个共用聚合和key
不需要给某个查询去做一个单独做一个物化视图
HELP CREATE MATERIALIZED VIEW
是一个异步的操作
一些简单物化视图相关的操作
SHOW ALTER TABLE MATERIALIZED VIEW FROM test_db;
查看 Base 表的所有物化视图
desc sales_records all;
DROP MATERIALIZED VIEW 物化视图名 on Base 表名;