首页 > 解决方案 > HDFS 和 Spark:编写文件并从另一个程序重用它的最佳方式

问题描述

我有一些 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() 对性能没有帮助。

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

标签: apache-sparkhadoophdfs

解决方案


您希望将所有文件合并为一个文件,以便您可以一次将所有文件加载到 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, 它的内容)


推荐阅读