我有一个Spark作业,从配置文件中读取数据。这是一个类型安全的配置文件。
读取配置的代码如下所示:
ConfigFactory.load().getConfig("com.mycompany")
现在我没有将application.conf组装为我的uber jar的一部分,因为我想将该文件作为外部文件传递
我想使用的external application.conf的内容如下:
com.mycompany {
//configurations my program needs
}
这个application.conf文件存在于我的本地机器文件系统(而不是HDFS)
我正在使用Spark 1.6.1与Yarn
我的spark-submit命令如下:
LOG4J_FULL_PATH=/log4j-path
ROOT_DIR=/application.conf-path
/opt/deploy/spark/bin/spark-submit
--class com.mycompany.Main
--master yarn
--deploy-mode cluster
--files $ROOT_DIR/application.conf
--files $LOG4J_FULL_PATH/log4j.xml
--conf spark.executor.extraClassPath="-Dconfig.file=file:application.conf"
--driver-class-path $ROOT_DIR/application.conf
--verbose
/opt/deploy/lal-ml.jar
我收到的异常是:
2016-11-09 12:32:14 ERROR ApplicationMaster:95 - User class threw exception: com.typesafe.config.ConfigException$Missing: No configuration setting found for key 'com'
com.typesafe.config.ConfigException$Missing: No configuration setting found for key 'com'
at com.typesafe.config.impl.SimpleConfig.findKey(SimpleConfig.java:124)
at com.typesafe.config.impl.SimpleConfig.find(SimpleConfig.java:147)
at com.typesafe.config.impl.SimpleConfig.find(SimpleConfig.java:159)
at com.typesafe.config.impl.SimpleConfig.find(SimpleConfig.java:164)
at com.typesafe.config.impl.SimpleConfig.getObject(SimpleConfig.java:218)
at com.typesafe.config.impl.SimpleConfig.getConfig(SimpleConfig.java:224)
at com.typesafe.config.impl.SimpleConfig.getConfig(SimpleConfig.java:33)
at com.mycompany.Main$.main(Main.scala:36)
at com.mycompany.Main.main(Main.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.spark.deploy.yarn.ApplicationMaster$$anon$2.run(ApplicationMaster.scala:542)
所以我的问题是:有没有人知道我如何加载一个外部类型安全的应用程序。配置文件,坐在我的本地机器与spark-submit和yarn?
我尝试以下一些解决方案如何添加一个类型安全的配置文件位于HDFS spark-submit(集群模式)?以及Spark中的Typesafe配置以及如何将-D参数或环境变量传递给Spark作业?
我将感谢任何解决这个问题的指导
Thanks in advance
因此,在Spark 1.6.1源代码中进行了一些挖掘,我找到了解决方案。
这些是您需要采取的步骤,以便在使用集群模式提交到yarn时获得您的应用程序使用的log4j和application.conf:
- 当传递几个文件时,就像我正在传递application.conf和log4j.xml文件一样,你需要使用像这样的一行来提交它们:
--files "$ROOT_DIR/application.conf,$LOG4J_FULL_PATH/log4j.xml"
(用逗号分隔它们) - 这就是application.conf的内容。application.conf不需要额外的javaopts(如我的问题中所写)。问题是Spark只使用了传递的最后一个——files参数,这就是传递log4j的原因。为了使用log4j.xml,我还必须执行以下步骤
--conf spark.driver.extraJavaOptions="-Dlog4j.configuration=file:log4j.xml"
-注意,一旦你用——files传递它,你可以只引用文件名,而不需要任何路径注意:我没有尝试过,但从我看到的,如果你试图在客户端模式下运行它,我认为spark.driver.extraJavaOptions
行应该重命名为类似driver-java-options的东西这是它。如此简单,我希望这些事情能被更好地记录下来。我希望这个答案能对某人有所帮助。
欢呼
尽管这是一年前的问题,但我在ConfigFactor中遇到了类似的问题。为了能够读取application.conf
文件,您必须做两件事。
- 向驱动程序提交文件。这是用以下代码
--files /path/to/file/application.conf
完成的。请注意,如果您愿意,您可以从HDFS读取它。提交com.typesafe.config包。这是通过--packages com.typesafe:config:version
完成的。
由于application.conf
文件将位于与主jar应用程序相同的临时目录中,您可以在代码中假设:
使用上面给出的答案(https://stackoverflow.com/a/40586476/6615465),这个问题的代码如下:
LOG4J_FULL_PATH=/log4j-path
ROOT_DIR=/application.conf-path
/opt/deploy/spark/bin/spark-submit
--packages com.typesafe:config:1.3.2
--class com.mycompany.Main
--master yarn
--deploy-mode cluster
--files "$ROOT_DIR/application.conf, $LOG4J_FULL_PATH/log4j.xml"
--conf spark.executor.extraClassPath="-Dconfig.file=file:application.conf"
--driver-class-path $ROOT_DIR/application.conf
--verbose
/opt/deploy/lal-ml.jar