订阅更新

AQE开了以后作业快了3倍——自适应查询执行是怎么回事?

Spark手册 第 10 题 约 3 分钟读完

本文目录
  1. 先说结论
  2. 功能一:自动合并小分区(Coalesce Partitions)
  3. 功能二:自动切换Join策略(Dynamic Join Selection)
  4. 功能三:自动处理Skew Join(倾斜连接)
  5. 实战效果
  6. 总结

先说结论

AQE做三件事:自动合并小分区、自动切换Join策略、自动处理倾斜。全部是在运行时根据实际数据动态决定的,不需要你手动调参。

先把这段讲顺;面试官追问时,再展开下面的原理和细节。

详细讲解

AQE(Adaptive Query Execution)是Spark 3.0引入的最重磅功能,没有之一。它解决了一个核心问题:传统的Catalyst优化器基于统计信息做决策,但统计信息往往不准。AQE则是在运行时根据实际数据量动态调整执行计划。我在出海硬件公司迁到Databricks后全局开启AQE,整体作业性能提升了约40%。

功能一:自动合并小分区(Coalesce Partitions)

问题:你设了shuffle.partitions=200,但实际数据量很小,导致200个分区每个只有几KB——这些小Task的调度开销比实际计算时间还长。

AQE的解决方案:Shuffle Write完成后,根据实际的Shuffle数据量,自动合并过小的分区。比如200个分区合并成20个,每个分区数据量合理。

SET spark.sql.adaptive.enabled = true;
SET spark.sql.adaptive.coalescePartitions.enabled = true;
SET spark.sql.adaptive.coalescePartitions.minPartitionSize = 64m;
-- Shuffle后每个分区至少64MB,太小就合并

功能二:自动切换Join策略(Dynamic Join Selection)

问题:Catalyst在编译时根据表的统计信息选择Join策略。但统计信息可能过时或不准,导致选了不最优的Join方式。

AQE的解决方案:Shuffle Write完成后,知道了实际的数据量。如果发现其中一张表足够小(经过过滤后只剩20MB),自动将Sort Merge Join转换为Broadcast Join。

这个功能特别有用——比如一张表原本1GB,但WHERE过滤后只剩50MB,传统的Catalyst不知道过滤后多大,会选择Sort Merge Join。耎AQE在过滤完成后知道实际只有50MB,自动切换为Broadcast Join。

功能三:自动处理Skew Join(倾斜连接)

前面第3篇已经讲过。AQE会自动检测倾斜分区,把大分区拆成多个小任务并行处理。这个功能替代了以前手动加盐打散的90%场景。

-- AQE全套配置(生产环境推荐全开)
SET spark.sql.adaptive.enabled = true;
SET spark.sql.adaptive.coalescePartitions.enabled = true;
SET spark.sql.adaptive.skewJoin.enabled = true;
SET spark.sql.adaptive.localShuffleReader.enabled = true;
 
-- Databricks默认全部开启,不需要手动配置

实战效果

我在出海硬件公司迁移到Databricks后,全局开启AQE的效果:

• 整体ETL作业执行时间减少40%

• 倾斜相关的作业执行时间减少70%(之前手动加盐打散的代码全部可以删了)

• 小分区合并后,Task数量减少60%,调度开销大幅降低

AQE是我认为Spark 3.x最值得升级的功能,没有之一。

总结

AQE三大功能:合并小分区、动态切换Join、自动处理倾斜。核心优势是“运行时”动态调整,不依赖不准确的统计信息。生产环境强烈推荐全开。面试时能说清楚三个功能的原理和适用场景,再加一个实战效果数据,就很完整。

第6-10篇完结。下一辑继续聊Streaming容错、Structured Streaming vs Spark Streaming、Executor内存调优、小文件治理、Delta Lake/Iceberg配合等实战场景。

你们生产环境开启AQE后效果怎么样?评论区聊聊~

关注「Wood聊大数据」| 9年大数据老兵,聊技术、聊职场、聊成长

刷题进度保存在当前浏览器