我试图了解Spark为简单的first()vs collect()操作创建的作业。
鉴于代码:
myRDD = spark.sparkContext.parallelize(['A', 'B', 'C'])
def func(d):
return d + '-foo'
myRDD = myRDD.map(func)
我的RDD分为16个分区:
print(myRDD.toDebugString())
(16) PythonRDD[24] at RDD at PythonRDD.scala:48 []
| ParallelCollectionRDD[23] at parallelize at PythonRDD.scala:475 []
如果我打电话:
myRDD.collect()
创建了16个任务,我得到了1份工作。我假设这是每个分区的一个任务。
但是,如果我打电话:
myRDD.first()
我得到3个工作,创建了1个,4个和11个任务。为什么要创建3个职位?
我使用由Mesos提供的单个16核执行程序运行spark-2.0.1。
答案 0 :(得分:1)
这实际上是非常聪明的Spark行为。您的map()
是转换(它是懒惰评估的),first()
和collect()
都是操作(终端操作)。所有转换都会在您调用操作时及时应用于数据。
当你致电first()
时,spark尝试尽可能少地执行操作(转换)。首先,它尝试一个随机分区。如果没有结果,则需要4次分区并计算。同样,如果没有结果,spark需要4次分区(5 * 4)并再次尝试获得任何结果。
在第三次尝试的情况下,您只有11个未触及的分区(16 - 1 - 4)。如果您在RDD中有更多数据或更少数量的分区,那么spark可能会更快找到first()
结果。