1. Doris基础学习
中文官网:https://doris.apache.org/zh-CN/docs/dev/summary/basic-summary/
1.1 doris 简介
Apache Doris 是一个现代化的 MPP(Massively Parallel Processing,即大规模并行处理) 分析型数据库产品
亚秒级响应时间即可获得查询结果
可以支持 10PB 以上的超大数据集
满足多种数据分析需求,例如固定历史报表,实时数据分析,交互式 数据分析和探索式数据分析等
1.2 Doris 架构
Doris 的架构很简洁,只设 FE(Frontend)、BE(Backend)两种角色、两个进程,不依赖于 外部组件,方便部署和运维,FE、BE 都可线性扩展。
FE(Frontend):存储、维护集群元数据;负责接收、解析查询请求,规划查询计划, 调度查询执行,返回查询结果。主要有三个角色:
Leader 和 Follower:主要是用来达到元数据的高可用,保证单节点宕机的情况下, 元数据能够实时地在线恢复,而不影响整个服务。
Observer:用来扩展查询节点,同时起到元数据备份的作用。如果在发现集群压力 非常大的情况下,需要去扩展整个查询的能力,那么可以加 observer 的节点。observer 不 参与任何的写入,只参与读取。
BE(Backend):负责物理数据的存储和计算;依据 FE 生成的物理计划,分布式地执行查询。
数据的可靠性由 BE 保证,BE 会对整个数据存储多副本或者是三副本。副本数可根据 需求动态调整。
MySQLClient
Doris 借助 MySQL 协议,用户使用任意 MySQL 的 ODBC/JDBC 以及 MySQL 的客户
端,都可以直接访问 Doris。
Broker
Broker 为一个独立的无状态进程。封装了文件系统接口,提供 Doris 读取远端存储系统 中文件的能力,包括 HDFS,S3,BOS 等。
1.3 基本概念
doris因为是mysql协议所以体验上和mysql很相似
首先DDL和DML语法上基本和mysql相同
和 mysql一致,拥有Row & Column & table等概念
不同的是
doris的Column分为 Key 和 Value,key有点类似mysql的索引,同时提供索引的快速查询功能
doris 的 value 可以根据key自动聚合,也就是doris的数据模型
2. doris 讲解
2.1 数据模型
doris字段分为key和value,key有以下几种方式
模型 | 特点 | 优势 | 劣势 | 建表指定 |
aggregate模型 | 按照key进行预聚合 目前有四种聚合方式:
| 降低聚合查询时所需扫描的数据量和查询的计算量,非常适合有固定模式的报表类查询场景 | 对count()查询很不友好 固定了聚合方式 例:已经设置了max聚合,表取数对该字段min求最小值就会出现不一致问题 不保留明细数据,只有聚合后的数据 解决:key加上时间戳 | AGGREGATE KEY(`user_id`, `date`) |
uniq模型 | 唯一Key,同一key数据自动覆盖,本质上是聚合模型的replace | 保证 Key 的唯一性 | 无法利 用 ROLLUP 等预聚合带来的查询优势 | UNIQUE KEY(`user_id`, `date`) |
duplicate模型 | 既没有主键,也没有聚合需求时 | 不受聚合模型的约束,可以发挥列模型的优势 | 无法利 用 ROLLUP 等预聚合带来的查询优势 | DUPLICATE KEY(`user_id`, `date`) |
2.2 分区、分桶
doris 也有分区和分桶,但和hive不同
Table是有很多分区Partition的
Partition 可以视为是逻辑上最小的管理单元。数据的导入与删除,都可以或仅能针对一个 Partition 进行(不能直接操作Tablet)。
一个 Partition包含多个数据分片Tablet组成,Tablet 包含若干数据行
所以本质上Tablet 是数据移动、复制等操作的最小物理存储单元,一定要设置分桶,可以不设置分区
2.2.1分区
可以设置多列分区,但是分区字段必须为 KEY 列
range分区
#通常为时间列,范围划分分区
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")
)
#删除分区会出现空洞
p201701: [MIN_VALUE, 2017-02-01)
p201702: [2017-02-01, 2017-03-01)
p201704: [2017-04-01, 2017-05-01)
删除p201703: [2017-03-01, 2017-04-01),不会改变已生成的分区,该部分的数据无法导入
list分区
##直接指定,但是可以命中多个
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") )
不设置分区
其实当不使用partition by建表的时候,系统会自动生成一个和表名同名的,全值范围的partition
动态分区
createtable student_dynamic_partition1 (
id int,
timedate,
name varchar(50),
age int
)
duplicate key(id,time)
PARTITIONBYRANGE(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"
);
常用的分区方式
一般都是动态range分区,或者数据较少时直接不分区
2.2.2 分桶
只支持hash分片
分桶列可以是多列,但必须为 Key 列
一个或少数分桶列
对应的点查询可以仅触发一个分桶扫描,当多个点查询并发时,这些查询有较大的概率分别触发不同的分桶扫描,各 个查询之间的 IO 影响较小,适合 高并发的点查询场景
多个分桶列
数据分布更均匀,但一个查询条件不包含所有分桶列的等值条件,会触发所有分桶同时扫描,查询吞吐会增加,单个查询的延迟随之降低,适合大吞吐低并发的查询场景
2.3 ENGINE
一般都是用默认的olap,只有这个 ENGINE 类型是由 Doris 负责数据管理和存储的
ENGINE 类型有mysql、broker、 es 等等,本质上只是对外部其他数据库或系统中的表的映射,以保证 Doris 可以读取这些数据。而 Doris 本身并不创建、管理和存储任何非 olap ENGINE 类型的表和数据
2.4 replication_num
副本机制,一般就用默认的 3
对于一些小,并且更新不频繁的维度表,可以考虑设置更多的副本数。这样在 Join 查询 时,可以有更大的概率进行本地数据 Join
3.4.2 storage_medium & storage_cooldown_time
数据存储目录可以显式的指定为 SSD 或者 HDD,一般也都不怎么在意这个参数
3. doris 进阶语法
3.1 Rollup 上卷
在原表的基础上按照指定粒度预聚合,提高查询效率
Rollup 的数据是基于 Base 表产生的,并且在物理上是独立存储的,也就意味着有存储成本和写入效率降低
还可以用Rollup调整前缀索引(建表时指定的索引顺序无法改变,可以通过Rollup实现)
ALTER TABLE table1 ADD ROLLUP rollup_city(citycode, pv);
SHOW ALTER TABLE ROLLUP;
3.2 视图
和Rollup一样,都是建立在Base表上,会自动同步Base表的数据更新等操作
物化视图覆盖了Rollup的全部功能,相当于Rollup的超集,弥补了Rollup无法对明细数据模型进行预聚合的短板。物化视图支持丰富的聚合函数。
Doris目前只支持物化视图的单表创建,不支持表join的方式创建。
3.3 bitmap数据类型
bitmap是一种数据结构-位图,使用每个位表示某种状态,大大节省存储空间,同时位图采用位运算计算效率也很高
适用场景:需要去重,数据较大
注意事项:在数据稀疏的情况下,效率会变得非常低,另外使用bitmap每次操作的行数不宜太多
除了使用位图外,使用上和set集合差不多