当前位置: 首页 > news >正文

Doris 数据均衡之道:四步教你通过分区和分桶策略彻底解决数据倾斜

Doris 数据均衡之道:四步教你通过分区和分桶策略彻底解决数据倾斜

    • 前言:那些年,我们一起踩过的数据倾斜坑
    • 一、 挖出祸根:为什么你的数据会倾斜?
    • 二、 四步策略:手把手教你做数据均衡
      • 第 1 步:选对“分区”粒度,控制物理体积
      • 第 2 步:校准“分桶键”,这是倾斜的重灾区
      • 第 3 步:调整“分桶数”,让 Tablet 大小刚刚好
      • 第 4 步:祭出大招——Random 分桶(解决无解之症)
    • 三、 实战思维导图:选哪种策略?
    • 四、 避坑指南:这些骚操作千万别做
    • 总结

🌺The Begin🌺点点关注,收藏不迷路🌺

别再让那几个“热点”节点累死,其他节点却在旁边看热闹了!

前言:那些年,我们一起踩过的数据倾斜坑

作为一个常年混迹于大数据圈的“老司机”,Doris 的高并发、低延迟能力确实让我们爱不释手。但在实际的生产环境中,数据倾斜却像一个幽灵,总在不经意间给我们的查询性能当头一棒。

你是否遇到过这种情况:明明集群有 10 台 BE(后端服务节点),跑一个简单的 Group By 查询,大部分节点都跑完了,唯独有那么 1-2 个节点 CPU 飙到 100%,大家都在等它。这就是典型的数据倾斜

今天,我们不聊虚的,直接深入 Doris 的分区分桶机制,通过一套标准化的四步法,从根源上解决数据分布不均的问题。


一、 挖出祸根:为什么你的数据会倾斜?

在 Doris 中,数据分布遵循Table -> Partition -> Bucket -> Tablet的层级结构。

倾斜通常发生在两个环节:

  1. 分区内部数据不均:虽然分了区,但数据在分桶时由于分桶键(Hash Key)选择不当,导致大量数据被 Hash 到同一个 Bucket 中。
  2. 分区数据量差异过大:例如按天分区,但周末的数据量和周一到周五的数据量差异巨大,导致某些分区的 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_idorder_iddevice_code

验证方法(数据质量检查):
在决定分桶键之前,先跑一把 SQL 看一眼分布:

-- 假设你打算拿 column_c 做分桶键SELECTcolumn_c,COUNT(*)ascntFROMyour_tableGROUPBYcolumn_cORDERBYcntDESCLIMIT10;

如果前几名(Top 10)的数据量占比超过总数据量的30%,这个列就不适合做 Hash 分桶键。

第 3 步:调整“分桶数”,让 Tablet 大小刚刚好

分桶数(Buckets)决定了并行度,也决定了单节点的压力。

计算公式与最佳实践:
每个 Bucket(Tablet)的数据量(压缩后)保持在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 RANDOM,Doris 帮你搞定均匀分布CREATETABLEIFNOTEXISTSexample_tbl(`user_id`LARGEINTNOTNULL,`date`DATENOTNULL,`city`VARCHAR(20),`cost`BIGINTSUMDEFAULT"0")AGGREGATEKEY(`user_id`,`date`,`city`)DISTRIBUTEDBYRANDOM BUCKETS16;-- 注意:这里没有分桶列!

三、 实战思维导图:选哪种策略?

为了让你在 5 秒内找到适合自己的方案,我整理了下方的决策树:

否(全表扫描较多)

开始设计表

数据量是否超过 50亿?

必须使用分区+分桶

可以不分区,直接分桶

是否存在明显的查询列?

该列数据是否均匀?

Hash 分桶
该列作为分桶键
设置合理桶数

是否有多个列组合能变均匀?

Hash 分桶
使用多列组合键

Random 分桶
放弃分桶剪裁,换取绝对均衡


四、 避坑指南:这些骚操作千万别做

以下几个“雷区”千万不要踩:

  1. 禁止使用 Auto Bucket 无脑模式:虽然 Doris 支持自动设置分桶数,但在生产环境中,自动策略可能会生成过多的小 Bucket(Tablet),导致小文件问题,拖慢 NameNode 和 Doris FE。手动指定BUCKETS N更可控
  2. 严禁低基数列做 Hash 分桶:再次强调,不要用sexstatusregion(如果只有几个大区)做主分桶键。血的教训!
  3. 分桶数不是越多越好:分桶数 = 并行度。但如果你的集群只有 3 台机器,设置 100 个 Bucket,每个 Bucket 数据量极小,不仅浪费资源,还会导致 Scan 算子调度开销过大。
  4. 区分表模型UNIQUE KEYAGGREGATE KEY模型下,分桶列必须是 Key 列。如果你非要用 Value 列做分桶,系统会报错或者产生不可预知的结果。

总结

解决 Doris 数据倾斜,本质上是一场“数据分布的艺术”

  • 分区负责“粗粒度”的隔离(主要是时间),帮你快速定位范围。
  • 分桶负责“细粒度”的打散,这才是均衡的关键。
  • Random则是当你无计可施时的“核武器”

最佳实践组合拳:
合理的分区(天/月)+高基数的 Hash 分桶(User_ID/Order_ID)+单个 Tablet 大小控制在 10GB 左右

按照这套方法论去做,你的 Doris 集群查询速度会有质的飞跃。如果你还在为数据不均头疼,赶紧去检查一下你的建表语句吧!


🌺The End🌺点点关注,收藏不迷路🌺
http://www.jsqmd.com/news/568642/

相关文章:

  • FMCW雷达实战:如何用Python快速解析雷达数据立方体(附完整代码)
  • 手把手教你为STM32G474自制开发板:从原理图到PCB布局的避坑指南(附GitHub工程)
  • Android Camera2开发:从抖音/微信的‘全屏拍摄’需求,到你的App适配方案
  • 从地震波到合成记录:用Python+NumPy手把手模拟地震勘探核心原理
  • Zotero Duplicates Merger:终极文献去重插件完全指南
  • 颠覆式原神辅助工具:Snap Hutao革新性游戏体验解析
  • 生信实战(一)——DESeq2差异基因分析从原理到可视化
  • OpCore-Simplify:零代码黑苹果配置终极指南,3步完成专业级EFI搭建
  • OpenCore Legacy Patcher实用指南:让老旧Mac焕发新生
  • 假芯片泛滥现状与识别防范指南
  • 保姆级教程:用乐鑫官方工具给ESP8266烧写MQTT透传固件(附CH340驱动安装)
  • OpenCore Legacy Patcher终极指南:四步解决老Mac显卡驱动与系统升级问题
  • 解决Error 500: named symbol not found报错问题
  • 保姆级教程:用ENVI 5.6和SARscape 5.6搞定国产GF3雷达影像预处理(附参数设置避坑点)
  • 高并发分布式存储系统的设计与实践
  • 百度网盘解析工具:突破下载限制的高效解决方案与极速体验
  • Paddle Inference实战:从模型加载到推理优化的全流程解析
  • 告别臃肿字体库!在嵌入式Linux上用FreeType 2.13.2为LVGL 8.3动态加载字体(GUI Guider 1.7.0工程实战)
  • 【Matlab】MATLAB教程:图形句柄;案例:h=plot(x,y);应用:控制图形属性
  • 如何轻松地将联系人从 iPhone 转移到 OnePlus?
  • PL-2303串口驱动Windows 10兼容性解决方案:从故障排查到深度优化
  • 消息撤回终结者:揭秘RevokeMsgPatcher的3个隐藏用法
  • AzurLaneAutoScript:碧蓝航线全自动游戏助手,释放您的双手与时间
  • 【车规Java安全合规白皮书】:ISO 21434与ASPICE Level 3双认证下,6类高危代码模式自动拦截实践
  • Stata绘图小白必看:5种常用图表从入门到美化(附完整代码)
  • RTX3070+Windows11深度学习环境搭建:CUDA与PyTorch版本选择指南
  • Gluegun模板系统完全教程:快速生成项目文件的秘密武器
  • iarduino_KB矩阵键盘库:硬件感知型Arduino按键驱动方案
  • 一键切换淘宝npm镜像源:2024最新配置指南
  • C-index避坑指南:生存分析中90%人会犯的5个评估错误