在火花流式上下文中将RDD写入HDFS

时间:2015-07-02 11:23:02

标签: scala hadoop apache-spark hdfs spark-streaming

我有一个带有spark 1.2.0的火花流式传输环境,我从本地文件夹中检索数据,每当我发现一个新文件添加到文件夹时,我就会进行一些转换。

val ssc = new StreamingContext(sc, Seconds(10))
val data = ssc.textFileStream(directory)

为了对DStream数据执行分析,我必须将其转换为数组

var arr = new ArrayBuffer[String]();
   data.foreachRDD {
   arr ++= _.collect()
}

然后我使用获取的数据来提取我想要的信息并将它们保存在HDFS上。

val myRDD  = sc.parallelize(arr)
myRDD.saveAsTextFile("hdfs directory....")

由于我真的需要使用数组操作数据,因此无法使用DStream.saveAsTextFiles("...")将数据保存在HDFS上(这样可以正常工作)并且我必须保存RDD但是通过这种预处理我终于有了空的输出​​文件命名part-00000等...

使用arr.foreach(println)我能够看到转换的正确结果。

我怀疑是spark会在每个批处理中尝试在同一个文件中写入数据,删除之前写的内容。我试图保存在动态命名文件夹中,如myRDD.saveAsTextFile("folder" + System.currentTimeMillis().toString()),但始终只创建一个folds,输出文件仍为空。

如何在Spark-streaming上下文中将RDD写入HDFS?

2 个答案:

答案 0 :(得分:6)

您正在以未设计的方式使用Spark Streaming。我建议您使用Spark代替您的用例,或者调整您的代码,使其以Spark方式工作。将阵列收集到驱动程序会破坏使用分布式引擎的目的,并使您的应用程序有效地实现单机(两台机器也会比仅在一台机器上处理数据产生更多的开销)。

你可以用数组做的一切,你可以用Spark做。因此,只需在流中运行计算,在工作程序上分发,然后使用DStream.saveAsTextFiles()编写输出。您可以使用foreachRDD + saveAsParquet(path, overwrite = true)写入单个文件。

答案 1 :(得分:2)

@vzamboni:Spark 1.5+数据帧api具有此功能:

dataframe.write().mode(SaveMode.Append).format(FILE_FORMAT).partitionBy("parameter1", "parameter2").save(path);