如何只将一个集合发送到火花节点一次?

时间:2017-02-25 07:20:40

标签: scala apache-spark

考虑前一个问题的简单代码: Large task size for simplest program

import org.apache.spark.{SparkContext, SparkConf}

object LargeTaskTest {

  def main(args: Array[String]) {
    val conf = new SparkConf().setAppName("DataTest").setMaster("local[*]")
    val sc = new SparkContext(conf)
    val dat = (1 to 10000000).toArray
    val data = sc.parallelize(dat).cache()
    for(i <- 1 to 100){
      println(data.sum)
    }
  }   
}

我基本上有同样的问题:如何摆脱大尺寸警告&#34;的任务。在每次迭代?

接受的解决方案建议使用flatMap并行创建数据。虽然这对于整数范围来说是一个很好的解决方案,但如果我的数据实际上是一个对象集合(来自我的程序中的其他地方)我不能并行创建该怎么办?

我理解,对于第一个操作,需要将数据发送到所有节点,从而导致任务规模较大。 但是,对于后续操作,是否可以重复使用已复制的数据?

提前感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

一般解决方案:不要使用sc.parallelize。这没有特别有效地实现,因为它实际上用于教学/调试,以及一些实际用例,例如并行化文件名(小)和读取RDD映射闭包中的文件。

在这种情况下,您可以通过不将Range(O(1)内存占用空间)转换为Array(O(N)内存占用空间)来大幅减小任务的大小。只需删除toArray,就不应该再次收到这些警告。

答案 1 :(得分:0)

我接受了蒂姆的回答:不要使用sc.parallelize。为了支持他的主张,以下列方式创建RDD可以解决数据复制问题。

val pw = new java.io.PrintWriter("tmp")
(1 to 10000000).foreach(pw.println)
pw.close()
val data = sc.textFile("tmp").map(_.toDouble).persist()