数据倾斜在 Spark SQL 中是如何发生的?请列举几种常见的处理手段与优化措施,并说明各自的适用条件。
考察说明
考查对 Spark SQL 数据倾斜的成因、定位及常用优化方案的掌握程度。
回答思路
- 【回答框架 1】数据倾斜的本质是某些 key 的数据量远大于其他 key,导致单个分区任务处理时间过长。常见成因包括 key 分布不均、join 时关联键大量重复、group by 或 distinct 的 key 热点,以及空值或默认值集中等。
- 【回答框架 2】定位方法:在 Spark UI 中观察 stage 中 task 的运行时间分布和 shuffle 读写量,若某一 task 的 input/shuffle 数据量远大于其他 task,即可判断存在倾斜。也可通过日志或事件历史服务器分析特定 stage 的 task metrics。
- 【回答框架 3】优化策略一:两阶段聚合(local 加 global)适用于 group by 和聚合场景,先在 map 端进行部分聚合,再对随机加盐后的 key 进行二次聚合,可显著缓解单点压力。
- 【回答框架 4】优化策略二:对于 join 倾斜,可对热点 key 加盐后广播小表,或将大表过滤出倾斜 key 单独与小表加盐 join,再将结果与正常 key 的 join 结果合并。若小表足够小,可直接使用广播 join 避免 shuffle。
- 【回答框架 5】其他手段包括调整分区数、过滤空值或异常值、使用随机前缀分散热点、以及考虑在数据存储阶段进行预聚合或分桶。实践中需结合具体执行计划(explain)和资源情况选择方案。
- 【关键点 1】倾斜本质是数据分布不均导致个别 task 过慢。
- 【关键点 2】通过 Spark UI 定位倾斜对应的 stage 和 task。
- 【关键点 3】group by 用两阶段聚合加盐处理。
- 【关键点 4】join 倾斜可用广播 join 或对热点 key 加盐分拆。
- 【关键点 5】调整并行度和过滤异常 key 也可辅助缓解。
- 【易错点 1】不要盲目调大 shuffle 分区数,可能增加小文件且不解决数据分布不均。
- 【易错点 2】广播 join 仅适合小表,大表广播会导致 driver 压力或 OOM。
- 【易错点 3】加盐处理热点 key 后,需确保聚合结果正确性,避免盐值引入重复计算。