3.7.5 手动分桶¶
如果使用了分区,则 DISTRIBUTED ...
语句描述的是数据在各个分区内的划分规则。
如果不使用分区,则描述的是对整个表的数据的划分规则。
也可以对每个分区单独指定分桶方式。
分桶列可以是多列, Aggregate
和 Unique
模型必须为 Key
列, Duplicate
模型可以是 key
列和 value
列。分桶列可以和 Partition
列相同或不同。
分桶列的选择,是在查询吞吐和查询并发之间的一种权衡:
-
如果选择多个分桶列,则数据分布更均匀。如果一个查询条件不包含所有分桶列的等值条件,那么该查询会触发所有分桶同时扫描,这样查询的吞吐会增加,单个查询的延迟随之降低。这个方式适合大吞吐低并发的查询场景。
-
如果仅选择一个或少数分桶列,则对应的点查询可以仅触发一个分桶扫描。此时,当多个点查询并发时,这些查询有较大的概率分别触发不同的分桶扫描,各个查询之间的
IO
影响较小(尤其当不同桶分布在不同磁盘上时),所以这种方式适合高并发的点查询场景。
1 Bucket 的数量和数据量的建议¶
-
一个表的
Tablet
总数量等于(Partition num * Bucket num
)。 -
一个表的
Tablet
数量,在不考虑扩容的情况下,推荐略多于整个集群的磁盘数量。 -
单个
Tablet
的数据量理论上没有上下界,但建议在1G - 10G
的范围内。如果单个Tablet
数据量过小,则数据的聚合效果不佳,且元数据管理压力大。如果数据量过大,则不利于副本的迁移、补齐,且会增加Schema Change
或者Rollup
操作失败重试的代价(这些操作失败重试的粒度是Tablet
)。 -
当
Tablet
的数据量原则和数量原则冲突时,建议优先考虑数据量原则。 -
在建表时,每个分区的
Bucket
数量统一指定。但是在动态增加分区时(ADD PARTITION
),可以单独指定新分区的Bucket
数量。可以利用这个功能方便的应对数据缩小或膨胀。 -
一个
Partition
的Bucket
数量一旦指定,不可更改。所以在确定Bucket
数量时,需要预先考虑集群扩容的情况。比如当前只有3
台host
,每台host
有1
块盘。如果Bucket
的数量只设置为3
或更小,那么后期即使再增加机器,也不能提高并发度。 -
举一些例子:假设在有
10
台BE
,每台BE
一块磁盘的情况下。如果一个表总大小为500MB
,则可以考虑4-8
个分片。5GB
:8-16
个分片。50GB
:32
个分片。500GB
:建议分区,每个分区大小在50GB
左右,每个分区16-32
个分片。5TB
:建议分区,每个分区大小在50GB
左右,每个分区16-32
个分片。
Tip
表的数据量可以通过 SHOW DATA
命令查看(该命令的统计结果会有延迟),结果除以副本数,即表的数据量。
2 Random Distribution¶
-
如果
OLAP
表没有更新类型的字段,将表的数据分桶模式设置为RANDOM
,则可以避免严重的数据倾斜(数据在导入表对应的分区的时候,单次导入作业每个batch
的数据将随机选择一个tablet
进行写入)。 -
当表的分桶模式被设置为
RANDOM
时,因为没有分桶列,无法根据分桶列的值仅对几个分桶查询,对表进行查询的时候将对命中分区的全部分桶同时扫描,该设置适合对表数据整体的聚合查询分析而不适合高并发的点查询。 -
如果
OLAP
表的是Random Distribution
的数据分布,那么在数据导入的时候可以设置单分片导入模式(将load_to_single_tablet
设置为true
),那么在大数据量的导入的时候,一个任务在将数据写入对应的分区时将只写入一个分片,这样将能提高数据导入的并发度和吞吐量,减少数据导入和Compaction
导致的写放大问题,保障集群的稳定性。