我有一个集群,我执行了 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 个任务同时运行(我的 CPU 数量)。我正在进行基准测试以观察极限...
最佳答案
从评论中总结我的建议:
- HDFS 不适合存储许多小文件。首先,NameNode 将元数据存储在内存中,因此您可能拥有的文件和 block 的数量是有限的(~100m block 是典型服务器的最大值)。接下来,每次读取文件时,首先向 NameNode 查询 block 位置,然后连接到存储文件的 DataNode。这种连接和响应的开销确实很大。
- 应始终检查默认设置。默认情况下,Spark 在 YARN 上启动时有 2 个执行器(
--num-executors
),每个执行器有 1 个线程(--executor-cores
)和 512m RAM(- -executor-memory
),只给你 2 个线程,每个线程 512MB RAM,这对于实际任务来说真的很小
所以我的建议是:
- 用
--num-executors 4 --executor-memory 12g --executor-cores 4
启动 Spark,这会给你更多的并行性——在这个特殊情况下有 16 个线程,这意味着有 16 个任务在运行并行 - 使用
sc.wholeTextFiles
读取文件,然后将它们转储到压缩序列文件中(例如,使用 Snappy block 级压缩),这是如何完成此操作的示例:http://0x0fff.com/spark-hdfs-integration/ .这将大大减少在下一次迭代中阅读它们所需的时间
关于scala - Spark : sc. WholeTextFiles 执行时间过长,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27989617/