【spark系列3】spark 3.0.1 AQE(Adaptive Query Exection)分析

本文介绍了Spark中AQE的发展历程,重点分析了Spark 3.0.1中AQE的配置,包括分区合并、数据倾斜优化等方面的核心代码,如ShufflePartitionsUtil.coalescePartition和OptimizeSkewedJoin.optimizeSkewJoin,还说明了相关规则的调用位置及注意事项。

AQE简介

spark configuration,到在最早在spark 1.6版本就已经有了AQE;到了spark 2.x版本,intel大数据团队进行了相应的原型开发和实践;到了spark 3.0时代,Databricks和intel一起为社区贡献了新的AQE

spark 3.0.1中的AQE的配置

配置项 默认值 官方说明 分析
spark.sql.adaptive.enabled false 是否开启自适应查询 此处设置为true开启
spark.sql.adaptive.coalescePartitions.enabled true 是否合并临近的shuffle分区(根据’spark.sql.adaptive.advisoryPartitionSizeInBytes’的阈值来合并) 此处默认为true开启,分析见: 分析1
spark.sql.adaptive.coalescePartitions.initialPartitionNum (none) shuffle合并分区之前的初始分区数,默认为spark.sql.shuffle.partitions的值 分析见:分析2
spark.sql.adaptive.coalescePartitions.minPartitionNum (none) shuffle 分区合并后的最小分区数,默认为spark集群的默认并行度 分析见: 分析3
spark.sql.adaptive.advisoryPartitionSizeInBytes 64MB 建议的shuffle分区的大小,在合并分区和处理join数据倾斜的时候用到 分析见:分析3
spark.sql.adaptive.skewJoin.enabled true 是否开启join中数据倾斜的自适应处理
spark.sql.adaptive.skewJoin.skewedPartitionFactor 5 数据倾斜判断因子,必须同时满足skewedPartitionFactor和skewedPartitionThresholdInBytes 分析见:分析4
spark.sql.adaptive.skewJoin.skewedPartitionThresholdInBytes 256MB 数据倾斜判断阈值,必须同时满足skewedPartitionFactor和skewedPartitionThresholdInBytes 分析见:分析4
spark.sql.adaptive.logLevel debug 配置自适应执行的计划改变日志 调整为info级别,便于观察自适应计划的改变
spark.sql.adaptive.nonEmptyPartitionRatioForBroadcastJoin 0.2 转为broadcastJoin的非空分区比例阈值,>=该值,将不会转换为broadcastjoin 分析见:分析5

分析1

OptimizeSkewedJoin.scala中,我们看到ADVISORY_PARTITION_SIZE_IN_BYTES,也就是spark.sql.adaptive.advisoryPartitionSizeInBytes被引用的地方, (OptimizeSkewedJoin是物理计划中的规则)

 /**
   * The goal of skew join optimization is to make the data distribution more even. The target size
   * to split skewed partitions is the average size of non-skewed partition, or the
   * advisory partition size if avg size is smaller than it.
   */
  private def targetSize(sizes: Seq[Long], medianSize: Long): Long = {
    val advisorySize = conf.getConf(SQLConf.ADVISORY_PARTITION_SIZE_IN_BYTES)
    val nonSkewSizes = sizes.filterNot(isSkewed(_, medianSize))
    // It's impossible that all the partitions are skewed, as we use median size to define skew.
    assert(nonSkewSizes.nonEmpty)
    math.max(advisorySize, nonSkewSizes.sum / nonSkewSizes.length)
  }

其中:

  1. nonSkewSizes为task非倾斜的分区
  2. targetSize返回的是max(非倾斜的分区的平均值,advisorySize),其中advisorySize为spark.sql.adaptive.advisoryPartitionSizeInBytes值,所以说
    targetSize不一定是spark.sql.adaptive.advisoryPartitionSizeInBytes值
  3. medianSize值为task的分区大小的中位值

分析2

SQLConf.scala

def numShufflePartitions: Int = {
    if (adaptiveExecutionEnabled && coalesceShufflePartitionsEnabled) {
      getConf(COALESCE_PARTITIONS_INITIAL_PARTITION_NUM).getOrElse(defaultNumShufflePartitions)
    } else {
      defaultNumShufflePartitions
    }
  }

从spark 3.0.1开始如果开启了AQE和shuffle分区合并,则用的是spark.sql.adaptive.coalescePartitions.initialPartitionNum,这在如果有多个shuffle stage的情况下,增加分区数,可以有效的增强shuffle分区合并的效果

分析3

CoalesceShufflePartitions.scala,CoalesceShufflePartitions是一个物理计划的规则,会执行如下操作

 if (!shuffleStages.forall(_.shuffle.canChangeNumPartitions)) {
      plan
   
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值