某个BE忙死了其他BE闲着——Doris数据倾斜怎么排查和解决?
本文目录
先说结论
Doris数据倾斜有两种:存储倾斜和查询倾斜。存储倾斜是某些Tablet数据量远大于其他(分桶列选错了);查询倾斜是某些BE处理的数据量远多于其他(GROUP BY某个Key数据量太大)。解决方案:① 选高基数列做分桶列;② 多列组合分桶;③ 调整桶数。
先把这段讲顺;面试官追问时,再展开下面的原理和细节。
详细讲解
数据倾斜不只是Spark和Kafka的问题,Doris也会有。在某元宇宙社交公司,有一次发现查询性能突然变差。Profile里看到一个BE的扫描耗时是其他BE的8倍。排查下来是分桶列选了一个低基数字段(country),中国用户占了70%的数据,全部集中在一个Tablet里。
怎么发现倾斜?——三种方法
倾斜的根因:分桶列选错了
| 分桶列 | 基数 | 分布 | 是否适合 |
|---|---|---|---|
| user_id | 千万级 | 均匀 | 最佳选择 |
| device_id | 百万级 | 均匀 | 好 |
| event_id | 极高 | 均匀但查询不常用 | 均匀但不利于桶裁剪 |
| country | 几十个 | 不均匀(中国70%) | 严重倾斜 |
| gender | 2-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倾斜用两阶段聚合)。能讲出完整修复经历的面试官会认可你的实战经验。