我从保存在HDFS中的Spark应用程序得到了一些结果,文件名为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()对性能没有帮助。
还有其他想法吗?建议?谢谢!
答案 0 :(得分: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,其内容)>
答案 1 :(得分:1)
尝试使用SPARK Bucket。
这是通过df.write.saveAsTable()提供的一项很好的功能,但是此格式只能由SPARK读取。数据显示在Hive Metastore中,但Hive IMPALA无法读取。
答案 2 :(得分: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
的地方。