将大文本文件导入Spark

时间:2017-10-24 17:57:34

标签: apache-spark pyspark bigdata

我有一个管道分隔的文本文件,360GB,压缩(gzip)。该文件位于S3存储桶中。 这是我第一次使用Spark。我知道您可以对文件进行分区,以便允许多个工作节点对数据进行操作,从而获得巨大的性能提升。但是,我正在尝试找到一种将我的360GB文件转换为分区文件的有效方法。有没有办法使用多个spark worker节点来处理我的压缩文件,以便对其进行分区?不幸的是,我无法控制我只是得到一个巨大的文件。我可以自己解压缩文件并将其分解为许多文件(例如360个1GB文件),但我只是使用一台机器来完成它并且它会很慢。我需要使用Spark对数据进行一些昂贵的转换,所以我认为分区文件是必要的。我在亚马逊胶水中使用Spark,所以我知道它可以扩展到大量的机器。另外,我正在使用python(pyspark)。

感谢。

3 个答案:

答案 0 :(得分:2)

如果我没有弄错的话,如果您使用TextInputFormat阅读文件,Spark会使用Hadoop SparkContext.textFile。如果设置了压缩编解码器,则TextInputFormat通过检查代码是否为SplittableCompressionCodec的实例来确定文件是否可拆分。

我认为GZIP不可分割,Spark只能生成一个分区来读取整个文件。

你能做的是:
1.在SparkContext.textFile之后添加重新分区,这样您至少可以处理多个转换过程中的部分数据。
2.要求多个文件而不是单个GZIP文件
3.编写一个应用程序,在将文件运行到其上之前,将文件解压缩并拆分为多个输出文件。
4.为GZIP编写自己的压缩编解码器(这有点复杂)。

看看这些链接:

TextInputFormat source code for TextInputFormat
GzipCodec source code for GZIPCodec

这些是在java中,但我确定它们有相同的Python / Scala版本。

答案 1 :(得分:1)

首先我建议您必须使用ORC格式和zlib压缩,因此您可以获得近70%的压缩率,根据我的研究,ORC是最适合最快数据处理的文件格式。因此,您必须加载文件,然后使用重新分区将其写入orc格式。

df.repartition(500).write.option("compression","zlib").mode("overwrite").save("testoutput.parquet")

答案 2 :(得分:1)

一个可能的解决方案是使用Amazon's S3DistCp作为EMR集群的一个步骤,将360GB文件复制到集群上可用的HDFS文件系统中(这需要在EMR上部署Hadoop)。

关于S3DistCp的一个好处是你可以改变输出文件的编解码器,并将原始的gzip文件转换成一种格式,允许Spark为其RDD生成多个分区。

但是我不确定S3DistCp执行操作需要多长时间(这是一个Hadoop Map / Reduce over S3。从EMR运行时它受益于优化的S3库,但我担心Hadoop会在生成Map任务时面临与Spark相同的限制。)