生而为人

程序员的自我修养

0%

官方文档目录摘要

[toc]

git wiki地址

编译与部署

安装与部署

软硬件需求

  • FE(前端)和BE(后端)存储数据的区别,以及所需机器配置
  • FE与BE端口、网络需求
  • ip绑定

集群部署

  • 手动部署

    • FE部署
    • BE部署
    • FS_Broker部署

扩容缩容

  • FE扩容和缩容

    • 增加FE节点
    • 删除FE节点
  • BE扩容和缩容

    • 增加BE节点
    • 删除BE节点
  • Broker扩容缩容

常见问题

开始使用

基础使用指南

1.创建用户

  • Root用户登陆与密码修改
  • 创建新用户

2.数据表的创建与数据导入

  • 创建数据库

  • 账户授权

  • 建表

    • 单分区
    • 复合分区
  • 导入数据

    • 流式导入
    • Broker导入

3.数据的查询

  • 简单查询
  • Join查询
  • 子查询

高级使用指南

1. 表结构变更

2. Rollup

3. 数据表的查询

  • 内存限制
  • 查询超时
  • Broadcast/Shuffle Join
  • 查询重试和高可用

最佳实践

1. 建表

  • 数据模型选择

    • AGGREGATE KEY
    • UNIQUE KEY
    • DUPLICATE KEY
  • 大宽表与Star Schema

  • 分区和分桶

    • Range分区(partition)
    • HASH分桶(bucket)
  • 稀疏索引和Bloom Filter

  • 物化视图(rollup)

    • Base Table中数据聚合度不高
    • Base Table中的前缀索引无法命中

2. Schema Change

  • Sorted Schema Change
  • Direct Schema Change: 无需重新排序,但需要对数据做一次转换。例如修改列的类型,在稀疏索引中加一列等
  • Linked Schema Change: 无需转换数据,直接完成。例如加列操作

数据划分

1. 基本概念

  • Row & Column
  • Tablet & Partition

2. 数据划分

  • 列定义

    • 列定义建议
  • 分区与分桶

Doris支持两层的数据划分。第一层是Partition,仅支持Range的划分方式。第二层是Bucket(Tablet),仅支持Hash的划分方式。也可以仅使用一层分区

    • Partition
    • Bucket
    • 关于Partition和Bucket的数量和数据量的建议
    • 多列分区
  • PROPERTIES

    • replication_num
    • storage_medium & storage_cooldown_time
  • ENGINE

3. 常见问题

  • 建表操作常见问题

    • 如果在较长的建表语句中出现语法错误,可能会出现语法错误提示不全的现象。这里罗列可能的语法错误供手动纠错:
    • Failed to create partition [xxx] . Timeout
    • 建表命令长时间不返回结果。

数据模型、ROLLUP及前缀索引

github wiki

1. 基本概念

  • Row

  • Column

    • Key
    • Value

2. Aggregate模型

  • 示例1: 导入数据聚合
  • 示例2: 保留明细数据
  • 示例3: 导入数据与已有数据聚合

3. Uniq模型

4. Duplicate模型(冗余模型)

5. ROLLUP

  • 基本概念

    • Aggregate和Uniq模型中的ROLLUP

      • 示例1: 获得每个用户的总消费
      • 示例2: 获得不同城市,不同年龄段用户的总消费、最长和最短页面驻留时间
    • Duplicate模型中的ROLLUP

  • 前缀索引与ROLLUP

    • 前缀索引

我们将一行数据的前 36 个字节 作为这行数据的前缀索引。当遇到 VARCHAR 类型时,前缀索引会直接截断。

    • ROLLUP调整前缀索引
  • ROLLUP的几点说明

    • 根本作用是提高某些查询的查询效率(无论是通过聚合来减少数据量,还是修改列顺序以匹配前缀索引)。因此 ROLLUP 的含义已经超出了 “上卷” 的范围。这也是为什么我们在源代码中,将其命名为 Materized Index(物化索引)的原因。
    • ROLLUP是附属于Base表的,可以看作是Base表的一种辅助数据结构。用户可以在 Base 表的基础上,创建或删除 ROLLUP,但是不能在查询中显式的指定查询某 ROLLUP。是否命中 ROLLUP 完全由 Doris 系统自动决定。
    • ROLLUP 的数据是独立物理存储的。因此,创建的 ROLLUP 越多,占用的磁盘空间也就越大。同时对导入速度也会有影响(导入的ETL阶段会自动产生所有 ROLLUP 的数据),但是不会降低查询效率(只会更好)。
    • ROLLUP 的数据更新与 Base 表示完全同步的。用户无需关心这个问题。
    • ROLLUP 中列的聚合方式,与 Base 表完全相同。在创建 ROLLUP 无需指定,也不能修改。
    • 查询能否命中 ROLLUP 的一个必要条件(非充分条件)是,查询所涉及的所有列(包括 select list 和 where 中的查询条件列等)都存在于该 ROLLUP 的列中。否则,查询只能命中 Base 表。
    • 某些类型的查询(如 count(*))在任何条件下,都无法命中 ROLLUP。具体参见接下来的 聚合模型的局限性 一节。
    • 可以通过 EXPLAIN your_sql; 命令获得查询执行计划,在执行计划中,查看是否命中 ROLLUP。
    • 可以通过 DESC tbl_name ALL; 语句显示 Base 表和所有已创建完成的 ROLLUP。
    • 查询如何命中ROLLUP

6. 聚合模型的局限性

  • Aggregate 模型(包括 Uniq 模型)

在聚合模型中,模型对外展现的,是最终聚合后的数据。也就是说,任何还未聚合的数据(比如说两个不同导入批次的数据),必须通过某种方式,以保证对外展示的一致性。

  • Duplicate 模型

Duplicate 模型没有聚合模型的这个局限性。因为该模型不涉及聚合语意,在做 count(*) 查询时,任意选择一列查询,即可得到语意正确的结果。

7. 数据模型的选择建议

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

  1. Aggregate 模型可以通过预聚合,极大地降低聚合查询时所需扫描的数据量和查询的计算量,非常适合有固定模式的报表类查询场景。但是该模型对 count(*) 查询很不友好。同时因为固定了 Value 列上的聚合方式,在进行其他类型的聚合查询时,需要考虑语意正确性。
  2. Uniq 模型针对需要唯一主键约束的场景,可以保证主键唯一性约束。但是无法利用 ROLLUP 等预聚合带来的查询优势(因为本质是 REPLACE,没有 SUM 这种聚合方式)。
  3. Duplicate 适合任意维度的 Ad-hoc 查询。虽然同样无法利用预聚合的特性,但是不受聚合模型的约束,可以发挥列存模型的优势(只读取相关列,而不需要读取所有 Key 列)。

Rollup与查询

在 Doris 里 Rollup 作为一份聚合物化视图,其在查询中可以起到两个作用:

  • 索引
  • 聚合数据(仅用于聚合模型,即aggregate key)

但是为了命中 Rollup 需要满足一定的条件,并且可以通过执行计划中 ScanNdoe 节点的 PreAggregation 的值来判断是否可以命中 Rollup,以及 Rollup 字段来判断命中的是哪一张 Rollup 表。

1. 名词解释

  • Base: 基表
  • Rollup: 一般指基于 Base 表创建的 Rollup 表,但在一些场景包括 Base 以及 Rollup 表。

2. 索引

3. 聚合数据

操作手册

数据导入

1. 导入总览

1.1 基本概念

  1. Frontend(FE):Doris 系统的元数据和调度节点。在导入流程中主要负责导入规划生成和导入任务的调度工作。
  2. Backend(BE):Doris 系统的计算和存储节点。在导入流程中主要负责数据的 ETL 和存储。
  3. Broker:Broker 为一个独立的无状态进程。封装了文件系统接口,提供 Doris 读取远端存储系统中文件的能力。
  4. 导入作业(Load job):导入作业读取用户提交的源数据,转换或清洗后,将数据导入到 Doris 系统中。导入完成后,数据即可被用户查询到。
  5. Label:所有导入作业都有一个 Label。Label 在一个数据库内唯一,可由用户指定或系统自动生成,用于标识一个导入作业。相同的 Label 仅可用于一个成功的导入作业。
  6. MySQL 协议/HTTP 协议:Doris 提供两种访问协议接口。 MySQL 协议和 HTTP 协议。部分导入方式使用 MySQL 协议接口提交作业,部分导入方式使用 HTTP 协议接口提交作业。

1.2 导入方式

  1. Broker load
  2. Stream load
  3. Insert
  4. Multi load
  5. Routine load

1.3 基本原理

1.3.1 导入执行流程
  1. PENDING(非必须)
  2. ETL(非必须)
  3. LOADING
  4. FINISHED
  5. CANCELLED
1.3.2 Label和原子性

1.4 同步和异步

1.4.1 同步
1.4.2 异步
1.4.3 注意事项

1.5 内存限制

1.6 最佳实践

1.7 通用系统配置

1.7.1 FE配置
1.7.2 BE配置
1.7.3 列映射

2.Broker Load

一种异步导入方式

2.1 适用场景

2.2 名词解释

2.3 基本原理

2.4 基本操作

2.4.1 创建导入
2.4.2 查看导入
2.4.3 取消导入

2.5 相关系统配置

2.5.1 FE 配置

2.6 最佳实践

2.6.1 应用场景

使用 Broker load 最适合的场景就是原始数据在文件系统(HDFS,BOS,AFS)中的场景。其次,由于 Broker load 是单次导入中唯一的一种异步导入的方式,所以如果用户在导入大文件中,需要使用异步接入,也可以考虑使用 Broker load。

2.6.2 数据量

这里仅讨论单个 BE 的情况,如果用户集群有多个 BE 则下面标题中的数据量应该乘以 BE 个数来计算。比如:如果用户有3个 BE,则 3G 以下(包含)则应该乘以 3,也就是 9G 以下(包含)。

2.6.3 性能分析
2.6.4 完整例子

2.7 常见问题

3. Stream load

Stream load 是一个同步的导入方式,用户通过发送 HTTP 协议发送请求将本地文件或数据流导入到 Doris 中。Stream load 同步执行导入并返回导入结果。用户可直接通过请求的返回体判断本次导入是否成功。

Stream load 主要适用于导入本地文件,或通过程序导入数据流中的数据。

3.1 基本原理

3.2 基本操作

3.3 相关系统配置

3.4 最佳实践

3.4.1 应用场景

使用 Stream load 的最合适场景就是原始文件在内存中,或者在磁盘中。其次,由于 Stream load 是一种同步的导入方式,所以用户如果希望用同步方式获取导入结果,也可以使用这种导入。

3.4.2 数据量
3.4.3 完整例子

3.5 常见问题

4. Routine Load

例行导入(Routine Load)功能为用户提供了一种自动从指定数据源进行数据导入的功能。

本文档主要介绍该功能的实现原理、使用方式以及最佳实践。

5. insert into

Insert Into 语句的使用方式和 MySQL 等数据库中 Insert Into 语句的使用方式类似。但在 Doris 中,所有的数据写入都是一个独立的导入作业。所以这里将 Insert Into 也作为一种导入方式介绍。

主要的 Insert Into 命令包含以下两种;

  • INSERT INTO tbl SELECT …
  • INSERT INTO tbl (col1, col2, …) VALUES (1, 2, …), (1,3, …);

其中第二种命令仅用于 Demo,不要使用在测试或生产环境中。

6. spark Load

Spark load 通过外部的 Spark 资源实现对导入数据的预处理,提高 Doris 大数据量的导入性能并且节省 Doris 集群的计算资源。主要用于初次迁移,大数据量导入 Doris 的场景。

Spark load 是一种异步导入方式,用户需要通过 MySQL 协议创建 Spark 类型导入任务,并通过 SHOW LOAD 查看导入结果。

6.1 适用场景

  • 源数据在 Spark 可以访问的存储系统中,如 HDFS。
  • 数据量在 几十 GB 到 TB 级别。

7. delete

Delete不同于其他导入方式,它是一个同步过程。和Insert into相似,所有的Delete操作在Doris中是一个独立的导入作业,一般Delete语句需要指定表和分区以及删除的条件来筛选要删除的数据,并将会同时删除base表和rollup表的数据。

表结构变更

常用参考

数据模型、ROLLUP 及前缀索引

ALTER TABLE