【问题标题】:What is happening during the "down time" when Spark is reading in big data sets on S3?当 Spark 在 S3 上读取大数据集时,在“停机时间”期间发生了什么?
【发布时间】:2019-04-23 08:33:42
【问题描述】:

我在 AWS S3 中有一堆 JSON 数据 - 比如说 100k 个文件,每个文件大约 5MB - 我正在使用 Spark 2.2 的 DataFrameReader 通过以下方式读取和处理它们:

sparkSession.read.json(...)

我发现 Spark 在开始计算之前只会挂起 5 分钟左右。对于较大的数据集,这可能需要数小时。当我说“挂起”时,我的意思是终端可视化指示集群正在哪个阶段以及它有多远没有出现 - 据我所知,它以某种方式位于阶段之间。

Spark 在此期间在做什么,我该如何帮助它更快地运行?

我有两个想法,但似乎都错了。

我的第一个想法是 Spark 试图列出它需要进行计算的所有文件。我通过实际离线创建文件列表并将它们直接提供给 Spark 而不是使用 glob 语法来测试这一点:

val fileList = loadFiles() sparkSession.read.json(fileList:_*)

这实际上导致“悬挂”期持续更长时间!

我的第二个想法是 Spark 正在利用这段时间为所有数据创建一个模式。但我通过手动指定模式排除了这一点:

val schema = createSchema() sparksession.read.schema(schema).json(...)

这里的“挂起”期和以前一样,但总体上计算要快得多。

所以我不太确定发生了什么或如何诊断它。还有其他人遇到这个吗?

【问题讨论】:

  • 我不能真正告诉你 spark 在做什么,但我可以说 spark 从不喜欢阅读许多小文件。如果您事先有任何方法将文件聚合成更少但更大的文件(例如至少 500MB),您应该会看到速度大大提高。
  • @GliennieHellesSindholt 谢谢你的建议——既然你提到了它,我可以想到我使用过的其他大型数据集,它们的分区效率更高,而且它们没有这个问题。我仍然对不需要重组数据的解决方法抱有适度的希望,但这也许是最好的策略。根据您的经验,用于此目的的文件大小是否有上限?也许这取决于集群?
  • 好吧,我使用 S3 的上限为 5GB(或者至少他们曾经使用过 - 不确定是否实际删除了),所以我的文件总是小于 5GB。然而,在我所有的写作工作中,我确实确保将数据存储在少数但大文件中。
  • @GlennieHellesSindholt 我采纳了您/Steve 的建议,结果显着——使用更少但更大的文件(约 2.6gb)消除了“停机时间”,并且工作比以前运行得更快。谢谢!

标签: apache-spark


【解决方案1】:

在 S3 中列出目录树的成本非常高,“分区”。这就是你正在经历的。

修复

  • 更少、更大的文件
  • 较浅的目录树

【讨论】:

  • 谢谢 - 考虑到我的数据组织方式,这听起来很合理。然而,我原以为提供完整的文件列表(没有 glob)可以省去解析目录树的麻烦——在我的实验中,这实际上让事情变得更糟。是否有其他方法可以缓存目录树或加快未来计算的速度?我正在对相同的数据进行许多计算,因此最好的策略可能是将文件合并在一起并按照您的建议简化目录结构。
  • 是的,合并很好,不仅是为了列出,而且是为了调度:每个工作人员一次将被安排一个文件的全部或部分:文件越大,每个人可以做的工作就越多在它需要与驱动程序交谈以提交该工作并请求更多内容之前
  • +spark 可能会获取文件列表并重新扫描它,因为它不知道哪些是目录,哪些是文件。每个文件一个 HEAD 请求。
  • 我硬着头皮对数据进行了重组,使目录树平坦,有 1000 个文件,而不是接近 100 万个。它得到了回报:完全消除了“停机时间”,各种计算的运行速度明显加快。所以你在钱上是对的。 (现在尝试说服系统团队改变我们获取数据的方式......)
猜你喜欢
  • 1970-01-01
  • 2017-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-24
  • 1970-01-01
  • 2013-03-29
  • 1970-01-01
相关资源
最近更新 更多