You need to enable JavaScript to run this app.
ByteHouse云数仓版

ByteHouse云数仓版

复制全文
最佳实践
Bucket Table 分桶最佳实践
复制全文
Bucket Table 分桶最佳实践

Bucket Table 说明

Bucket table 是 ByteHouse 在建表的时候的一种性能优化选项,在 ByteHouse 中使用 Bucket table 时,系统会依据用户建表语句中提供的一个或者多个列、表达式整理表数据,将相同值的数据聚簇在同一个 bucket number 下,主要用于唯一键表 bucket 级别去重优化性能。没有唯一键的表,一般不需要配置 Bucket,除非需要两张表进行 colocation join,这时需要两张表的 bucket 配置一致。​本文将介绍非唯一键表的分桶实践,唯一键表分桶请参见Bucket 去重优化

使用 Bucket Table 的收益

使用 cluster key 聚簇数据在大表上可以获得以下几项收益:

  1. 针对 cluster key 的点查可以过滤掉大部分数据,降低 IO 量获得更短的执行时间和更高的并发 QPS。
  2. 两张或者多张表针对 cluster key 的 join 可以获得 co-located join 的优化,极大的降低 shuffle 数据量并得到更短的执行时间。

如何选择分桶键 Cluster Key

Cluster key 可以是一个或者多个列、表达式,建议最多使用 3 个字段,更多的字段通常会引入过高的写入代价且获益语句范围更小。
选择正确的 cluster key 对于性能的影响非常显著,因此需要慎重选择。通常可以按照如下原则:

  1. 经常用于相等、IN 过滤的列。
  2. 常用的聚合列。
  3. 多表的 join key。

上述场景如果常用的情况是两列组合,比如 a = 1 and b = 2,那么 cluster key 选择两列可以获得更好的效果。
另一个需要考虑的维度是列的 distinct 值数量:

  1. distinct 值需要至少超过 worker 数量。
  2. 如果 distinct 值数量较小,最好能保持 worker 数量的倍数,以实现查询时数据分布的更均衡。

如何选择分桶表达式

从性能和查询优化角度考虑,推荐使用如下表达式

CLUSTER BY EXPRESSION cityHash64V2(cluster_column) % N INTO N BUCKETS

在一个分区内:

  1. 数据会依据 cluster key 的值分配到相应 bucket number 的 parts 文件中。
  2. 同一个 bucket number 的 parts 文件在查询时会发送到同一个 worker 节点上计算。

因此选择一个合适的 bucket number 对于存储和查询都有重大的影响,唯一键表场景设置如何设置请参见ByteHouse 唯一键表最佳实践
下面主要指非唯一键表的 bucket 数目设置最佳实践:

  1. 确保 bucket number 为计算组 worker 数量的倍数,这是为了保证查询时分配的均衡,一般建议设置为 1 倍或者 2 倍(预留扩充 worker 节点余度)计算组 worker 数量即可,不推荐少于计算组 worker 数量,会导致部分 worker 没有数据,查询不均。
  2. 非唯一键表不要设置超过 1000 或者超过计算组节点数 10 倍以上的 bucket nubmer。
  3. 确保一个分区下一个 bucket number 中有足够多的数据,至少确保一个分区的一个 bucket number parts 大小超过 1GB。

如何决定是否要修改 Cluster by 定义

在运行过程中因为数据变化、查询模式变化、worker 节点数量变化,您可能会想要重新设置 cluster key 和 bucket number。
这里需要考虑实施修改的代价,权衡是否需要修改以及何时修改:

  1. 修改 cluster by 定义需要对现存已有数据做 recluster,需要评估现存数据量估算 recluster 执行时间。
  2. Recluster 期间现存数据的查询会回退为一张普通表,所有 bucket table 的收益暂时都失去。
  3. Recluster 会占用 write worker 的资源,需要评估当前 ByteHouse 集群是否有独立的 write worker 以及当前负担,评估对现有查询、merge 等任务的影响。

这里有两种情况:

  1. 修改 cluster key:
    • 此时意味着当前的数据已经无法获得 bucket table 收益,因此无需考虑 recluster 期间失去的收益。
    • 需要评估 recluster 任务对于现有任务的影响判断是否可以执行。
  2. 修改 bucket number:
    • 当前 bucket table 的收益仍在,因此需要和业务方确认可以接受的性能回退的时间,进一步根据 recluster 时间判断是否可以执行,以及确定开始执行时间。
    • 也需要评估 recluster 任务对于现有任务的影响判断是否可以执行。

分桶应用案例

假设某 ByteHouse 订阅用户启用了六个计算节点,由于单个分区的数据量较大,超过 2 亿条记录,应用程序经常根据 c1c2 字段进行聚合和连接操作。 因此,决定使用桶表进行优化。 桶表的设计选项如下:

  • 分桶键( CLUSTER Key )选择:选择 c1c2 列作为分桶键。
  • 桶(Bucket)数:取节点数的两倍:12。
-- 创建带有分桶的表 
create or replace table table_01 (c1 timestamp, c2 string, c3 number) CLUSTER BY EXPRESSION cityHash64V2(to_date(c1), c2) % 12 INTO 12 BUCKETS;

-- 将桶添加到现有数据中
ALTER TABLE t CLUSTER BY EXPRESSION cityHash64V2(column, expression, ...) % 64 INTO 64 BUCKETS;

-- 按多列将桶添加到集群中 
ALTER TABLE t CLUSTER BY EXPRESSION cityHash64V2(a, b, c) % 64 INTO 64 BUCKETS;

-- 添加或更改集群属性
ALTER TABLE t MODIFY CLUSTER BY EXPRESSION cityHash64V2(column, expression, ...) % 64 INTO 64 BUCKETS;
最近更新时间:2026.02.13 18:00:29
这个页面对您有帮助吗?
有用
有用
无用
无用