0%

资源调度与执行计划优化

资源调度与执行计划优化

一句话定位:作业跑得快不快,一半在资源撮合(能不能拿到合适的容器),一半在执行计划(会不会自适应地选对分区数和 Join 策略)。Spark 3 的 AQE 把后者从”人肉调参”变成了”运行时自适应”。

1. YARN / K8s 资源撮合

  • YARN:ResourceManager 按 Container 申请(内存 + vcore)在 NodeManager 上分配;Capacity/Fair 调度器决定队列配额与共享;受 min-allocation / increment 规整化影响,实际占用常大于申请(见 Spark 资源评估)。
  • K8s:executor 以 Pod 申请,由 kube-scheduler 按节点资源/亲和性调度;支持动态资源分配与 Spot/抢占,弹性更好。

2. 任务优先级与抢占

  • 队列/作业设优先级,高优先级优先获得资源。
  • 抢占(Preemption):Fair/Capacity 模式下,在优雅终止期内回收低优先级容器的资源给高优先级,保障关键作业 SLA。
  • 代价:被抢占作业需重试/重算对应 partition,设计上要容忍。

3. AQE(自适应查询执行,Spark 3.0+)

运行时基于 shuffle 统计动态调整执行计划,三项核心能力:

  1. 分区合并(Coalesce Partitions):把多个小 post-shuffle 分区合并,避免小 task 过多、调度开销爆炸(无需手动设 spark.sql.shuffle.partitions)。
  2. 倾斜处理(Skew Join):检测到倾斜分区(> 中位数 N 倍且超阈值)自动拆分为多 task 并行(见 1.1.2 数据倾斜)。
  3. Join 策略切换:运行时若某表小于 spark.sql.autoBroadcastJoinThreshold,把 SortMergeJoin 动态转 BroadcastHashJoin,免 Shuffle。
  • 收益:对数据量/分布不确定的 ad-hoc 查询尤其明显;把”凭经验调参”变为”运行时自适应”。

4. 执行计划优化

  • explain() 读懂物理计划;开启 CBO(需列统计/直方图)让优化器选更优 Join 顺序;
  • 配合广播阈值、谓词下推、列裁剪,减少 shuffle 与扫描量。

参考:Apache Spark 官方文档 Adaptive Query Execution / Running Spark on YARN / Kubernetes