目录
一、Doris简介
二、Doris的定位
三、产品定位
四、Doris的整体架构
五、Doris的数据分布
六、Doris的关键性技术
6.1 数据可靠性
6.2 易于维护
6.3ROLLUP表
七、 Doris的数据模型
7.1 aggregate聚合模型
7.2 uniqu key模型
7.3 duplicate key模型
7.4 数据模型的选择建议
八、数据组织(存储原则)--按列存储
九、索引:
9.1 前缀索引:
9.2 智能索引
十、mysql数据导入doris
一、Doris简介
Doris(原百度 Palo)是一款 基于大规模并行处理技术的分布式 SQL 数据库。/基于 MPP 的交互式SQL数据仓库,可用于 OLAP 。MPP 是将任务并行的分散到多个服务器和节点上,在每个节点上计算完成后,将各自部分的结果汇总在一起得到最终的结果
二、Doris的定位
MPP 架构的关系型分析数据库
PB 级别大数据集,秒级/毫秒级查询
主要用于多维分析和报表查询
三、产品定位
四、Doris的整体架构
Doris的架构只设FE(Frontend)、BE(Backend)两种角色、两个进程,不依赖于外部组件,方便部署和运维。
以数据存储的角度观之,FE存储、维护集群元数据;BE存储物理数据。
以查询处理的角度观之, FE节点接收、解析查询请求,规划查询计划,调度查询执行,返回查询结果;BE节点依据FE生成的物理计划,分布式地执行查询。
FE主要有有三个角色,一个是leader,一个是follower,还有一个observer。leader跟follower,主要是用来达到元数据的高可用,保证单节点宕机的情况下,元数据能够实时地在线恢复,而不影响整个服务。右边observer只是用来扩展查询节点,就是说如果在发现集群压力非常大的情况下,需要去扩展整个查询的能力,那么可以加observer的节点。observer不参与任何的写入,只参与读取。
数据的可靠性由BE保证,BE会对整个数据存储多副本或者是三副本。副本数可根据需求动态调整。
五、Doris的数据分布
如果从表的角度来看数据结构,用户的一张 Table 会拆成多个 Tablet,Tablet 会存成多副本,存储在不同的 BE 中,从而保证数据的高可用和高可靠。
六、Doris的关键性技术
6.1 数据可靠性
元数据使用 Memory+Checkpoint+Journal ( 分别是什么?),使用 BTBJE ( 类似于 Raft ) 协议实现高可用性和高可靠性。元数据的每次更新,都首先写入到磁盘的日志文件中,然后再写到内存中,最后定期checkpoint到本地磁盘上。一般只有三个FE就可以保证高可靠性。
Doris 内部自行管理数据的多副本和自动修复。保证数据的高可用、高可靠。在服务器宕机的情况下,服务依然可用,数据也不会丢失。
总结:FE用一致性协议保证高可用,BE采用多副本保证高可用。
6.2 易于维护
它不依赖于Hadoop,也不依赖其他的外部组件,只有FE跟BE两个进程,数据都是自成一体的,所以可以很方便地部署启动。
6.3ROLLUP表
解释:
在Doris中,我们将用户通过建表语句创建出来的表称为base表(base table)。base表中保存中按用户建表语句指定的方式存储的基础数据。
在base表之上,我们可以创建任意多个rollup表。这些rollup的数据是基于base表产生的,并且在物理存储是独立存储的。rollup表的基本作用,在于base表的基础上,获得更粗粒度的聚合数据。
作用:
ROLLUP 最根本的作用是提高某些查询的查询效率(无论是通过在base表的基础上进一步建立rolllup表进一步聚合来减少数据量,还是修改列顺序以匹配前缀索引)。
例子:
select date, sum(nums) from a group by date; -->. 38s
alter table a add rollup rollup 5(date, nums);--> 该rollup表只保留了每个date在nums上的sum数。
select date, sum(nums) from a group by date;(自动命中rollup5)。 0.2ms
七、 Doris的数据模型
7.1 aggregate聚合模型
维度列key: 没设置aggregationtype
指标列value:设置了aggregationtype
当我们导入数据的时候,对于key列相同的行会聚合成一行,而value列会按照设置的aggregationtype进行聚合。aggregationtype目前有一下四种聚合方式:
sum:求和,多列的value值进行累加;
Max:保留最大值
Min:保留最小值
Replace:替代,下一批数据中的value会替换之前导入过的行中的value。在同一个批次中的数据,对于replace这种聚合方式,替换顺序不做保证。
优点:我们会按维度列去聚合数据,如果维度列数据相同我们会把这些数据合并(compaction)起来。也就相当于在数据库里面存储的其实是一个合并之后的结果,这个结果对于统计分析来说是很有效果的。因为广告报表只关心这种统计之后的数据,现在我们把大量的数据聚合,比如一天的数据可能有一千条,我们聚合成一条,相当于整个的I/O节省一千倍,效果非常明显。
缺点:有些业务场景分析的时候,是需要明细数据的,它不太关心统计的结果,而是更关心流程分析,更关心的是我要拿着历史的全量数据跟现在的数据做对比。
7.2 uniqu key模型
我们提供一个唯一Key模型,在整个历史数据导入的时候,我们保证Key的唯一,不聚合。
Unique Key的模型主要面向留存分析或者订单分析的场景,他们需要一个Unique Key的约束去保证整个数据不丢不重。
7.3 duplicate key模型
数据完全按照导入文件中的数据进行存储,不会有任何聚合。即使两行数据完全相同,也都会保留。 而在建表语句中指定的 DUPLICATE KEY,只是用来指明底层数据按照那些列进行排序。
数据可能重复,对于有些日志分析它不太在意数据多几条或者少几条,可能只关心排序,这个时候可能重复Key的模型会更加有效果。/这种数据模型适用于既没有聚合需求,又没有主键唯一性约束的原始数据的存储。
7.4 数据模型的选择建议
因为数据模型在建表时就已经确定,且无法修改。所以,选择一个合适的数据模型非常重要。
Aggregate 模型可以通过预聚合,极大地降低聚合查询时所需扫描的数据量和查询的计算量,非常适合有固定模式的报表类查询场景。但是该模型对 count(*) 查询很不友好。同时因为固定了 Value 列上的聚合方式,在进行其他类型的聚合查询时,需要考虑语意正确性。
Uniq 模型针对需要唯一主键约束的场景,可以保证主键唯一性约束。但是无法利用 ROLLUP 等预聚合带来的查询优势(因为本质是 REPLACE,没有 SUM 这种聚合方式,rollup只是用来调准列顺序命中前缀索引)。
Duplicate 适合任意维度的 Ad-hoc 查询。虽然同样无法利用预聚合的特性,但是不受聚合模型的约束,可以发挥列存模型的优势(只读取相关列,而不需要读取所有 Key 列)
八、数据组织(存储原则)--按列存储
好处:对分析的场景来说,多数时候用户只关心几列的数据,这个时候如果用一个列存的话,它可以只访问查询涉及的列,大量降低I/O,达到一个比较好的一个I/O的效果。
1、Doris 的数据是按列存储的,每一列单独存放。
2、查询时,只访问查询涉及的列,大量降低 I/O。
3、按列存储,数据类型一致,方便压缩。
4、数据包建索引,数据即索引。
5、利用原始过滤条件以及 min、max 和 sum 等智能索引技术,将数据集查询范围尽可能地缩小,大大减少 I/O,提升查询效率。
九、索引:
9.1 前缀索引:
不同于传统的数据库设计,Doris不支持在任意列上创建索引。Doris这类mpp架构的olap数据库,通常都是通过提高高并发,来处理大量数据的。
本质上,Doris的数据存储在类似sstable的数据结构中,该结构是一种有序的数据结构,可以按照指定的列进行排序存储。在这种结构上,以排序列作为条件进行查找,会非常高效。而前缀索引,即在排序的基础上,实现的一种根据给定前缀列,快速查询数据的索引方式。我们将一行数据的前36个字节作为这行数据的前缀索引。 前缀索引遇到varchar类型数据失效。
9.2 智能索引
Doris存储引擎对于排序列,会存储min/max/sum等智能索引技术,将数据集扫描范围尽可能地缩小,减少磁盘I/O,提升查询性能。比如说这一列排过序了,然后我在这一列的十万行所组成的一个粒度上面,给它加一个min/max,然后这样查询的时候,它就可以快速去过滤这个十万行,这会大大地减少整个数据的扫描量,从而减少I/O。
十、doris数据导入hive
方式一:封装spark程序
def mysqToDoris(session:SparkSession, url:String, user:String,
password:String, tableName:String):DateFrame = {
val temMap = new Properties()
temMap.setProperty("user", user)
temMap.setProperty("password", password)
val frame: DateFrame = session.read.jdbc(url,tableName,temMap) //官方API
frame
}
下一步,在开发代码里直接调用该方法:
mysqlToDoris(session, url, user, password, "test").createOrReplaceTempView("doris_test")
insert overwrite table 表名 select * from doris_test
方式二:直接在doris中关联mysql表
create table doris_test(
id BIGINT,
name varchar
)ENGINE=mysql
PROPERTIES
( "host" = "127.0.0.1",
"port" = "3306",
"user" = "root",
"password" = "123",
"database" = "db",
"table" = "test"
);