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 数量)。我正在进行基准测试以观察极限...
根据评论总结我的建议:
- HDFS 不适合存储许多小文件。首先,NameNode 将元数据存储在内存中,因此您可能拥有的文件和块的数量是有限的(~100m 块是典型服务器的最大值)。接下来,每次读取文件时,首先向 NameNode 查询块位置,然后连接到存储文件的 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 块级压缩),这是如何完成此操作的示例:http://0x0fff.com/spark-hdfs-integration/。这将大大减少下一次迭代读取它们所需的时间
我有一个集群,我执行了 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 数量)。我正在进行基准测试以观察极限...
根据评论总结我的建议:
- HDFS 不适合存储许多小文件。首先,NameNode 将元数据存储在内存中,因此您可能拥有的文件和块的数量是有限的(~100m 块是典型服务器的最大值)。接下来,每次读取文件时,首先向 NameNode 查询块位置,然后连接到存储文件的 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 块级压缩),这是如何完成此操作的示例:http://0x0fff.com/spark-hdfs-integration/。这将大大减少下一次迭代读取它们所需的时间