我有一个看起来像这样的火花工作:
rdd.keyBy(lambda x: (x.id, x.location))
.aggregateByKey('my 3 aggregation parameters')
.map(expensiveMapFunction)
.collect()
映射步骤非常昂贵,我期望所有运行映射的任务并行执行,因为分区数足够大(等于键的数量)。但是,作业似乎有许多阶段(通常是2或3),只有少数任务在每个阶段进行实际计算,而其余任务没有任何事情可做。 如果所有任务一次运行,则作业将在一个阶段完成,但现在需要三倍的时间,因为任务似乎分3批运行。
什么可能导致这种行为?
答案 0 :(得分:2)
我认为你对舞台的意义有错误的印象。
与您显示的代码段相对应的作业至少需要两个阶段(如果您想计算结果阶段,则需要三个阶段)。 Spark中的每个阶段都是一组本地操作,它们为shuffle生成输出。
假设您用作输入的rdd
不需要改组,您需要:
rdd
计算mapSideCombine
和aggregateByKey
seqFunc
部分的一个阶段aggregateByKey
与combFunc
及后续map
与expensiveMapFunction
阶段数由相应的DAG完全定义,如果不改变血统就无法改变。
编辑(基于评论中的其他信息):
如果您实际关注aggregateByKey
之后的活动任务数,这通常是数据严重偏差的症状。如果频繁键的数量很少,则可以预期在随机播放期间大多数数据将仅分配给几个分区。
不幸的是,在这种情况下没有通用的解决方案。根据聚合逻辑和expensiveMapFunction
,您可以尝试使用一些salting来获得更好的数据分布。