在PySpark中从S3 Bucket读取阅读数百万个小JSON文件非常慢

ha5z0ras  于 5个月前  发布在  Spark
关注(0)|答案(2)|浏览(53)

我在s3中有一个文件夹(path = mnt/data/*.json),里面有数百万个json文件(每个文件不到10 KB)。我运行以下代码:

df = (spark.read
           .option("multiline", True)
           .option("inferSchema", False)
           .json(path))
display(df)

字符串
问题是它非常慢。Spark用一个任务创建了一个作业。这个任务似乎没有更多的执行者运行它,这通常意味着一个作业的完成(对吗?),但由于某种原因,DataBricks中的命令单元仍然在运行。它已经像这样卡住了10分钟。我觉得像这样简单的事情应该不超过5分钟。
x1c 0d1x的数据

注意事项:

  • 由于有数百万个json文件,我不能很有信心地说它们会有相同的结构(可能会有一些差异)
  • json文件是从同一REST API中通过Web抓取的
  • 我在某个地方读到过inferSchema = False可以帮助减少运行时间,这就是我使用它的原因
  • AWS s3存储桶已经安装,因此完全没有必要使用boto 3
wsxa1bj1

wsxa1bj11#

Apache Spark非常擅长处理大文件,但是当你有成千上万个小文件(在你的情况下是数百万个),在一个目录中/分布在几个目录中时,这将对处理时间产生严重影响(可能是几十分钟到几小时),因为它必须读取这些小文件中的每一个。
一个理想的文件大小应该在128 MB到1GB之间,任何小于128 MB(due spark.sql.files. maxPartitions.exe)的文件都会出现这种小文件问题,并将成为瓶颈。
您可以在中间位置以parquet格式将数据重写为 * 一个大文件 *(使用 coalesce)或 * 多个大小相等的文件 *(使用 repartition
您可以从这个中间位置读取数据以进行进一步处理&这应该可以防止任何与TinyFiles问题有关的瓶颈。

5t7ly7z5

5t7ly7z52#

感谢Anand指出的“小文件问题”,我的方法非常简单。因此,我的问题是,我无法提取大约200万个大小为10 KB的JSON文件。因此,我无法读取并将其存储为parquet格式作为中间步骤。我得到了一个s3桶,其中包含从Web上抓取的原始JSON文件。
无论如何,使用python的zipfile模块是可以的。它被用来附加多个json文件,每个文件至少128 MB,最多1GB。工作得很好!
还有另一种方法可以使用AWS Glue来完成此操作,但当然这需要IAM角色授权并且可能很昂贵,但其优点是您可以直接将这些文件转换为parquet。
zip文件解决方案:https://docs.python.org/3/library/zipfile.html
AWS Glue解决方案:https://medium.com/searce/convert-csv-json-files-to-apache-parquet-using-aws-glue-a760d177b45f
很好的博客文章解释了小文件的问题:
https://mungingdata.com/apache-spark/compacting-files/
https://garrens.com/blog/2017/11/04/big-data-spark-and-its-small-files-problem/?unapproved=252&moderation-hash=5a657350c6169448d65209caa52d5d2c#comment-252

相关问题