Doris数据分桶
Doris 支持两层的数据划分。第一层是 Partition,支持 Range 和 List 的划分方式。第二层是 Bucket(Tablet),支持 Hash 和 Random 的划分方式。
当创建一个无分区的表时,默认还是会有一个不可见的单分区。在这个分区之下在根据分桶键(DISTRIBUTED BY HASH(user_id) )进行数据分桶,会按设置的数量(BUCKETS 16)进行HASH计算来确定每一个记录放在哪个桶(Tablet)。
分桶键根据实际情况进行设置,下面对分桶进行部分说明:
- 如果使用了 Partition,则
DISTRIBUTED ...
语句描述的是数据在各个分区内的划分规则。如果不使用 Partition,则描述的是对整个表的数据的划分规则。 - 分桶列可以是多列,Aggregate 和 Unique 模型必须为 Key 列,Duplicate 模型可以是 key 列和 value 列。分桶列可以和 Partition 列相同或不同。
- 分桶列的选择,是在 查询吞吐 和 查询并发 之间的一种权衡:
- 如果选择多个分桶列,则数据分布更均匀。如果一个查询条件不包含所有分桶列的等值条件,那么该查询会触发所有分桶同时扫描,这样查询的吞吐会增加,单个查询的延迟随之降低。这个方式适合大吞吐低并发的查询场景。
- 如果仅选择一个或少数分桶列,则对应的点查询可以仅触发一个分桶扫描。此时,当多个点查询并发时,这些查询有较大的概率分别触发不同的分桶扫描,各个查询之间的IO影响较小(尤其当不同桶分布在不同磁盘上时),所以这种方式适合高并发的点查询场景。
- AutoBucket: 根据数据量,计算分桶数。 对于分区表,可以根据历史分区的数据量、机器数、盘数,确定一个分桶。
- 分桶的数量理论上没有上限。
数据分桶数的一些建议,可根据实际性能表现调整:
- 假设表/分区数据量在kb级别到50MB级别可考虑设置1个分桶
- 假设表/分区数据量在50MB到1GB级别可考虑设置1~10个分桶
- 假设表/分区数据量在1GB到5GB级别可考虑设置5~20个分桶
- 假设表/分区数据量在5GB到100GB级别建议设置10~100个分桶
案例1:当一个小表设置的分桶数量过多会严重影响查询关联速度。
XXXXXXXXX表数据量只有几百k,初始设置了60个分桶,用户反馈需要一分多钟才会关联出结果。
该现象就是因为分桶数设置太高,增加了数据聚合的网络开销,导致速度慢,改成2个分桶,只需要不到一秒,就可以返回结果
案例2:单分桶键可能会引发分桶数据倾斜。
一般在设置分桶键时可以优先选择where条件常用的过滤键,能在查询时获取更好的查询性能,但有时hash分桶后造成桶之间数据分布不均衡,严重时会对查询和关联产生较大影响,此时可以选择多个分桶键,将数据在进行打散。
此外分桶键可以设置Random,这种情况数据分布更均匀。Random分桶会将数据随机分发到各个数据分桶中,可以保证各数据分桶相对均衡,但同时可能会影响一些情况下的查询性能。
DISTRIBUTED BY RANDOM [BUCKETS num|auto]