一、问题描述:
1.1、具体说明:
在利用spark-yarn jar包中的submitApplication方法将spark 任务远程提交到yarn 上的过程中,程序会将spark任务所用到的jar 包 上传至hdfs的某个暂存目录中。每次提交任务 ,程序都会将spark 用到的所有jar 包都上传至hdfs的某个暂存目录中,而且每次上传的hdfs 目录都不同(暂存目录路径和applicationId有关),随着提交任务的增多,hdfs 上的文件就会越来越多,最终导致hdfs 上小文件过多 ,影响hdfs 集群的正常运行。
1.2、相关代码:
ApplicationId appId = client.submitApplication();
1.3、代码运行日志片段:
INFO Client: Uploading resource hdfs://nameservice1:8020/spark/HikariCP-java7-2.4.12.jar -> hdfs://nameservice1/user/cloudera-scm/.sparkStaging/application_1690970479248_0356/HikariCP-java7-2.4.12.jar
1.4、日志分析:
从日志中可以看出 ,submitApplication方法会将hdfs://nameservice1:8020/spark/下的所有jar包上传至hdfs://nameservice1/user/clouderascm/.sparkStaging/application_1690970479248_0356/路径下。application_1690970479248_0356为该任务提交到yarn 上的应用id。
从程序效率的角度看,这个上传至hdfs的操作就是多余且费时的,因为
1、spark 所需的所有jar包都已经在hdfs 上了,没必要再上传一份至hdfs的另一路径。
2 、如果上传的jar很多 ,这必然会极大的增加任务提交的时间,影响程序提交spark任务的效率。
3、随着任务提交的增多,hdfs上的文件会越来越多,给hdfs集群造成压力 ,影响集群的正常运行。
二、优化方案:
2.1、优化步骤:
1、将程序所用的jar包都上传至hdfs 的某个路径下,例如:
hdfs://nameservice1:8020/spark/
2、将以下两个参数的值 都设置成hdfs上相同的路径(1步骤的路径):
spark.yarn.stagingDir //提交应用程序时使用的暂存目录
spark.yarn.jars //包含Spark类的jar的位置
例如:
spark.yarn.stagingDir hdfs://nameservice1:8020/spark/
spark.yarn.jars hdfs://nameservice1:8020/spark/*.jar
2.2、 优化后代码日志片段:
INFO Client: Source and destination file systems are the same. Not copying hdfs://nameservice1:8020/spark/HdrHistogram-2.1.9.jar
2.3、日志分析
从日志中可以看出,已经不存在hdfs copy的操作了。
至此,优化结束。