将系统属性传递给spark-submit并从类路径或自定义路径读取文件

Ata*_*ais 8 java scala apache-spark apache-spark-2.0 spark-submit

我最近发现了一种在Apache Spark中使用logback而不是log4j的方法(两者都用于本地使用spark-submit).然而,最后一块遗失了.

问题是Spark非常努力地不在logback.xml其类路径中查看设置.我已经找到了一种在本地执行期间加载它的方法:

到目前为止我有什么

基本上,检查系统属性logback.configurationFile,但加载logback.xml从我/src/main/resources/以防万一:

// the same as default: https://logback.qos.ch/manual/configuration.html
private val LogbackLocation = Option(System.getProperty("logback.configurationFile"))
// add some default logback.xml to your /src/main/resources
private lazy val defaultLogbackConf = getClass.getResource("/logback.xml").getPath

private def getLogbackConfigPath = {
   val path = LogbackLocation.map(new File(_).getPath).getOrElse(defaultLogbackConf)
   logger.info(s"Loading logging configuration from: $path")
   path
}
Run Code Online (Sandbox Code Playgroud)

然后当我初始化我的SparkContext时......

val sc = SparkContext.getOrCreate(conf)
sc.addFile(getLogbackConfigPath)
Run Code Online (Sandbox Code Playgroud)

我可以确认它在本地工作.

和谁玩 spark-submit

spark-submit \
  ...
  --master yarn \
  --class com.company.Main\
  /path/to/my/application-fat.jar \
  param1 param2 
Run Code Online (Sandbox Code Playgroud)

这给出了一个错误:

Exception in thread "main" java.io.FileNotFoundException: Added file file:/path/to/my/application-fat.jar!/logback.xml does not exist
Run Code Online (Sandbox Code Playgroud)

我认为这是无稽之谈,因为首先是应用程序,找到文件(根据我的代码)

getClass.getResource("/logback.xml").getPath
Run Code Online (Sandbox Code Playgroud)

然后,期间

sc.addFile(getLogbackConfigPath)
Run Code Online (Sandbox Code Playgroud)

事实证明......哇!那里没有文件!?有没有搞错!?为什么它不会在jar中找到该文件.它显然在那里,我做了三重检查.

另一种方法 spark-submit

所以我想,好吧.我将传递我的文件,因为我可以指定系统属性.我把logback.xml文件放在我旁边,application-fat.jar然后:

spark-submit \
  ...
  --conf spark.driver.extraJavaOptions="-Dlogback.configurationFile=/path/to/my/logback.xml" \
  --conf spark.executor.extraJavaOptions="-Dlogback.configurationFile=/path/to/my/logback.xml" \
  --master yarn \
  --class com.company.Main\
  /path/to/my/application-fat.jar \
  param1 param2 
Run Code Online (Sandbox Code Playgroud)

我得到与上面相同的错误.所以我的设置完全被忽略了!为什么?如何指定

-Dlogback.configurationFile
Run Code Online (Sandbox Code Playgroud)

正确地将它传递给驱动程序和执行程序?

谢谢!

Ata*_*ais 12

1.解决 java.io.FileNotFoundException

可能无法解决.

简单来说,SparkContext.addFile无法从Jar内部读取文件.我相信它被视为某些zip或类似的.

精细.

2.通过 -Dlogback.configurationFile

由于我对配置参数的误解,这无法正常工作.

因为我使用的--master yarn参数,但我不指定--deploy-modecluster它是默认的client.

阅读https://spark.apache.org/docs/1.6.1/configuration.html#application-properties

spark.driver.extraJavaOptions

注意:在客户端模式下,不能直接在应用程序中通过SparkConf设置此配置,因为驱动程序JVM已在此时启动.相反,请通过--driver-java-options命令行选项或在默认属性文件中设置它.

所以通过这个设置--driver-java-options工作:

spark-submit \
  ...
  --driver-java-options "-Dlogback.configurationFile=/path/to/my/logback.xml" \
  --master yarn \
  --class com.company.Main\
  /path/to/my/application-fat.jar \
  param1 param2 
Run Code Online (Sandbox Code Playgroud)

请注意 --driver-java-options

相比之下,必须--conf多个参数作为一个参数传递,例如:

--driver-java-options "-Dlogback.configurationFile=/path/to/my/logback.xml -Dother.setting=value" \
Run Code Online (Sandbox Code Playgroud)

以下不起作用

--driver-java-options "-Dlogback.configurationFile=/path/to/my/logback.xml" \
--driver-java-options "-Dother.setting=value" \
Run Code Online (Sandbox Code Playgroud)