如何在RDD中存储单个值或者您是否绝对需要将其转换为数组?

时间:2015-08-19 20:06:17

标签: apache-spark

我有一个正在运行的程序,它在包含整数数组的输入RDD上进行一系列转换。但是在完成所有转换后,我想找到所有这些数字的总和,只得到1个整数并将该值存储在输出文件中。

我可以通过对RDD执行reduce操作来获取最终的整数值。但是,在执行此ACTION后,我得到一个返回给我的整数(而不是RDD),因此我无法使用RDD.saveAsTextFile("/output_location")方法。

此外,当我尝试为该整数创建RDD时,它给出了一个错误:

// finalvalue is my variable that contains the output value to be stored.
val out = sc.parallelize(finalvalue);

错误:Type Mismatch, expected Seq[NotInferedT], actual: Int

有人可以向我解释为什么我不能将一个单独的值存储到RDD中,还是必须将其转换为数组?

2 个答案:

答案 0 :(得分:3)

基本上情况是您有一个Int,并且您想将其写入文件。您首先想到的是在一组计算机上创建一个分布式集合,该集合只包含此Int,并允许这些计算机以分布式方式将Int写入一组文件。

我认为这不是正确的做法。不要使用Spark将Int保存到文件中。相反,您可以使用PrintWriter

val out = new java.io.PrintWriter("filename.txt")
out.println(finalvalue)
out.close()

这仅适用于写入本地文件。如果您要写入HDFS it gets more complicated

答案 1 :(得分:2)

所以,让我们考虑一下这个场景,一次理解一个步骤:

// Creating the RDD named x which stores 3 integers
scala> val x = sc.parallelize(Array(1,2,3))
x: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[2] at parallelize at <console>:12

// Now calculating the sum converting it into an Integer and storing in mysum variable
scala> val mysum = x.sum().toInt
[Stage 1:>                                                                                                                       (0 + 0) / 2]mysum: Int = 6

到目前为止一切顺利。现在,当您尝试使用mysum上的sc.parallelize()创建RDD时,会发生以下情况:

scala> val sumRDD = sc.parallelize(mysum)
<console>:16: error: type mismatch;
 found   : Int
 required: Seq[?]
Error occurred in an application involving default arguments.
       val sumRDD = sc.parallelize(mysum)
                                   ^

如错误所示,您只能将Sequence作为参数提供给parallelize方法。所以解决这个问题你需要将一个数组(或Seq等)或一个字符串传递给parallelize:

// So either do this
scala> val sumRDD = sc.parallelize(mysum.toString)
sumRDD: org.apache.spark.rdd.RDD[Char] = ParallelCollectionRDD[4] at parallelize at <console>:16

// or do this
scala> val sumRDD = sc.parallelize(Array(mysum))
sumRDD: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[6] at parallelize at <console>:16

下一步是将其存储到特定路径。 &#39;文件&#39;是将它存储在本地机器和&#39; hdfs&#39;分别存储在HDFS上

scala> sumRDD.saveAsTextFile("file:///home/hdfs/a12")
15/08/19 16:14:57 WARN DomainSocketFactory: The short-circuit local reads feature cannot be used because libhadoop cannot be loaded.
  • 当我尝试在磁盘上存储字符串时,不确定为什么警告出现在最后一步。

在上述路径中创建一个目录,其中包含部分文件。