如果一张表数据非常大,并且分桶数量有问题就会出现数据倾斜。 分桶(Bucketing)的根本目的是**将数据打散,使其均匀地分布到所有BE节点上**。每个桶就是一个数据分片,在Doris中称为**Tablet**。 - **数据均匀分布**:可以避免数据倾斜,防止单个BE节点成为写入或查询的瓶颈。这对于高成本的**主键模型(Merge-on-Write)** 尤为重要。 - **最大化并行处理**:当查询或写入发生时,Doris可以同时在多个BE节点上的多个Tablet上并行执行任务,从而大幅提升效率。 ### 黄金法则:分桶数与节点数的关系 #### 法则1:分桶数应该是BE节点数的整数倍 这是为了保证每个BE节点上的Tablet数量完全相等。 - **场景**: 3个BE节点,副本数通常为3。 - **如果分桶数为10**: Doris会尝试均匀分配,但无法做到绝对平均。可能会出现类似 `BE1: 4个Tablet, BE2: 3个Tablet, BE3: 3个Tablet` 的情况(这只是一个示意,实际分配更复杂),导致轻微的负载不均。 - **如果分桶数为12 (3的倍数)**: Doris可以精确地为每个BE节点分配 `12 / 3 = 4` 个Tablet(的主副本)。这样在数据写入和查询时,负载可以完美地均分到3个节点上。 #### 法则2:总Tablet数量要适中 一个分区的总Tablet数 = **分桶数 × 副本数**。 单个BE节点上的Tablet数 = **分桶数** (在副本数为3,BE节点为3的典型情况下)。 Doris官方和社区的最佳实践建议: - **单个BE节点上的Tablet总数不宜过多**:过多的Tablet会增加FE的元数据管理压力,增加RPC开销,并可能导致Compaction调度不及时,产生大量小文件。 - **单个Tablet的数据量不宜过小或过大**: - **太小(< 100MB)**: 说明分桶太多,增加了管理开销,且无法发挥Doris列存和压缩的优势。 - **太大(> 10GB)**: 可能导致单Tablet的Compaction时间过长,或者在节点故障时,单个Tablet的迁移恢复时间过长。 - **理想范围**: 单个Tablet的数据量建议保持在 **100MB ~ 1GB** 之间。 ### 如何计算最适合你的分桶数? 这是一个自上而下的推算过程: 1. **预估分区数据量**: 评估一下您的表,单个分区(通常是一天或一个月)的数据增量大概是多少?例如,我们预估一天的数据量是 `50 GB`。 2. **设定理想Tablet大小**: 我们选择一个理想的Tablet大小,比如 `1 GB`。 3. **计算理想分桶数**: - 理想Tablet总数 = 分区数据量 / 理想Tablet大小 = `50 GB / 1 GB = 50` 个。 - 因为总Tablet数 = 分桶数 × 副本数,所以: - 理想分桶数 = 理想Tablet总数 / 副本数 = `50 / 3 ≈ 16.7`。 4. **结合“法则1”进行调整**: - 我们计算出的理想分桶数是 `16.7`。 - 我们需要找到一个最接近 `16.7` 并且是 `3` 的倍数的数字。 - `15` 和 `18` 都是很好的选择。在这种情况下,选择 `18` 会让Tablet更小一些,更灵活;选择 `15` 会让Tablet更大一些,管理开销更小。两者都是合理的。