如何在地图中填充变量 - Scala Spark

时间:2016-10-06 14:50:45

标签: scala apache-spark

我必须读取一个文本文件并将其读取以将其值保存在变量类型

Map[Int, collection.mutable.Map[Int, Double]]

我用foreach和一个广播变量完成了它,它在我的本地机器上正常工作,但它不在一个纱线集群中。 Foreach任务花费太多时间执行与本地计算机仅需1分钟的相同任务。

val data = sc.textFile(fileOriginal)

val dataRDD = parsedData.map(s => s.split(';').map(_.toDouble)).cache()

val datos = collection.mutable.Map[Int, collection.mutable.Map[Int, Double]]()
val bcDatos = sc.broadcast(datos)


dataRDD.foreach { case x =>

  if (bcDatos.value.contains(x.apply(0).toInt)) {
    bcDatos.value(x.apply(0).toInt).put(x.apply(1).toInt, x.apply(2) / x.apply(3) * 100)

  } else {
    bcDatos.value.put(x.apply(0).toInt, collection.mutable.Map((x.apply(1).toInt, x.apply(2) / x.apply(3) * 100)))
  }
}

我的问题是:我怎么能这样做,但是使用地图?我可以填写"地图内部具有该结构的变量?

谢谢

1 个答案:

答案 0 :(得分:2)

使用Spark时 - 你应该从不尝试以分布式方式使用可变结构 - 这根本就不受支持。如果你改变在驱动程序代码中创建的变量(无论是否使用广播),该变量的副本将分别在每个执行程序上进行变异,并且你永远不会能够&#34 ;合并"这些突变的部分结果并将它们发送回驱动程序。

相反 - 您应该将您的RDD转换为具有所需数据的新(不可变!)RDD。

如果我设法正确地遵循您的逻辑 - 这将为您提供所需的地图:

// assuming dataRDD has type RDD[Array[Double]] and each Array has at least 4 items:
val result: Map[Int, Map[Int, Double]] = dataRDD
  .keyBy(_(0).toInt)
  .mapValues(arr => Map(arr(1).toInt -> arr(2) / arr(3) * 100))
  .reduceByKey((a, b) => a) // you probably want to "merge" maps "a" and "b" here, but your code doesn't seem to do that now either
  .collectAsMap()