Spark:sc.WholeTextFiles 需要很长时间才能执行

Spark: sc.WholeTextFiles takes a long time to execute

我有一个集群,我执行了 wholeTextFiles,它应该提取大约一百万个文本文件,总计大约 10GB 我有一个 NameNode 和两个 DataNode,每个有 30GB 个 RAM,每个有 4 个内核。数据存储在HDFS.

我没有 运行 任何特殊参数,并且该作业仅读取数据就需要 5 个小时。这是预期的吗?是否有任何参数可以加快读取速度(spark 配置或分区、执行程序数量?)

我才刚刚起步,以前从未需要优化作业

编辑: 此外,有人可以准确解释 wholeTextFiles 函数的工作原理吗? (不是如何使用它,而是它是如何编程的)。我很想了解分区参数等

编辑 2: 基准评估

所以我尝试在wholeTextFile之后重新分区,问题是一样的,因为第一次读取仍然使用预定义的分区数,所以没有性能提升。加载数据后,集群性能非常好......在处理数据(对于 200k 文件)时,整个文本文件上出现以下警告消息:

15/01/19 03:52:48 WARN scheduler.TaskSetManager: Stage 0 contains a task of very large size (15795 KB). The maximum recommended task size is 100 KB.

这会是表现不佳的原因吗?我该如何对冲?

此外,在执行 saveAsTextFile 时,根据 Ambari 控制台,我的速度是 19MB/s。使用 wholeTextFiles 进行读取时,我的速度为 300kb/s.....

似乎通过增加 wholeTextFile(path,partitions) 中的分区数量,我的性能得到了改善。但仍然只有 8 个任务同时 运行ning(我的 CPU 数量)。我正在进行基准测试以观察极限...

根据评论总结我的建议:

  1. HDFS 不适合存储许多小文件。首先,NameNode 将元数据存储在内存中,因此您可能拥有的文件和块的数量是有限的(~100m 块是典型服务器的最大值)。接下来,每次读取文件时,首先向 NameNode 查询块位置,然后连接到存储文件的 DataNode。这种连接和响应的开销确实很大。
  2. 应始终检查默认设置。默认情况下,Spark 在 YARN 上启动,有 2 个执行程序(--num-executors),每个执行程序有 1 个线程(--executor-cores)和 512m RAM(--executor-memory),给你只有 2 个线程,每个线程有 512MB RAM,这对于现实世界的任务来说真的很小

所以我的建议是:

  1. --num-executors 4 --executor-memory 12g --executor-cores 4 启动 Spark,这会给你更多的并行性 - 在这个特殊情况下有 16 个线程,这意味着 16 个任务 运行 并行
  2. 使用 sc.wholeTextFiles 读取文件,然后将它们转储到压缩序列文件中(例如,使用 Snappy 块级压缩),这是如何完成此操作的示例:http://0x0fff.com/spark-hdfs-integration/。这将大大减少下一次迭代读取它们所需的时间