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() 在使用减法命令之前和之后需要很长时间