作者:玄天战猫 | 来源:互联网 | 2023-05-26 14:01
我有一个集群,我执行wholeTextFiles
它应该提取大约一百万个文本文件,总计大约10GB
总共我有一个NameNode和两个DataNode 30GB
每个RAM,每个4个核心.数据存储在HDFS
.
我没有运行任何特殊参数,作业需要5个小时才能读取数据.这是预期的吗?是否有任何参数可以加快读取(火花配置或分区,执行器数量?)
我刚刚开始,我以前从未需要优化工作
编辑:此外,有人可以准确解释整个文本功能的工作原理吗?(不是如何使用它,而是如何编程).我对理解分区参数等非常感兴趣.
编辑2:基准评估
所以我在整个文本文件之后尝试重新分区,问题是一样的,因为第一次读取仍然使用预定义数量的分区,因此没有性能改进.加载数据后,集群执行得非常好...在处理整个文本文件时,我在处理数据(对于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数量).我正在进行基准测试以观察极限......
1> 0x0FFF..:
从评论中总结我的建议:
HDFS不适合存储许多小文件.首先,NameNode将元数据存储在内存中,因此您可能拥有的文件和块的数量是有限的(典型服务器的最大约为100m块).接下来,每次读取文件时,首先查询NameNode的块位置,然后连接到存储该文件的DataNode.这种联系和响应的开销非常大.
应始终检查默认设置.默认情况下,Spark在YARN上启动,带有2个执行器(--num-executors
),每个执行1个线程(--executor-cores
)和--executor-memory
512米RAM(),每个只有2个线程,每个512MB RAM,这对于实际任务来说非常小
所以我的建议是:
启动Spark --num-executors 4 --executor-memory 12g --executor-cores 4
可以提供更多的并行性 - 在这种特殊情况下有16个线程,这意味着16个并行运行的任务
使用sc.wholeTextFiles
读取这些文件,然后将它们转储到压缩的序列文件(例如,与斯纳皮块级压缩),这里有一个如何可以做到这一点的例子:http://0x0fff.com/spark-hdfs-integration/.这将大大减少下次迭代读取它们所需的时间
从这开始:http://stackoverflow.com/questions/17875277/reading-file-as-single-record-in-hadoop - 一次性读取整个文件.这样你就可以在内存缓冲区中拥有一个完整的文件,之后你就可以将Java库应用于gunzip这个缓冲区并解压缩其内容