Doris介绍

一、Doris 概述

  1. 定义与起源

    • Doris 是一款基于 ‌MPP(大规模并行处理)架构‌ 的实时分析型数据库,最初由百度于 2008 年开发(内部称 Palo),2017 年开源,2018 年捐赠至 Apache 基金会并更名23。
    • 2022 年成为 Apache 顶级项目,全球超 4000 家企业采用,包括百度、美团、腾讯等28。
  2. 核心特性

    • 高性能‌:亚秒级查询响应,支持 PB 级数据分析。
    • 易用性‌:兼容 MySQL 协议与 SQL 语法,支持 BI 工具无缝对接。
    • 实时性‌:支持流式数据导入,写入后立即可查。
    • 扩展性‌:单集群可水平扩展至 200+ 节点。
    • MPP 架构的关系型分析数据库
    • PB 级别大数据集,秒级/毫秒级查询
    • 主要用于多维分析和报表查询

二、Doris的整体架构

Doris的架构只设FE(Frontend)、BE(Backend)两种角色、两个进程,不依赖于外部组件,方便部署和运维。

以数据存储的角度观之,FE存储、维护集群元数据;BE存储物理数据。
以查询处理的角度观之, FE节点接收、解析查询请求,规划查询计划,调度查询执行,返回查询结果;BE节点依据FE生成的物理计划,分布式地执行查询。
FE主要有有三个角色,一个是leader,一个是follower,还有一个observer。leader跟follower,主要是用来达到元数据的高可用,保证单节点宕机的情况下,元数据能够实时地在线恢复,而不影响整个服务。右边observer只是用来扩展查询节点,就是说如果在发现集群压力非常大的情况下,需要去扩展整个查询的能力,那么可以加observer的节点。observer不参与任何的写入,只参与读取。

数据的可靠性由BE保证,BE会对整个数据存储多副本或者是三副本。副本数可根据需求动态调整。

三、应用场景

  1. 实时分析

    • 电商、金融领域的实时报表与用户行为分析。
    • 案例:某银行 1 小时完成 4300+ 候选人 AI 面试筛选。
  2. 数据湖联邦查询

    • 支持 Hive、Iceberg 等外部数据源联邦查询。
  3. 日志与画像分析

    • 日志检索、用户画像构建及 AB 实验平台。

四、Doris的数据分布

如果从表的角度来看数据结构,用户的一张 Table 会拆成多个 Tablet,Tablet 会存成多副本,存储在不同的 BE 中,从而保证数据的高可用和高可靠。

五、Doris的关键性技术

5.1 数据可靠性

元数据使用 Memory+Checkpoint+Journal ( 分别是什么?),使用 BTBJE ( 类似于 Raft ) 协议实现高可用性和高可靠性。元数据的每次更新,都首先写入到磁盘的日志文件中,然后再写到内存中,最后定期checkpoint到本地磁盘上。一般只有三个FE就可以保证高可靠性。

Doris 内部自行管理数据的多副本和自动修复。保证数据的高可用、高可靠。在服务器宕机的情况下,服务依然可用,数据也不会丢失。

总结:FE用一致性协议保证高可用,BE采用多副本保证高可用。

5.2 易于维护

它不依赖于Hadoop,也不依赖其他的外部组件,只有FE跟BE两个进程,数据都是自成一体的,所以可以很方便地部署启动。

5.3 ROLLUP表

解释:

     在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的数据模型

6.1 aggregate聚合模型

维度列key: 没设置aggregationtype

指标列value:设置了aggregationtype

当我们导入数据的时候,对于key列相同的行会聚合成一行,而value列会按照设置的aggregationtype进行聚合。aggregationtype目前有一下四种聚合方式:

sum:求和,多列的value值进行累加;
Max:保留最大值
Min:保留最小值
Replace:替代,下一批数据中的value会替换之前导入过的行中的value。在同一个批次中的数据,对于replace这种聚合方式,替换顺序不做保证。
优点:我们会按维度列去聚合数据,如果维度列数据相同我们会把这些数据合并(compaction)起来。也就相当于在数据库里面存储的其实是一个合并之后的结果,这个结果对于统计分析来说是很有效果的。因为广告报表只关心这种统计之后的数据,现在我们把大量的数据聚合,比如一天的数据可能有一千条,我们聚合成一条,相当于整个的I/O节省一千倍,效果非常明显。

缺点:有些业务场景分析的时候,是需要明细数据的,它不太关心统计的结果,而是更关心流程分析,更关心的是我要拿着历史的全量数据跟现在的数据做对比。

6.2 uniqu key模型

我们提供一个唯一Key模型,在整个历史数据导入的时候,我们保证Key的唯一,不聚合。

    Unique Key的模型主要面向留存分析或者订单分析的场景,他们需要一个Unique Key的约束去保证整个数据不丢不重。

6.3 duplicate key模型

数据完全按照导入文件中的数据进行存储,不会有任何聚合。即使两行数据完全相同,也都会保留。 而在建表语句中指定的 DUPLICATE KEY,只是用来指明底层数据按照那些列进行排序。

    数据可能重复,对于有些日志分析它不太在意数据多几条或者少几条,可能只关心排序,这个时候可能重复Key的模型会更加有效果。/这种数据模型适用于既没有聚合需求,又没有主键唯一性约束的原始数据的存储。

6.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,提升查询效率。

八、索引

8.1 前缀索引

不同于传统的数据库设计,Doris不支持在任意列上创建索引。Doris这类mpp架构的olap数据库,通常都是通过提高高并发,来处理大量数据的。

    本质上,Doris的数据存储在类似sstable的数据结构中,该结构是一种有序的数据结构,可以按照指定的列进行排序存储。在这种结构上,以排序列作为条件进行查找,会非常高效。而前缀索引,即在排序的基础上,实现的一种根据给定前缀列,快速查询数据的索引方式。我们将一行数据的前36个字节作为这行数据的前缀索引。       前缀索引遇到varchar类型数据失效。

8.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"
);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

墨痕诉清风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值