1

我有一些 Spark 应用程序的结果保存在 HDFS 中,作为名为 part-r-0000X(X=0、1 等)的文件。而且,因为我想将整个内容加入文件中,所以我使用以下命令:

hdfs dfs -getmerge srcDir destLocalFile

前面的命令在 bash 脚本中使用,它使输出目录(part-r-...保存文件的位置)为空,并在循环内执行上述getmerge命令。

问题是我需要在另一个 Spark 程序中使用生成的文件,该程序需要该合并文件作为 HDFS 中的输入。因此,我将其保存为本地,然后将其上传到 HDFS。

我想到了另一种选择,即以这种方式从 Spark 程序中写入文件:

outputData.coalesce(1, false).saveAsTextFile(outPathHDFS)

但我读过 coalesce() 对性能没有帮助。

还有其他想法吗?建议?谢谢!

4

3 回答 3

2

您希望将所有文件合并为一个文件,以便您可以一次将所有文件加载到 Spark rdd 中,这是我的猜测。

让文件位于 HDFS 的 Parts(0,1,....) 中。

为什么不使用wholetextFiles 加载它,它实际上可以满足您的需要。

wholeTextFiles(path, minPartitions=None, use_unicode=True)[source]

从 HDFS、本地文件系统(在所有节点上可用)或任何 Hadoop 支持的文件系统 URI 读取文本文件目录。每个文件被读取为单个记录并以键值对的形式返回,其中键是每个文件的路径,值是每个文件的内容。

如果 use_unicode 为 False,字符串将保存为 str(编码为 utf-8),比 unicode 更快更小。(在 Spark 1.2 中添加)

例如,如果您有以下文件:

hdfs://a-hdfs-path/part-00000 hdfs://a-hdfs-path/part-00001 ... hdfs://a-hdfs-path/part-nnnnn

做 rdd = sparkContext.wholeTextFiles(“hdfs://a-hdfs-path”),然后 rdd 包含:

(a-hdfs-path/part-00000, 它的内容) (a-hdfs-path/part-00001, 它的内容) ... (a-hdfs-path/part-nnnnn, 它的内容)

于 2018-07-20T22:40:20.077 回答
1

试试 SPARK BucketBy。

这是通过 df.write.saveAsTable() 实现的一个不错的功能,但这种格式只能由 SPARK 读取。数据显示在 Hive 元存储中,但无法被 Hive、IMPALA 读取。

于 2018-08-14T22:25:02.170 回答
0

到目前为止,我发现的最佳解决方案是:

outputData.saveAsTextFile(outPath, classOf[org.apache.hadoop.io.compress.GzipCodec])

outputData它将压缩part-0000X.gz文件保存在outPath目录下。

而且,从另一个 Spark 应用程序中,它使用以下命令读取这些文件:

val inputData = sc.textFile(inDir + "part-00*", numPartition)

inDir对应于哪里outPath

于 2018-08-14T15:29:07.970 回答