更新时间:2024-11-29 GMT+08:00

Doris基本原理

Doris简介

Doris是一个基于MPP架构的高性能、实时的分析型数据库,以极速易用的特点被人们所熟知,仅需亚秒级响应时间即可返回海量数据下的查询结果,不仅可以支持高并发的点查询场景,也能支持高吞吐的复杂分析场景。基于此,Apache Doris能够较好的满足报表分析、即席查询、统一数仓构建、数据湖联邦查询加速等使用场景,用户可以在此之上构建用户行为分析、AB实验平台、日志检索分析、用户画像分析、订单分析等应用。

Doris架构

Doris整体架构如下图所示,FE和BE节点可以横向无限扩展。

图1 Doris架构
表1 参数说明

名称

说明

MySQL Tools

Doris采用MySQL协议,高度兼容MySQL语法,支持标准 SQL,用户可以通过各类客户端工具来访问Doris,并支持与 BI工具无缝对接。

FE

主要负责用户请求的接入、查询解析规划、元数据的管理、节点管理相关工作。

BE

主要负责存储数据、执行查询计划、副本负载均衡。

Leader

Leader为Follower组中选举出来的一种角色。

Follower

一条元数据日志需要在多数Follower节点写入成功,才算成功。

Doris采用MPP的模型,节点间和节点内都是并行执行,适用于多个大表的分布式Join。

支持向量化的查询引擎、AQE( Adaptive Query Execution )技术、CBO 和 RBO 结合的优化策略、热数据缓存查询等。

Doris基本概念

在Doris中,数据都以表(Table)的形式进行逻辑上的描述。

  • Row&Column

    一张表包括行(Row)和列(Column):

    • Row:即用户的一行数据。
    • Column: 用于描述一行数据中不同的字段。

    Column可以分为两大类:Key和Value。从业务角度看,Key和Value可以分别对应维度列和指标列。从聚合模型的角度来说,Key列相同的行,会聚合成一行。其中Value列的聚合方式由用户在建表时指定。

  • Tablet&Partition

    在Doris的存储引擎中,用户数据被水平划分为若干个数据分片(Tablet,也称作数据分桶)。每个Tablet包含若干数据行。各个Tablet之间的数据没有交集,并且在物理上是独立存储的。

    多个Tablet在逻辑上归属于不同的分区(Partition)。一个Tablet只属于一个Partition,而一个Partition包含若干个Tablet。因为Tablet在物理上是独立存储的,所以可以视为Partition在物理上也是独立。Tablet是数据移动、复制等操作的最小物理存储单元。

    若干个Partition组成一个Table。Partition可以视为是逻辑上最小的管理单元。数据的导入与删除,只能针对一个Partition进行。

  • 数据模型

    Doris的数据模型主要分为3类:Aggregate、Unique、Duplicate。

    • Aggregate模型

      导入数据时,对于Key列相同的行会聚合成一行,而Value列会按照设置的AggregationType进行聚合。 AggregationType目前有以下四种聚合方式:

      • SUM:求和,多行的Value进行累加。
      • REPLACE:替代,下一批数据中的Value会替换之前导入过的行中的Value。
      • MAX:保留最大值。
      • MIN:保留最小值。
    • Unique模型

      在某些多维分析场景下,用户更关注的是如何保证Key的唯一性,即如何获得Primary Key唯一性约束。因此,引入了Unique数据模型。

      • 读时合并

        Unique模型的读时合并实现完全可以用Aggregate模型中的REPLACE方式替代,其内部的实现方式和数据存储方式也完全一样。

      • 写时合并

        Unique模型的写时合并实现,不同于Aggregate模型,查询性能更接近于Duplicate模型,在有主键约束需求的场景上相比Aggregate模型有较大的查询性能优势,尤其是在聚合查询以及需要用索引过滤大量数据的查询中。

        在开启了写时合并选项的Unique表中,数据在导入阶段就会去将被覆盖和被更新的数据进行标记删除,同时将新的数据写入新的文件。在查询时,所有被标记删除的数据都会在文件级别被过滤,读取出的数据就都是最新的数据,消除了读时合并中的数据聚合过程,并且能够在很多情况下支持多种谓词的下推。因此在许多场景都能带来比较大的性能提升,尤其是在有聚合查询的情况下。

    • Duplicate模型

      在某些多维分析场景下,数据既没有主键,也没有聚合需求。可以引入Duplicate数据模型来满足这类需求。

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

    • 数据模型的选择建议​

      因为数据模型在建表时就已经确定,且无法修改。所以,选择一个合适的数据模型非常重要。

      • Aggregate模型可以通过预聚合,极大地降低聚合查询时所需扫描的数据量和查询的计算量,非常适合有固定模式的报表类查询场景。但是该模型对count(*)查询不友好。同时因为固定了Value列上的聚合方式,在进行其他类型的聚合查询时,需要考虑语义正确性。
      • Unique模型针对需要唯一主键约束的场景,可以保证主键唯一性约束。但是无法利用ROLLUP等预聚合带来的查询优势。
        • 对于聚合查询有较高性能需求的用户,推荐使用自1.2版本加入的写时合并实现。
        • Unique模型仅支持整行更新,如果用户既需要唯一主键约束,又需要更新部分列(例如将多张源表导入到一张Doris表的场景),则可以考虑使用Aggregate模型,同时将非主键列的聚合类型设置为REPLACE_IF_NOT_NULL。
        • Duplicate适合任意维度的Ad-hoc查询。虽然同样无法利用预聚合的特性,但是不受聚合模型的约束,可以发挥列存模型的优势(只读取相关列,而不需要读取所有Key列)。