Doris 数据均衡之道四步教你通过分区和分桶策略彻底解决数据倾斜前言那些年我们一起踩过的数据倾斜坑一、 挖出祸根为什么你的数据会倾斜二、 四步策略手把手教你做数据均衡第 1 步选对“分区”粒度控制物理体积第 2 步校准“分桶键”这是倾斜的重灾区第 3 步调整“分桶数”让 Tablet 大小刚刚好第 4 步祭出大招——Random 分桶解决无解之症三、 实战思维导图选哪种策略四、 避坑指南这些骚操作千万别做总结The Begin点点关注收藏不迷路别再让那几个“热点”节点累死其他节点却在旁边看热闹了前言那些年我们一起踩过的数据倾斜坑作为一个常年混迹于大数据圈的“老司机”Doris 的高并发、低延迟能力确实让我们爱不释手。但在实际的生产环境中数据倾斜却像一个幽灵总在不经意间给我们的查询性能当头一棒。你是否遇到过这种情况明明集群有 10 台 BE后端服务节点跑一个简单的 Group By 查询大部分节点都跑完了唯独有那么 1-2 个节点 CPU 飙到 100%大家都在等它。这就是典型的数据倾斜。今天我们不聊虚的直接深入 Doris 的分区与分桶机制通过一套标准化的四步法从根源上解决数据分布不均的问题。一、 挖出祸根为什么你的数据会倾斜在 Doris 中数据分布遵循Table - Partition - Bucket - Tablet的层级结构。倾斜通常发生在两个环节分区内部数据不均虽然分了区但数据在分桶时由于分桶键Hash Key选择不当导致大量数据被 Hash 到同一个 Bucket 中。分区数据量差异过大例如按天分区但周末的数据量和周一到周五的数据量差异巨大导致某些分区的 Tablet 压力过大。流程图数据写入与分布逻辑Range/List计算 Hash 值Hash 分桶Random 分桶分桶键选择错误数据流分区策略划分到具体分区分桶策略分桶键高基数/均匀随机写入数据倾斜!Tablet 分布均匀部分 Tablet 数据过大查询性能优良查询性能瓶颈/节点过热二、 四步策略手把手教你做数据均衡以下四步策略是基于生产环境踩坑经验的总结。第 1 步选对“分区”粒度控制物理体积分区的主要目的是减少扫描数据量但如果分区设计不当也会加剧倾斜。场景分析如果你的业务数据量在10亿级别以下且没有明确的删除旧数据需求不要过度分区过度分区例如按小时分区会产生大量小文件导致元数据膨胀和调度开销。操作建议时间序列数据建议按天或月分区。确保单个分区内的数据量在20GB 到 100GB之间为宜。兜底策略如果是 2000万 以内的维表或小表直接使用默认分区即不写分区语句仅靠分桶即可避免“大炮打蚊子”。第 2 步校准“分桶键”这是倾斜的重灾区分桶键的选择是解决倾斜的核心。Doris 使用 Hash 算法将数据映射到不同的 Bucket。反面教材常见错误很多新手喜欢按日期或省份或枚举类型进行 Hash 分桶。如果按is_vip(0或1) 分桶那么 50% 的数据会涌入少数几个桶这是典型的低基数陷阱。正面教材黄金法则选择高基数、分布均匀且常用于 Join 或 Where 条件的列。例如user_id、order_id、device_code。验证方法数据质量检查在决定分桶键之前先跑一把 SQL 看一眼分布-- 假设你打算拿 column_c 做分桶键SELECTcolumn_c,COUNT(*)ascntFROMyour_tableGROUPBYcolumn_cORDERBYcntDESCLIMIT10;如果前几名Top 10的数据量占比超过总数据量的30%这个列就不适合做 Hash 分桶键。第 3 步调整“分桶数”让 Tablet 大小刚刚好分桶数Buckets决定了并行度也决定了单节点的压力。计算公式与最佳实践每个 BucketTablet的数据量压缩后保持在1GB 到 20GB之间。场景 A数据量 10GB无需纠结设置BUCKETS 1或少量桶即可。过多的小文件会导致 Compaction 压力巨大。场景 B数据量 10GB - 200GB分桶数量 总数据量 / 2GB目标。例如 100GB 数据建议设置 50 个左右 Buckets。场景 C数据量 200GB优先扩大分区比如把日分区改成周分区而不是无限增加 Buckets。单个分区内 Buckets 不建议超过 1000 个否则 FE 元数据压力会很大。第 4 步祭出大招——Random 分桶解决无解之症如果你已经尝试了上述所有方法但你的表实在找不出一个均匀的高基数列例如数据全是null或者只有一个维度或者你不想动脑子管分桶键Random 分桶就是你的救星。核心原理数据导入时不按 Key 计算 Hash而是随机写入某个 Tablet。优缺点分析✅优点绝对的数据均衡彻底杜绝写入倾斜。❌缺点无法进行分桶剪裁。查询时将会扫描分区内的所有Bucket对于点查Point Query性能有影响适合全表扫描的聚合分析场景。建表示例-- 只需要指定 DISTRIBUTED BY RANDOMDoris 帮你搞定均匀分布CREATETABLEIFNOTEXISTSexample_tbl(user_idLARGEINTNOTNULL,dateDATENOTNULL,cityVARCHAR(20),costBIGINTSUMDEFAULT0)AGGREGATEKEY(user_id,date,city)DISTRIBUTEDBYRANDOM BUCKETS16;-- 注意这里没有分桶列三、 实战思维导图选哪种策略为了让你在 5 秒内找到适合自己的方案我整理了下方的决策树是否是是否是否否(全表扫描较多)开始设计表数据量是否超过 50亿?必须使用分区分桶可以不分区直接分桶是否存在明显的查询列?该列数据是否均匀?Hash 分桶该列作为分桶键设置合理桶数是否有多个列组合能变均匀?Hash 分桶使用多列组合键Random 分桶放弃分桶剪裁换取绝对均衡四、 避坑指南这些骚操作千万别做以下几个“雷区”千万不要踩禁止使用 Auto Bucket 无脑模式虽然 Doris 支持自动设置分桶数但在生产环境中自动策略可能会生成过多的小 BucketTablet导致小文件问题拖慢 NameNode 和 Doris FE。手动指定BUCKETS N更可控。严禁低基数列做 Hash 分桶再次强调不要用sexstatusregion如果只有几个大区做主分桶键。血的教训分桶数不是越多越好分桶数 并行度。但如果你的集群只有 3 台机器设置 100 个 Bucket每个 Bucket 数据量极小不仅浪费资源还会导致 Scan 算子调度开销过大。区分表模型UNIQUE KEY和AGGREGATE KEY模型下分桶列必须是 Key 列。如果你非要用 Value 列做分桶系统会报错或者产生不可预知的结果。总结解决 Doris 数据倾斜本质上是一场“数据分布的艺术”。分区负责“粗粒度”的隔离主要是时间帮你快速定位范围。分桶负责“细粒度”的打散这才是均衡的关键。Random则是当你无计可施时的“核武器”。最佳实践组合拳合理的分区天/月高基数的 Hash 分桶User_ID/Order_ID单个 Tablet 大小控制在 10GB 左右按照这套方法论去做你的 Doris 集群查询速度会有质的飞跃。如果你还在为数据不均头疼赶紧去检查一下你的建表语句吧The End点点关注收藏不迷路