阿里云RemoteShuffleService 新功能:AQE 和流控
阿里云EMR 自2020年推出 Remote Shuffle Service(RSS) 以来,帮助了诸多客户解决 Spark 作业的性能、稳定性问题,并使得存算分离架构得以实施。为了更方便大家使用和扩展,RSS 在2022年初开源(https://github.com/alibaba/RemoteShuffleService),欢迎各路开发者共建: ) RSS的整体架构请参考[1],本文将介绍 RSS 最新的两个重要功能:支持 Adaptive Query Execution(AQE),以及流控。
RSS 支持 AQE
AQE 简介
自适应执行(Adaptive Query Execution, AQE)是 Spark3 的重要功能[2],通过收集运行时 Stats,来动态调整后续的执行计划,从而解决由于 Optimizer 无法准确预估 Stats导致生成的执行计划不够好的问题。AQE 主要有三个优化场景: Partition 合并(Partition Coalescing), Join 策略切换(Switch Join Strategy),以及倾斜 Join 优化(Optimize Skew Join)。这三个场景都对 Shuffle 框架的能力提出了新的需求。
Partition 合并
Partition 合并的目的是尽量让 reducer 处理的数据量适中且均匀,做法是首先 Mapper按较多的 Partition 数目进行 Shuffle Write,AQE 框架统计每个 Partition 的 Size,若连续多个 Partition 的数据量都比较小,则将这些 Partition 合并成一个,交由一个 Reducer 去处理。过程如下所示。
由上图可知,优化后的 Reducer2 需读取原属于 Reducer2-4 的数据,对 Shuffle 框架的需求是 ShuffleReader 需要支持范围 Partition:
def getReader[K, C](
handle: ShuffleHandle,
startPartition: Int,
endPartition: Int,
context: TaskContext): ShuffleReader[K, C]
Join 策略切换
Join 策略切换的目的是修正由于 Stats 预估不准导致 Optimizer 把本应做的 Broadcast Join 错误的选择了 SortMerge Join 或 ShuffleHash Join。具体而言,在 Join 的两张表做完 Shuffle Write 之后,AQE 框架统计了实际大小,若发现小表符合 Broadcast Join 的条件,则将小表 Broadcast 出去,跟大表的本地 Shuffle 数据做 Join。流程如下:
Join 策略切换有两个优化:1. 改写成 Broadcast Join; 2. 大表的数据通过LocalShuffleReader 直读本地。其中第2点对 Shuffle 框架提的新需求是支持 Local Read。
倾斜Join优化
倾斜Join优化的目的是让