Apache spark 完成所有任务需要多个阶段

Apache spark 完成所有任务需要多个阶段,apache-spark,pyspark,Apache Spark,Pyspark,我有一份充满活力的工作,看起来像这样: rdd.keyBy(lambda x: (x.id, x.location)) .aggregateByKey('my 3 aggregation parameters') .map(expensiveMapFunction) .collect() 映射步骤非常昂贵,我希望运行映射的所有任务都能并行执行,因为分区的数量足够大(等于键的数量)。但是,该作业似乎有许多阶段(通常为2或3个阶段),只有少数任务在每个阶段进行实际计算,而其余任务

我有一份充满活力的工作,看起来像这样:

rdd.keyBy(lambda x: (x.id, x.location))
   .aggregateByKey('my 3 aggregation parameters')
   .map(expensiveMapFunction)
   .collect()
映射步骤非常昂贵,我希望运行映射的所有任务都能并行执行,因为分区的数量足够大(等于键的数量)。但是,该作业似乎有许多阶段(通常为2或3个阶段),只有少数任务在每个阶段进行实际计算,而其余任务则没有任何事情要做。 如果所有任务同时运行,作业将在一个阶段内完成,但现在需要三倍的时间,因为任务似乎分三批运行


什么会导致这种行为?

我认为你们对舞台的意义有错误的印象

与所显示的代码段相对应的作业至少需要两个阶段(如果要计算结果阶段,则需要三个阶段)。Spark中的每个阶段都是一组本地操作,这些操作生成洗牌的输出

假设您用作输入的
rdd
不需要您需要的洗牌:

  • 计算
    rdd
    mapSideCombine
    部分
    aggregateByKey
    seqFunc
  • 使用
    combFunc
    计算
    aggregateByKey
    合并部分的一个阶段,以及随后使用
    expensiveMapFunction
    计算
    map
    合并部分的一个阶段
阶段的数量完全由相应的DAG定义,并且在不更改沿袭的情况下无法更改

编辑(基于评论中的其他信息):

如果您真正关心的是
aggregateByKey
之后活动任务的数量,那么这通常是数据严重倾斜的症状。如果频繁键的数量较低,则可以预期在洗牌过程中,大多数数据将仅分配给几个分区


不幸的是,在这种情况下没有通用的解决方案。根据聚合逻辑和
expensiveMapFunction
的不同,您可以尝试使用一些salt来获得更好的数据分布

谢谢你的回答!我指的是你提到的第二个阶段,具有ExpensiveMap功能的阶段。我原以为它包含的所有任务都会并行运行,但该阶段会运行多次,有20个任务,其中只有2个或3个做实际工作。如果您看到只有一小部分执行者在工作,这通常是数据倾斜的结果。但这与阶段数无关:)