Spark AQE 配置和源码说明

本文深入探讨Spark 3.2.0的Adaptive Query Execution (AQE)机制,详细介绍了AQE的配置选项,如`spark.sql.adaptive.enabled`,以及调用流程,包括`toRdd`、`executedPlan`、`prepareForExecution`等关键步骤。文章还概述了AQE在Stage创建前后的优化规则及其应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

网摘:AQE(Adaptive Query Execution)自适应查询,是Spark 3.0开始增加的一种机制,可以根据 Shuffle Map阶段的统计信息,基于预设的规则 动态 地调整和修正尚未执行逻辑计划和物理计划,来完成对原始查询语句的运行时优化。

该文基于Spark 3.2.0版本,进行AQE的配置以及源码说明,主要的源码实现都在下面这个包:

org.apache.spark.sql.execution.adaptive

1. AQE流程梳理

先简单根据实际代码下一个结论,生成物理执行计划之后,根据AQE和其他的计算规则,选中一个最终待支持的物理计划,在QueryExecution代码里大概就是这样:

sparkPlan -> AQE -> executedPlan

  lazy val sparkPlan: SparkPlan = withCteMap {
    // We need to materialize the optimizedPlan here because sparkPlan is also tracked under
    // the planning phase
    assertOptimized()
    executePhase(QueryPlanningTracker.PLANNING) {
      // Clone the logical plan here, in case the planner rules change the states of the logical
      // plan.
      QueryExecution.createSparkPlan(sparkSession, planner, optimizedPlan.clone())
    }
  }

  // executedPlan should not be used to initialize any SparkPlan. It should be
  // only used for execution.
  lazy val executedPlan: SparkPlan = withCteMap {
    // We need to materialize the optimizedPlan here, before tracking the planning phase, to ensure
    // that the optimization time is not counted as part of the planning phase.
    assertOptimized()
    executePhase(QueryPlanningTracker.PLANNING) {
      // clone the plan to avoid sharing the plan instance between different stages like analyzing,
      // optimizing and planning.
      QueryExecution.prepareForExecution(preparations, sparkPlan.clone())
    }
  }

1.1 AQE配置说明

spark.sql.adaptive.enabled 这个是AQE的开关配置,默认是打开的。

spark.sql.adaptive.forceApply 这个是AQE强制执行的开关配置,AQE会跳过没有shuffle的查询或者没有子查询的查询,这个配置默认是会跳过没有shuffle或者没有子查询的执行计划,,因为在这些场景下AQE对于性能提升没有帮助。这个配置是internal的,即外部的配置是更改不了的。

//AQE是否打开
val ADAPTIVE_EXECUTION_ENABLED = buildConf("spark.sql.adaptive.enabled")
    .doc("When true, enable adaptive query execution, which re-optimizes the query plan in the " +
      "middle of query execution, based on accurate runtime statistics.")
    .version("1.6.0")
    .booleanConf
    .createWithDefault(true)


//AQE会跳过没有shuffle的查询或者没有子查询的查询,这个配置默认是关闭的,即对于没有shuffle或者没有子查询的执行计划,直接跳过了,因为对于性能提升没有帮助,这个配置是internal的,即外部的配置是更改不了的。
val ADAPTIVE_EXECUTION_FORCE_APPLY = buildConf("spark.sql.adaptive.forceApply")
### Spark自适应查询执行(AQE)功能及配置 Spark的自适应查询执行(Adaptive Query Execution, AQE)是Spark 3.0引入的一项重要功能,旨在通过动态调整查询计划来优化查询性能。以下是关于AQE的功能配置的详细介绍: #### 1. AQE的核心概念 AQE允许Spark在运行时根据已知的数据分布动态调整查询计划,从而避免基于静态统计信息生成的次优计划。其主要改进包括以下几个方面[^4]: - **动态分区裁剪**:在运行时确定哪些分区需要被扫描,减少不必要的数据读取。 - **动态合并小文件**:在Shuffle阶段后合并小文件以减少任务数量。 - **动态调整Shuffle分区数**:根据实际数据量动态调整Shuffle分区的数量。 #### 2. AQE的启用与配置 要启用AQE功能,可以通过设置以下配置参数来实现[^4]: ```properties spark.sql.adaptive.enabled=true ``` 此外,还可以对其他相关参数进行调整以进一步优化AQE的行为,例如: - `spark.sql.adaptive.shuffle.targetPostShuffleInputSize`:设置每个Shuffle分区的目标大小(默认为64MB)。 - `spark.sql.adaptive.coalescePartitions.enabled`:启用动态合并小文件(默认为true)。 - `spark.sql.adaptive.coalescePartitions.minPartitionNum`:设置合并后的最小分区数。 #### 3. AQE的工作流程 AQE的工作流程可以分为以下几个阶段[^4]: - **逻辑计划优化**:在编译阶段生成初始逻辑计划。 - **物理计划生成**:基于初始逻辑计划生成物理计划。 - **运行时优化**:在运行时根据实际数据分布调整物理计划。 #### 4. 示例代码 以下是一个简单的示例,展示如何通过`spark-submit`提交一个启用了AQESpark作业[^2]: ```bash spark-submit \ --class org.apache.examples.SparkPi \ --master local \ --conf spark.sql.adaptive.enabled=true \ ../examples/jars/spark-examples_2.12-3.0.0.jar 10 ``` #### 5. 性能改进 AQE通过减少不必要的数据读取、合并小文件以及优化Shuffle分区数等方式显著提升了查询性能[^4]。此外,结合Dataset API的优势,可以进一步减少序列化反序列化的开销[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值