2015-06-27 27 views
0

我正在Spark群集上分发一些下载任务。输入来自一个源,它不能总是与Spark的常规方法并行,如parallelizetextFile等等。相反,我有一个服务为我提供了一堆使用parallelize分发的下载任务(URL +封装的逻辑来读取和解密它)。控制Spark中任务的分配

当有几千个任务时,Spark将任务平均分配给所有从服务器,从而实现最高水平的并行性。但是,当有几百个任务时,Spark认为数据集很小,可以在几个从站上计算,以减少通信时间并增加数据局部性。但是在我的情况中,这是错误的,每个任务都可以生成数千个JSON记录,并且我希望下载能够通过与群集中一样多的机器来执行。

我的那一刻两个想法:

  • 使用repartition到分区的数量设置为使用repartition设置分区的号码下载任务数的核心
  • 数量

我不喜欢第一个,因为我必须传递一段代码中的核心数量,这些代码当前并不需要知道它有多少资源。我一次只运行一个Spark作业,但将来可能会有更多这样的作业,所以实际上我必须将核心数量除以要在群集上运行的并行作业数量。我不喜欢第二个,因为当我只有40个节点时,划分成数千个分区似乎很尴尬。

有没有办法告诉Spark尽可能分配RDD的元素?如果不是,两种选择中的哪一种更可取?

+0

你说你不能使用'parallelize'并且你也使用'parallelize'。我理解正确吗? :) –

+0

啊,我想我明白了!你的意思是你没有预先提供的数据,只有网址。所以你不能通过'parallelize'分发数据,而是使用'parallelize'来分发这些URL。不介意我... –

+0

@DanielDarabos你说得对了 – Dici

回答

1

如果每次下载都能产生大量记录,而且下载量也不会很多(只有几千个),我建议在每次下载时创建一个分区

调度几千个任务的总开销只有几秒钟。我们通常在生产中拥有数万个分区。

如果您在一个分区中有多次下载,最终可能会出现非常大的分区。如果你有一个分区无法整合两次可用内存,那么你将会遇到一些操作问题。例如,一个joindistinct构建整个分区的散列表。


您不应该使用repartitionparallelize需要第二个参数,即需要的分区数量。尽管URL列表并不是大量数据,但如果您只是使用适当数量的分区创建RDD,而不是在创建之后对其进行重新组合,那将会更好。

+0

嗨,你的回答很有道理,因此我赞成它。我现在不接受,因为我想在星期一之前测试它。我还有一个问题:当你的群集中有更多的分区而不是节点(和核心)时,几个分区是由相同的节点计算出来的吗?那么,如何将节点分成尽可能多的节点,又有哪些不同? – Dici

+0

每个分区都成为一个计算单位(Spark _任务_)。无论您有多少个小型工作单元,或者更少的大型单元,无论内核的数量如何,都会有所不同。调度任务有一些开销。如果您有N个分区,洗牌会创建N^2个块。分区有时必须适合内存。等等无论如何,最好是在你决定之前测试两个选项,如果你能做一个有代表性的测试! –

+0

好的,谢谢你的回答,我会在星期一尝试,让你知道! – Dici