如何将RDD数据保存到json文件中,而不是文件夹中

时间:2016-11-13 18:53:17

标签: scala apache-spark spark-streaming

我收到了我要在S3中保存的流数据myDStreamDStream[String])(基本上,对于这个问题,我想要保存输出的位置无关紧要,但我提到它是为了以防万一)。

以下代码效果很好,但它使用jsonFile-19-45-46.json等名称保存文件夹,然后在文件夹中保存文件_SUCCESSpart-00000

是否可以将每个RDD[String](这些是JSON字符串)数据保存到JSON 文件中,而不是文件夹中?我认为repartition(1)必须制作这个技巧,但事实并非如此。

    myDStream.foreachRDD { rdd => 
       // datetimeString = ....
       rdd.repartition(1).saveAsTextFile("s3n://mybucket/keys/jsonFile-"+datetimeString+".json")
    }

3 个答案:

答案 0 :(得分:1)

AFAIK没有将其保存为文件的选项。因为它是一个分布式处理框架,并且在单个文件上写入并不是一个好的做法,而不是每个分区在指定的路径中写入自己的文件。

  

我们只能传递我们想要保存数据的输出目录。 OutputWriter将使用part-文件名前缀在指定路径内创建文件(取决于分区)。

答案 1 :(得分:1)

作为rdd.collect.mkString("\n")的替代方法,您可以使用hadoop文件系统库通过将part-00000文件移动到其位置来清理输出。下面的代码完全适用于本地文件系统和HDFS,但我无法用S3测试它:

val outputPath = "path/to/some/file.json"
rdd.saveAsTextFile(outputPath + "-tmp")

import org.apache.hadoop.fs.Path
val fs = org.apache.hadoop.fs.FileSystem.get(spark.sparkContext.hadoopConfiguration)
fs.rename(new Path(outputPath + "-tmp/part-00000"), new Path(outputPath))
fs.delete(new Path(outputPath  + "-tmp"), true)

答案 2 :(得分:0)

对于JAVA,我实现了这一点。希望对您有所帮助:

    val fs = FileSystem.get(spark.sparkContext().hadoopConfiguration());
    File dir = new File(System.getProperty("user.dir") + "/my.csv/");
    File[] files = dir.listFiles((d, name) -> name.endsWith(".csv"));
    fs.rename(new Path(files[0].toURI()), new Path(System.getProperty("user.dir") + "/csvDirectory/newData.csv"));
    fs.delete(new Path(System.getProperty("user.dir") + "/my.csv/"), true);