聊聊分布式 SQL 数据库Doris(三)

在 Doris 的存储引擎规则:

  • 表的数据是以分区为单位存储的,不指定分区创建时,默认就一个分区.
  • 用户数据首先被划分成若干个分区(Partition),划分的规则通常是按照用户指定的分区列进行范围划分,比如按时间划分。
  • 在每个分区内,数据被进一步的按照Hash的方式分桶,分桶的规则是要找用户指定的分桶列的值进行Hash后分桶。每个分桶就是一个数据分片(Tablet),也是数据划分的最小逻辑单元。
  • Partition 可以视为是逻辑上最小的管理单元。数据的导入与删除,都可以或仅能针对一个 Partition 进行。
  • Tablet直接的数据是没有交集的,独立存储的。Tablet也是数据移动、复制等操作的最小物理存储单元。

Table (逻辑描述) -- > Partition(分区:管理单元) --> Bucket(分桶:存储,每个分桶就是一个数据分片:Tablet,数据划分的最小逻辑单元。称为子表) ,如下图:

语法与示例

语法:

sql 复制代码
-- 该表记录了某个时间点,在某个站点上各个用户的pv数据
CREATE TABLE demo.test_tbl(
    sdate      DATE,  -- 日期
    site       INT,  -- 站点id
    city       VARCHAR(64),  -- 城市
    user       VARCHAR(32)  DEFAULT '', -- 用户名
    pv         BIGINT -- pv量
) ENGINE=olap DUPLICATE KEY(sdate, site, city)
[PARTITION_DESC]
[BUCKET_DESC]
PROPERTIES ("replication_num" = "1");

[PARTITION_DESC] 表示创建分区的详细语句,[BUCKET_DESC] 表示创建分桶的语句.

动态分区:

sql 复制代码
PARTITION BY RANGE(sdate)()

-- 剩余参数需要在PARTITION进行配置:
PROPERTIES (
  "dynamic_partition.enable" = "true",
  "dynamic_partition.time_unit" = "DAY",
  "dynamic_partition.start" = "-30",
  "dynamic_partition.end" = "3",
  "dynamic_partition.prefix" = "p",
  "dynamic_partition.create_history_partition"="true",
  "replication_num" = "1"
);

分桶:

sql 复制代码
DISTRIBUTED BY HASH(site) BUCKETS 20

此时指定以 site 列的哈希值作为分桶,并且分桶个数设置为 20 个.

官方示例:

sql 复制代码
CREATE TABLE tbl1
(
    k1 DATE,
    -- ...
)
PARTITION BY RANGE(k1) ()
DISTRIBUTED BY HASH(k1)
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" = "32"
);

批量分区与自动分桶

批量分区使得用户能够批量操作表的分区结构,一次性创建多个分区,而不是逐个单独创建。

sql 复制代码
-- 当然,分区创建个数受到max_multi_partition_num参数控制,该值默认为4096,有需求可以修改
PARTITION BY RANGE(sdate)
(
   FROM ("2013-01-01") TO ("2023-01-01") INTERVAL 1 DAY
)
-- 从这个 case 来看,批量分区功能的语法更为简洁,但该功能的易用性和灵活性远不止于此。

自动分桶是基于表中某个列(或在创建表时指定咧)的值范围进行的。系统会根据该列的数据分布情况,将数据划分到不同的数据桶中。

sql 复制代码
-- 旧版本指定分桶个数的创建语法
DISTRIBUTED BY HASH(site) BUCKETS 20

-- 新版本使用自动分桶推算的创建语法
DISTRIBUTED BY HASH(site) BUCKETS AUTO
properties("estimate_partition_size" = "100G")

底层逻辑

查询路由

一个分区的数据不会跨多个不同的BE节点存储.

在 Apache Doris 中,当请求到来时,查询某个分区的数据时,Doris 使用以下的过程来定位到相应的 Backend(BE)节点:

  1. 分区键(Partition Key): 在 Doris 中,表的分区是按照某一列的值范围进行划分的,这个列通常被称为分区键。用户在创建表时可以选择分区键。

  2. 查询请求中的分区键值: 当查询请求到达 Doris 时,请求中通常包含了要查询的分区键值。

  3. 分区键值与分区映射关系: Doris 通过分区键值与分区的映射关系,确定具体的分区。这个映射关系通常存储在系统的元数据中,其中包括每个分区所在的 BE 节点信息。

  4. BE 节点负责的分区: 根据分区键值的映射关系,Doris 确定了负责该分区的 BE 节点。

  5. 查询计划的生成和执行: Doris 生成查询计划,其中包含了具体的查询操作。该计划会被发送到负责该分区的 BE 节点上执行。

在 Apache Doris 中,一个表的多个分区数据通常会存储在不同的 Backend(BE)节点上,以实现分布式存储和查询的优势。每个分区的数据都会被划分并存储在负责该分区的一个 BE 节点上。具体来说:

  1. 表的分区: Doris 中的表通常根据某一列的值范围进行分区。每个分区是表的逻辑组织单元,用于提高查询性能、管理数据、支持按范围删除等操作。

  2. 分布式存储: Doris 的设计目标之一是分布式存储和查询。因此,一个表的多个分区数据会被分布存储在不同的 BE 节点上。这样的设计有助于提高系统的横向扩展性,允许系统有效地处理大规模数据和高并发的查询请求。

  3. 负责分区的 BE 节点: Doris 通过元数据信息记录每个分区所在的 BE 节点。当执行查询请求时,Doris 会根据查询涉及的分区,确定负责这些分区的 BE 节点。每个 BE 节点负责存储和管理分配给它的分区数据。

  4. 分布式计算: 查询请求在涉及多个分区时,Doris 可以通过分布式计算的方式,在多个 BE 节点上并行执行查询计划,以提高查询性能。

分桶算法

暂时只支持HASH.

分区算法

暂时只支持List, RANGE. 常用的有四种: (a) Round-Robin、(b) Range、(c) List、(d) Hash .

参考:
Doris数据分布


详细内容阅读: Apache Doris 分区分桶新功能数据划分. 本文在此基础上做总结与自我思考的延伸.

相关推荐
nangonghen6 小时前
在华为云通过operator部署Doris v2.1集群
kubernetes·华为云·doris·operator
Sigtuna4 天前
Doris SQL 特技
数据库·sql·doris
向阳121812 天前
Apache Doris 数据类型
apache·doris
SelectDB技术团队12 天前
Apache Doris 3.0.3 版本正式发布
大数据·数据库·数据仓库·数据分析·doris
SunnyRivers12 天前
Elasticsearch入门之HTTP基础操作
http·elasticsearch·删除·文档·索引·查询
SunnyRivers15 天前
Elasticsearch入门之HTTP高级查询操作
http·elasticsearch·排序·查询
atbigapp.com24 天前
Apache Doris 现行版本 Docker-Compose 运行教程
大数据·doris·mpp
crabdave12325 天前
Doris 2.1.7镜像制作
docker·doris
SelectDB技术团队1 个月前
兼顾高性能与低成本,浅析 Apache Doris 异步物化视图原理及典型场景
大数据·数据库·数据仓库·数据分析·doris
饭桶也得吃饭1 个月前
部署Apache Doris
linux·apache·doris