请描述 Spark 中 DAG 执行计划的生成过程,并探讨如何通过优化 DAG 来降低执行开销。
考察说明
考查对 Spark 任务调度核心机制的理解以及 DAG 优化的实践能力。
回答思路
- 【回答框架 1】Spark 中 DAG 由 Action 操作触发构建,从 RDD 依赖关系出发,通过血缘关系(lineage)记录宽窄依赖,形成有向无环图。窄依赖(如 map)可流水线执行,宽依赖(如 shuffle)产生 Stage 划分。DAGScheduler 根据宽依赖划分 Stage,每个 Stage 包含一组可并行执行的任务。
- 【回答框架 2】TaskScheduler 将 Stage 中的任务集提交到集群执行,每个任务处理一个分区。DAG 生成过程包括:逻辑计划到物理计划的转换,涉及算子链合并、分区器选择等优化。
- 【回答框架 3】优化 DAG 以减少执行开销的方法:1) 减少 shuffle,通过合理使用聚合算子(如 reduceByKey vs groupByKey)或调整分区数;2) 使用广播变量避免大表 join 的 shuffle;3) 通过缓存(persist)复用中间结果,避免重复计算;4) 采用数据本地性调度,减少网络传输;5) 使用 coalesce 减少分区数等。
- 【回答框架 4】实践技巧:利用 Spark UI 查看 DAG 图,识别执行计划中的瓶颈,如数据倾斜、过度 shuffle;根据任务特点调整并行度、内存配置等。
- 【关键点 1】DAG 由 Action 触发,基于 RDD 血缘构建,宽依赖决定 Stage 划分。
- 【关键点 2】窄依赖允许流水线执行,减少调度开销。
- 【关键点 3】优化核心是减少 shuffle 和重复计算,利用缓存和广播变量。
- 【关键点 4】数据本地性影响任务调度效率,应尽量使任务在数据所在节点执行。
- 【关键点 5】可通过 Spark UI 的 DAG 可视化辅助排查性能问题。
- 【易错点 1】误认为所有 shuffle 都可避免,实际上某些操作如 join 必须 shuffle。
- 【易错点 2】过度缓存可能导致内存压力,需权衡存储级别。
- 【易错点 3】依赖单一优化技巧,忽视集群资源、数据倾斜等综合因素。