订阅更新

某个BE忙死了其他BE闲着——Doris数据倾斜怎么排查和解决?

Doris手册 第 12 题 约 3 分钟读完

本文目录
  1. 先说结论
  2. 怎么发现倾斜?——三种方法
  3. 倾斜的根因:分桶列选错了
  4. 解法一:选高基数列做分桶列(推荐)
  5. 解法二:多列组合分桶
  6. 查询时的Runtime倾斜
  7. 实战踩坑:分桶列选country导致的倾斜
  8. 面试高频追问
  9. 总结

先说结论

Doris数据倾斜有两种:存储倾斜和查询倾斜。存储倾斜是某些Tablet数据量远大于其他(分桶列选错了);查询倾斜是某些BE处理的数据量远多于其他(GROUP BY某个Key数据量太大)。解决方案:① 选高基数列做分桶列;② 多列组合分桶;③ 调整桶数。

先把这段讲顺;面试官追问时,再展开下面的原理和细节。

详细讲解

数据倾斜不只是Spark和Kafka的问题,Doris也会有。在某元宇宙社交公司,有一次发现查询性能突然变差。Profile里看到一个BE的扫描耗时是其他BE的8倍。排查下来是分桶列选了一个低基数字段(country),中国用户占了70%的数据,全部集中在一个Tablet里。

怎么发现倾斜?——三种方法

倾斜的根因:分桶列选错了

分桶列基数分布是否适合
user_id千万级均匀最佳选择
device_id百万级均匀好
event_id极高均匀但查询不常用均匀但不利于桶裁剪
country几十个不均匀(中国70%)严重倾斜
gender2-3个不均匀极度倾斜
dt(日期)按天每天数据量不同应该做分区列不是分桶列

解法一:选高基数列做分桶列(推荐)

解法二:多列组合分桶

权衡:多列组合分桶数据更均匀,但桶裁剪条件更严格。如果大部分查询只按user_id过滤,不如单列HASH(user_id)。

查询时的Runtime倾斜

实战踩坑:分桶列选country导致的倾斜

在某元宇宙社交公司,用户行为表一开始DISTRIBUTED BY HASH(country) BUCKETS 16。用户覆盖全球50+国家,看起来基数还行。但实际上中国用户占了70%、美国15%、其他国家合计15%。

结果:hash('CN') % 16 = 3,Tablet-3的数据量是其他Tablet平均值的10倍。查询时BE-1负责Tablet-3,CPU打满;其他BE几乎空闲。

修复过程:① 创建新表分桶列改为user_id;② INSERT INTO逐分区迁移数据;③ 验证Tablet分布均匀;④ 切换应用查询到新表;⑤ 删除旧表。整个迁移花了2天。

教训:分桶列选择是建表时最重要的决策——一旦选错了后期改很痛苦(要重建表迁移数据)。建表前一定要分析数据分布。

面试高频追问

追问一:怎么判断倾斜是存储层还是查询层的?

SHOW TABLET看DataSize差异大是存储倾斜;Tablet大小均匀但Profile里某个BE耗时远大于其他是查询倾斜。两种解法不同。

追问二:Doris的数据倾斜和Spark的有什么异同?

原理类似。区别是Spark的倾斜在Shuffle阶段(运行时),可用AQE处理;Doris的存储倾斜是建表时决定的,一旦选错需要重建表。所以Doris的分桶列选择比Spark更不可逆。

追问三:能不能用Random分桶避免倾斜?

Doris支持DISTRIBUTED BY RANDOM。好处是绝对不倾斜,坏处是失去桶裁剪能力。适用于大批量聚合查询为主的场景。

总结

Doris数据倾斜面试讲三点:① 怎么发现(Profile看BE耗时差异、SHOW TABLET看数据分布);② 根因(分桶列选了低基数字段);③ 解决方案(换高基数列、多列组合、调桶数、Runtime倾斜用两阶段聚合)。能讲出完整修复经历的面试官会认可你的实战经验。

刷题进度保存在当前浏览器