Spark - 加载许多小 csv 需要很长时间

Posted

技术标签:

【中文标题】Spark - 加载许多小 csv 需要很长时间【英文标题】:Spark - loading many small csv takes very long 【发布时间】:2019-08-15 10:26:45 【问题描述】:

说明 在我的工作场所,我们有大量需要处理的数据。它涉及数量快速增长的实例(目前约为 3000 个),这些实例都在 S3 上的 gzip csv 文件中存储了数兆字节的数据。

我已经设置了一个 spark 集群并编写了一个 spark 脚本来执行以下操作。

    对于每个实例:

    加载数据框 运行计算 但尚未保存数据帧(因此未触发任何操作,我在 spark 作业 UI 中确认了这一点)

    之后,我将所有数据帧组合成一个数据帧并保存结果(因此触发一个动作)

问题 当我使用少量实例时,上述工作非常好。但是我发现了以下问题: - 当实例文件加载到数据帧中时,需要 4-6 秒而不触发任何操作。 - 数据帧的加载发生在驱动程序上 - 由于上述两个原因,加载数据帧需要将近 2 个小时(通过使用 python“线程”对此进行了一些优化

谁能解释一下导致加载缓慢的原因并建议我如何处理这个问题?

也许相关信息是我正在使用 aws s3a hadoop 文件系统。此外,我计算的第一部分是每个实例完全独立的,这就是为什么我有点犹豫将所有输入数据合并到一个 gzip 压缩的 csv 文件中以及其他原因。

任何帮助都将不胜感激,我是在深夜对这个问题深思熟虑后写下这篇文章,直到深夜 5 点。

如果我应该提供更多详细信息,请告诉我。

编辑

感谢 cmets,我在 kubernetes 上运行 spark,因此无法使用 hadoop 命令合并文件。但是我正在追求合并实例文件的想法。

编辑 2 原来我以完全错误的方式使用火花,我认为我可以通过保持数据分开来使火花更容易,但这适得其反。最好的解决方案似乎是将您的输入文件聚合成更大的文件。并调整您的脚本以将它们分开。

【问题讨论】:

我建议您将数据复制到您的 hadoop 集群 (EMR) 上,然后合并这些文件 ***.com/questions/39103872/… 或 ***.com/questions/3548259/… 【参考方案1】:

Spark 并未真正针对处理大量小文件进行优化。我不知道这是否有可能,但您可以尝试将小文件聚合成更大的文件,这可能会奏效。

【讨论】:

您可以将文件与hadoop fs -getmerge合并【参考方案2】:

我会尝试以下方法:

    如果每个实例在创建后保持不变,只有实例的数量随着天数增加,我会:

    (1) 加载所有实例并将它们组合成一个大DataFrame,并额外增加一列来表示实例ID。

    (2) 保存大DataFrame

    (3) 展望未来,也许每天的任务只是加载大 DataFrame 和新实例,组合它们,进行计算,保存输出。 由于每个实例数据都有自己的实例 ID,因此您仍然可以在它们上运行并行计算。

    (4) 另外,当你加载 csv 时,如果所有实例都有相同的 header,加载时尝试指定 schema。这可能会为您节省一些时间。

    这个我自己从来没有试过,也不确定它是否有效,只是想在这里集思广益:)

(1) 可以创建一个DataFrame,一列是实例ID,另一列是对应实例的地址或文件名。

(2) 然后您在实例 ID 上groupby,并在您的udf 中加载csv 文件。因此 csv 加载将分布在工作人员之间,而不是全部在驱动程序上运行。

(3) groupby 应该自动返回一个组合的DataFrame。然后你从它开始。

希望对您有所帮助。 请让我们知道您如何解决问题。

【讨论】:

感谢您的建议。每个实例的数据都在增长,但是在某些时候,旧记录的数据不会再改变。我意识到我在滥用 spark 并改写脚本以大批量加载数据。我确实安排了一个额外的列,指示实例 ID。此外,我确实已经提供了一个仪表模式。

以上是关于Spark - 加载许多小 csv 需要很长时间的主要内容,如果未能解决你的问题,请参考以下文章

截断具有许多子分区的表需要很长时间

Pyspark count() 在使用减法命令之前和之后需要很长时间

BigQuery - 删除重复记录有时需要很长时间

从 csv 文件中读取数据需要很长时间 [重复]

将 CSV 加载到 localhost 上的 phpmyadmin(长时间)

需要 PHP 逐行处理的 CSV 需要很长时间(或超时)才能进入 SQL 数据库