在 Apache Spark 中,有哪些策略可以减少或避免 shuffle?请列举并解释几种常见的 shuffle 优化方法。
考察说明
考查对 Spark shuffle 原理及优化手段的理解,以及在实际中减少 shuffle 开销的能力。
回答思路
- 【回答框架 1】shuffle 是 Spark 中数据在分区间重新分布的过程,涉及磁盘 IO、网络传输和序列化,是性能热点。避免 shuffle 的核心是尽量使数据在本地分区内完成计算,减少跨节点数据传输。
- 【回答框架 2】常用优化手段包括:使用 reduceByKey 代替 groupByKey,因为 reduceByKey 会在 map 端进行预聚合,减少传输数据量;使用广播变量代替 join 操作,适合小表与大表 join;使用累加器代替 reduce 操作,但需注意累加器只能用于计数等场景。
- 【回答框架 3】合理设置分区数和并行度,避免过多或过少的分区导致 shuffle 数据倾斜或资源浪费。使用 coalesce 减少分区数可以减少 shuffle 的再分配,但要注意可能导致数据倾斜。
- 【回答框架 4】可以通过调整 shuffle 相关参数如 spark.shuffle.compress 开启压缩,减少网络传输;使用 Kryo 序列化提高序列化效率;调整 spark.sql.shuffle.partitions 控制结果分区数。
- 【回答框架 5】在数据倾斜时,可使用 salting 技术给 key 加随机前缀,将热点 key 分散,再聚合结果;或使用两阶段聚合等方案。
- 【关键点 1】reduceByKey 在 map 端预聚合,减少 shuffle 数据量。
- 【关键点 2】广播变量适用于小表 join,避免 shuffle。
- 【关键点 3】合理设置分区数可减少 shuffle 开销。
- 【关键点 4】开启压缩和使用 Kryo 序列化可优化 shuffle 传输效率。
- 【关键点 5】数据倾斜可用 salting 技术缓解。
- 【易错点 1】广播变量仅适用于小数据,不能滥用,否则会 OOM。
- 【易错点 2】coalesce 使用不当可能导致数据倾斜,需要评估。
- 【易错点 3】reduceByKey 和 groupByKey 的语义不同,避免误解。