如何在Spark中为任务分配执行者?

时间:2018-07-29 09:05:39

标签: scala apache-spark broadcast

我的文件如下:

(1,object1)
(2,object2)
(3,object3)
...

数字是对象的ID。我要从该文件计算两个对象之间的距离。这意味着我要得到如下结果:

(1,1,0.0)
(1,2,1.2)
(1,3,1.3)
...

对于每一行,第一个元素是一个对象的ID,第二个元素是另一个对象的ID,最后一个元素是距离。因此,如果原始文件中有3行,它将生成一个9行文件。 现在的问题是我的原始文件包含很多行,大小非常大,所以我转向使用集群的Spark进行计算。 因此,我使用以下代码:(假设原始文件为file1.txt)

val fileRdd = sc.textFile("hdfs://../file1.txt")
val fileRdd2 = sc.textFile("hdfs://../file1.txt")
val objects = fileRdd.collect()
val objectsArr = spark.sparkContext.broadcast(objects)
val distanceRes = fileRdd2.flatMap(x=>{
        distanceCal(x,objectsArr.value)
    }).saveAsTextFile(targetFile)

在此代码段中,distanceCal函数接收一个对象和一个对象数组,然后返回一个(objectID,objectID,distance)数组。我在这里要做的是首先将对象广播给每个执行器,然后在flatMap函数中执行双循环。 我使用yarn提交工作,其配置如下:

--master yarn --num-executors 6 --executor-memory 8G --executor-cores 8 --conf spark.default.parallelism=144

我使用6个执行器来执行此作业。我想该计算将在许多任务中完成,但是在saveAsTextFile阶段,该计算仅在两个执行程序上运行。在这种情况下,它仅在dn01和dn07上运行,而其他执行程序没有任务。 enter image description here

那么,出什么问题了?非常感谢!

更具体地说,我尝试使用以下代码来增加分区,以使其在最后阶段(saveAsTextFile)同时在不同的执行程序上运行。但是,它仍然仅使用两个执行程序,而另一个执行程序没有任务。那么如何更改我的代码来实现这一目标?也就是说,在最后阶段,在计算中将使用更多的执行程序,而在我的示例中不仅是其中两个。

fileRdd2.repartition(1000).flatMap(...)

0 个答案:

没有答案