使用(spark,python,pyspark,jupyter)将多个项目保存到HDFS

时间:2017-05-11 13:01:10

标签: python apache-spark hdfs pyspark-sql

我习惯用Python编程。我公司现在安装了Jupyter的Hadoop集群。到现在为止,我从未使用过Spark / Pyspark。

我可以像以前一样轻松地从HDFS加载文件:

text_file = sc.textFile("/user/myname/student_grades.txt")

我能写出这样的输出:

text_file.saveAsTextFile("/user/myname/student_grades2.txt")

我想要实现的是使用简单的“for循环”逐个读取文本文件并将其内容写入一个HDFS文件。所以我尝试了这个:

list = ['text1.txt', 'text2.txt', 'text3.txt', 'text4.txt']

for i in list:
    text_file = sc.textFile("/user/myname/" + i)
    text_file.saveAsTextFile("/user/myname/all.txt")

所以这适用于列表的第一个元素,但后来给了我这个错误信息:

Py4JJavaError: An error occurred while calling o714.saveAsTextFile.
: org.apache.hadoop.mapred.FileAlreadyExistsException: Output directory 
XXXXXXXX/user/myname/all.txt already exists

为了避免混淆我用XXXXXXXX“模糊”了IP地址。


这样做的正确方法是什么? 我将拥有大量的数据集(如'text1','text2'...),并希望在将它们保存到HDFS之前对每个数据集执行python函数。但我希望将结果全部放在“一个”输出文件中。

非常感谢!
MG

编辑: 似乎我的最终目标并不是很清楚。我需要单独为每个文本文件应用一个函数,然后我想将输出附加到现有的输出目录。像这样:

for i in list:
    text_file = sc.textFile("/user/myname/" + i)
    text_file = really_cool_python_function(text_file)
    text_file.saveAsTextFile("/user/myname/all.txt")

3 个答案:

答案 0 :(得分:1)

我想将此作为评论发布,但由于我没有足够的声誉,因此无法发表评论。

您必须将RDD转换为数据帧,然后以追加模式写入。要将RDD转换为数据帧,请查看以下答案:
https://stackoverflow.com/a/39705464/3287419
或者此链接http://spark.apache.org/docs/latest/sql-programming-guide.html
要在下面的附加模式中保存数据框,链接可能很有用:
http://spark.apache.org/docs/latest/sql-programming-guide.html#save-modes

这里几乎同样的问题Spark: Saving RDD in an already existing path in HDFS。但提供的答案是scala。我希望在python中也可以做类似的事情。

还有另一种(但很难看)的做法。将您的RDD转换为字符串。让结果字符串为resultString。使用子进程将该字符串附加到目标文件,即

subprocess.call("echo "+resultString+" | hdfs dfs -appendToFile - <destination>", shell=True)

答案 1 :(得分:0)

如果文本文件都具有相同的模式,则可以使用Hive将整个文件夹作为单个表读取,并直接写入该输出。

答案 2 :(得分:0)

我会试试这个,应该没问题:

   list = ['text1.txt', 'text2.txt', 'text3.txt', 'text4.txt']
    
    for i in list:
        text_file = sc.textFile("/user/myname/" + i)
    text_file.saveAsTextFile(f"/user/myname/{i}")