我有一个集群,我执行 wholeTextFiles
其中应该拉了大约一百万个文本文件,总计大约 10GB
总共有一个namenode和两个datanode 30GB
每个内存4芯。数据存储在 HDFS
.
我不运行任何特殊参数和工作需要5个小时来读取数据。这是预期的吗?是否有任何参数可以加快读取速度(spark配置或分区、执行器的数量?)
我才刚开始,以前从来没有优化工作的必要
编辑:另外,有人能解释一下wholetextfiles函数是如何工作的吗(不是如何使用它,而是如何编程)。我对理解分区参数等很感兴趣。
编辑2:基准评估
所以我尝试在wholetextfile之后重新分区,问题是相同的,因为第一次读取仍然使用预定义的分区数,所以没有性能改进。一旦数据被加载,集群就会表现得非常好。。。在处理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.
那会是演出不好的原因吗?我该如何对冲?
另外,在执行savastextfile时,根据ambari控制台,我的速度是19mb/s。当读取wholetextfiles时,我的速度是300kb/s。。。。。
似乎通过增加 wholeTextFile(path,partitions)
,我的表现越来越好。但是仍然只有8个任务同时运行(我的CPU数量)。我在做基准测试来观察极限。。。
1条答案
按热度按时间3xiyfsfu1#
从评论中总结我的建议:
hdfs不适合存储许多小文件。首先,namenode将元数据存储在内存中,因此您可能拥有的文件和块的数量是有限的(对于典型的服务器,最大为100m块)。接下来,每次读取文件时,首先查询namenode中的块位置,然后连接到存储文件的datanode。这种连接和响应的开销非常大。
应始终检查默认设置。默认情况下,Spark从带有2个执行器的Yarn开始(
--num-executors
)各有一根线(--executor-cores
)以及512m的ram(--executor-memory
),只提供2个线程,每个线程的内存为512mb,对于实际任务来说,这是非常小的所以我的建议是:
启动Spark
--num-executors 4 --executor-memory 12g --executor-cores 4
这将给你更多的并行性-在这个特殊的情况下16个线程,这意味着16个任务并行运行使用
sc.wholeTextFiles
要读取文件,然后将其转储到压缩序列文件中(例如,使用snappy块级压缩),下面是一个如何执行此操作的示例:http://0x0fff.com/spark-hdfs-integration/. 这将大大减少在下一次迭代中读取它们所需的时间