spark,count和saveAsObjectFile,无需计算两次

时间:2016-11-08 09:44:58

标签: apache-spark

使用Spark,我可以过滤和转换集合。然后我想计算结果集合的大小并将结果集合保存到文件中。因此,如果结果集合不适合内存,这是否意味着输出将被计算两次?有没有办法同时计算和saveAsObjectFile,所以它不会被计算两次?

val input: RDD[Page] = ...
val output: RDD[Result] = input.filter(...).map(...)  // expensive computation
output.cache()
val count = output.count
output.saveAsObjectFile("file.out")

1 个答案:

答案 0 :(得分:2)

使用缓存到内存和磁盘的解决方案#1

您可以将缓存用于内存和磁盘 - 您将避免计算两次,但您必须从磁盘(而不是RAM)读取数据

使用带有MEMORY_AND_DISK的persist()作为参数。 这会将计算数据保存到内存或磁盘

http://spark.apache.org/docs/latest/programming-guide.html#which-storage-level-to-choose

MEMORY_AND_DISK将RDD存储为JVM中的反序列化Java对象。如果RDD不适合内存,请存储不适合磁盘的分区,并在需要时从那里读取它们。

解决方案#2使用累加器执行计数

类似的问题在这里被问到/回答: http://thread.gmane.org/gmane.comp.lang.scala.spark.user/7920

建议使用累加器,在应用saveAsObjectFile()

之前将应用累加器
val counts_accum = sc.longAccumulator("count Accumulator")
output.map{x =>
  counts_accum.add(1)
  x
}.saveAsObjectFile("file.out")

在完成saveAsObjectFile之后,累加器值将保持总计数,并且您将能够打印它(您必须使用" .value&#34 ;为了获得累加器值

println(counts_accum.value)

如果使用名称创建累加器,它们将显示在Spark的UI中。这对于了解运行阶段的进度非常有用

更多信息可以在这里找到: http://spark.apache.org/docs/latest/programming-guide.html#accumulators