tencent cloud

腾讯云数据仓库 TCHouse-D

产品简介
产品概述
基本概念
集群架构
产品优势
应用场景
购买指南
计费概述
续费说明
到期与欠费说明
退费说明
配置变更计费说明
快速入门
通过控制台使用腾讯云数据仓库 TCHouse-D
通过客户端使用腾讯云数据仓库 TCHouse-D
操作指南
集群操作
监控和告警配置
账户权限管理
数据管理
查询管理
配置管理
节点管理
日志分析
SQL 工作区
开启资源隔离
开发指南
数据表设计
数据导入
数据导出
基础功能
查询优化
生态扩展功能
API 文档
History
Introduction
API Category
Making API Requests
Cluster Operation APIs
Database and Table APIs
Cluster Information Viewing APIs
Hot-Cold Data Layering APIs
Database and Operation Audit APIs
User and Permission APIs
Resource Group Management APIs
Data Types
Error Codes
云上生态
为子账号授予 CAM 策略
查询加速腾讯云 DLC
实践教程
基本功能使用
高级特性使用
资源规格选型及调优建议
命名规范及库表限制
表设计与数据导入
查询调优
建议规避的用法
通过 JDBC 方式公网访问 TCHouse-D
性能测试
TPC-H 性能测试
SSB 性能测试
TPC-DS 性能测试
常见问题
常见操作问题
常见报错
联系我们
词汇表
产品协议
服务等级协议
隐私政策
数据处理和安全协议

自动分桶

PDF
聚焦模式
字号
最后更新时间: 2024-06-27 11:09:45
说明
该功能适用于 Doris 1.2.2及后续版本。
用户经常设置不合适的 Bucket,导致各种问题,这里提供一种方式,来自动设置分桶数。

实现

以往创建分桶时需要手动设定分桶数,而自动分桶推算功能使 Doris 可以动态地推算分桶个数,使得分桶数始终保持在一个合适范围内,让用户不再操心桶数的细枝末节。 为了方便阐述该功能,该部分会将桶拆分为两个时期的桶,即初始分桶以及后续分桶;这里的初始和后续只是本文为了描述清楚该功能而采用的术语,Doris 分桶本身没有初始和后续之分。 BUCKET_DESC 非常简单,但是需要指定分桶个数。在自动分桶推算功能上,BUCKET_DESC 的语法直接将分桶数改成"Auto",并新增一个 Properties 配置即可:
-- 旧版本指定分桶个数的创建语法
DISTRIBUTED BY HASH(site) BUCKETS 20

-- 新版本使用自动分桶推算的创建语法
DISTRIBUTED BY HASH(site) BUCKETS AUTO properties("estimate_partition_size" = "100G")
新增的配置参数 estimate_partition_size 表示一个单分区的数据量。该参数是可选的,如果没有给出则 Doris 会将 estimate_partition_size 的默认值取为 10GB。 从上文中已经得知,一个分桶在物理层面就是一个Tablet,为了获得最好的性能,建议 Tablet 的大小在 1GB - 10GB 的范围内。那么自动分桶推算是如何保证 Tablet 大小处于这个范围内的呢?主要原则如下:
若是整体数据量较小,则分桶数不要设置过多。
若是整体数据量较大,则应使桶数跟总的磁盘块数相关,充分利用每台 BE 机器和每块磁盘的能力。

初始分桶推算

从原则出发,理解自动分桶推算功能的详细逻辑就变得简单了,首先来看初始分桶:
1. 先根据数据量得出一个桶数 N。首先使用 estimate_partition_size 的值除以 5(按文本格式存入 Doris 中有 5 比 1 的数据压缩比计算),得到的结果为:
(, 100MB),则取 N=1。
[100MB, 1GB),则取 N=2。
[1GB, ),则每GB一个分桶。
2. 根据 BE 节点数以及每个 BE 节点的磁盘容量,计算出桶数 M。其中每个 BE 节点算 1,每 50G 的磁盘容量算 1,那么 M 的计算规则为: M = BE 节点数 ( 一块磁盘块大小 / 50GB) 磁盘块数 例如有 3 台 BE,每台 BE 都有 4 块 500GB 的磁盘,那么 M = 3 (500GB / 50GB) 4 = 120。
3. 得到最终的分桶个数计算逻辑: 先计算一个中间值 x = min(M, N, 128), 如果 x < N并且x < BE节点个数,则最终分桶为 y 即 BE 节点个数;否则最终分桶数为 x。
上述过程伪代码表现形式为:
int N = 计算N值;
int M = 计算M值;

int y = BE节点个数;
int x = min(M, N, 128);

if (x < N && x < y) {
return y;
}
return x;
有了上述算法,再引入一些例子来更好地理解这部分逻辑:
case1:
数据量 100 MB,10 台 BE 机器,2TB *3 块盘
数据量 N = 1
BE 磁盘 M = 10* (2TB/50GB) * 3 = 1230
x = min(M, N, 128) = 1
最终: 1

case2:
数据量 1GB, 3 台 BE 机器,500GB *2块盘
数据量 N = 2
BE 磁盘 M = 3* (500GB/50GB) * 2 = 60
x = min(M, N, 128) = 2
最终: 2

case3:
数据量100GB,3台BE机器,500GB *2块盘
数据量N = 20
BE磁盘M = 3* (500GB/50GB) * 2 = 60
x = min(M, N, 128) = 20
最终: 20

case4:
数据量500GB,3台BE机器,1TB *1块盘
数据量N = 100
BE磁盘M = 3* (1TB /50GB) * 1 = 60
x = min(M, N, 128) = 63
最终: 63

case5:
数据量500GB,10台BE机器,2TB *3块盘
数据量 N = 100
BE磁盘 M = 10* (2TB / 50GB) * 3 = 1230
x = min(M, N, 128) = 100
最终: 100

case 6:
数据量1TB,10台BE机器,2TB *3块盘
数据量 N = 205
BE磁盘M = 10* (2TB / 50GB) * 3 = 1230
x = min(M, N, 128) = 128
最终: 128

case 7:
数据量500GB,1台BE机器,100TB *1块盘
数据量 N = 100
BE磁盘M = 1* (100TB / 50GB) * 1 = 2048
x = min(M, N, 128) = 100
最终: 100

case 8:
数据量1TB, 200台BE机器,4TB *7块盘
数据量 N = 205
BE磁盘M = 200* (4TB / 50GB) * 7 = 114800
x = min(M, N, 128) = 128
最终: 200
可以看到,详细逻辑与原则是匹配的。

后续分桶推算

上述是关于初始分桶的计算逻辑,后续分桶数因为已经有了一定的分区数据,可以根据已有的分区数据量来进行评估。后续分桶数会根据最多前 7 个分区数据量的 EMA(短期指数移动平均线)值,作为 estimate_partition_size 进行评估。此时计算分桶有两种计算方式,假设以天来分区,往前数第一天分区大小为 S7,往前数第二天分区大小为 S6,依次类推到 S1。
1. 如果 7 天内的分区数据每日严格递增,则此时会取趋势值。有6个 delta 值,分别是:
S7 - S6 = delta1,
S6 - S5 = delta2,
...
S2 - S1 = delta6
由此得到 ema(delta) 值: 那么,今天的 estimate_partition_size = S7 + ema(delta)
2. 非第一种的情况,此时直接取前几天的 EMA 平均值:
今天的estimate_partition_size = EMA(S1, ..., S7)
根据上述算法,初始分桶个数以及后续分桶个数都能被计算出来。跟之前只能指定固定分桶数不同,由于业务数据的变化,可能前面分区的分桶数和后面分区的分桶数不一样,这对用户是透明的,用户无需关心每一分区具体的分桶数是多少,而这一自动推算的功能会让分桶数更加合理。

最佳实践

创建使用自动分桶表

CREATE TABLE IF NOT EXISTS example_auto_bucket_tbl ( user_id VARCHAR(128) NOT NULL COMMENT "用户id", date DATE NOT NULL COMMENT "数据灌入日期时间", data varchar(512) NOT NULL ) ENGINE=OLAP DUPLICATE KEY(user_id) PARTITION BY RANGE(date)() DISTRIBUTED BY HASH(user_id) BUCKETS AUTO PROPERTIES ( "replication_num" = "1", # 开启动态分区 "dynamic_partition.enable" = "true", # 按月进行动态分区 "dynamic_partition.time_unit" = "MONTH", # 保留5个历史分区 "dynamic_partition.start" = "-5", # 提前创建10个未来分区 "dynamic_partition.end" = "3", # 分区命名前缀 "dynamic_partition.prefix" = "p_", # 开启创建历史分区 "dynamic_partition.create_history_partition" = "true", # 创建3个历史分区 "dynamic_partition.history_partition_num" = "3", # 预计分区的数据量 "estimate_partition_size" = "1G" );
可以看到,在创建表后,Doris系统自动为每个分区设置的分桶数量为2。
enter image description here


enter image description here


接下来我们向表内导入一定数量的数据,之后调整 dynamic_partition.end 参数,让 Doris 自动创建新的分区。查看新分区的分桶情况,可以看到新创建的分区的分桶数量变为7。

enter image description here



关闭自动分桶功能

临时关闭:关闭动态分区

ALTER TABLE example_auto_bucket_tbl SET
(
# 关闭动态分区
"dynamic_partition.enable" = "false"
);

永久关闭:关闭动态分区后,修改表的分桶数量关闭

# 关闭动态分区后,修改表的分桶数量
alter table example_auto_bucket_tbl modify DISTRIBUTION DISTRIBUTED BY HASH(`user_id`) BUCKETS 16;
需要注意两种操作的效果:
临时关闭后,如果重新打开动态分区功能,动态分区新创建的分区分桶数量为 Doris 根据最近几个分区的数据量计算出的结果。
关闭动态分区后,若修改表的分桶数量,后续将无法再开启自动分桶功能。

说明

只对动态分区创建的分区生效。
开启 autobucket 之后,在 show create table 的时候看到的 schema 也是 BUCKETS AUTO。如果想要查看确切的 bucket 数,可以通过 show partitions from ${table}; 来查看。
不可以在已有表上开启自动分桶功能,自动分桶功能只能在创建表时开启。
自动分桶不会对已有分区产生影响,自动分桶只是在动态分区创建新分区时,根据历史分区数据,磁盘,doris 的 BE 节点数量等信息,通过一定的算法得出新分区的分桶数量,不会对已有的分区造成影响。

帮助和支持

本页内容是否解决了您的问题?

填写满意度调查问卷,共创更好文档体验。

文档反馈