Spark InProcessLauncher 未获取 Hadoop 配置

问题描述

我正在尝试使用 InProcessLauncher 从 Java Spring 应用程序提交集群模式 spark 2 应用程序。我之前使用了 SparkLauncher 类,该类有效,但它为每个作业启动了一个长期存在的 SparkSubmit java 进程,这会消耗太多资源,并且有大量作业在运行。

我的代码sparkLauncher.setMaster("yarn")sparkLauncher.setDeployMode("cluster")

在启动我的 Spring 应用程序之前,我将 HADOOP_CONF_DIR env 变量设置为包含我的配置(yarn-site.xml 等)的目录,并记录它正在获取此变量:

INFO  System Environment - HADOOP_CONF_DIR = /etc/hadoop/conf

然而,在提交时,我看到 INFO o.apache.hadoop.yarn.client.RMProxy - Connecting to ResourceManager at /0.0.0.0:8032 - 即它使用认的 0.0.0.0 而不是实际的 ResourceManager IP,当然它失败了。它似乎没有选择 Hadoop 配置。

我可以使用 spark-submit 直接从同一个 shell 提交作业,甚至可以直接调用 java -cp /usr/hdp/current/spark2-client/conf/:/usr/hdp/current/spark2-client/jars/*:/etc/hadoop/conf/ org.apache.spark.deploy.SparkSubmit ...。所以我不确定为什么我的 Spring App 没有选择相同的配置。

解决方法

通过将 conf 文件夹添加到类路径,我设法让我的应用程序获取了 hadoop 配置。这是 spark-submit 作为单独进程启动时为您所做的事情,但在使用 InProcessLauncher 时不会发生。

因为我的 Spring Boot 应用程序是使用 -jar xxx.jar 启动的,所以我无法在命令行上使用 -cp(不能与 -jar 结合使用),但必须将其添加到出现在罐子里。我通过将以下内容添加到 build.gradle(使用 Spring Boot gradle 插件)来做到这一点:

bootJar {
    manifest {
        attributes 'Class-Path': '/usr/hdp/current/spark2-client/conf/ /etc/hadoop/conf/'
    }
}