我收到了我要在S3中保存的流数据myDStream
(DStream[String]
)(基本上,对于这个问题,我想要保存输出的位置无关紧要,但我提到它是为了以防万一)。
以下代码效果很好,但它使用jsonFile-19-45-46.json
等名称保存文件夹,然后在文件夹中保存文件_SUCCESS
和part-00000
。
是否可以将每个RDD[String]
(这些是JSON字符串)数据保存到JSON 文件中,而不是文件夹中?我认为repartition(1)
必须制作这个技巧,但事实并非如此。
myDStream.foreachRDD { rdd =>
// datetimeString = ....
rdd.repartition(1).saveAsTextFile("s3n://mybucket/keys/jsonFile-"+datetimeString+".json")
}
答案 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);