在 Yarn 上对 Spark 使用类型安全配置
Using typesafe config with Spark on Yarn
我有一个从配置文件中读取数据的 Spark 作业。此文件是类型安全的配置文件。
读取配置的代码如下所示:
ConfigFactory.load().getConfig("com.mycompany")
现在我不 assemble application.conf 作为我的 uber jar 的一部分,因为我想将文件作为外部文件传递
我想使用的外部 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.run(ApplicationMaster.scala:542)
所以我的问题是:有人知道如何使用 spark-submit 和 yarn 加载本地机器上的外部类型安全 application.conf 文件吗?
我尝试了 and in Typesafe Config in Spark and also in How to pass -D parameter or environment variable to Spark job? 中的一些解决方案,但没有任何效果
对于解决此问题的任何指导,我将不胜感激
提前致谢
因此,通过深入研究 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 不需要 extraJavaOpts(正如我的问题中所写)。问题在于 Spark 仅使用传递的最后一个 --files 参数,这就是传递 log4j 的原因。为了使用 log4j.xml 我还必须采取以下步骤
- 像这样向 spark 提交添加另一行:
--conf spark.driver.extraJavaOptions="-Dlog4j.configuration=file:log4j.xml"
- 注意,一旦你使用 --files 传递它,你就可以只引用文件名而不需要任何路径
注意:我还没有尝试过,但从我看到的情况来看,如果你试图在客户端模式下 运行 它,我认为 spark.driver.extraJavaOptions
行应该重命名为 driver- java-选项
而已。如此简单,我希望这些事情能得到更好的记录。我希望这个答案对某人有所帮助
干杯
尽管这是一年前的问题,但我对 ConfigFactor 也有类似的问题。
为了能够读取 application.conf
文件,您必须做两件事。
- 将文件提交给 driver。这是通过以下代码
--files /path/to/file/application.conf
完成的。请注意,您可以根据需要从 HDFS 读取它。
- 提交com.typesafe.config包。这是通过
--packages com.typesafe:config:version
. 完成的
由于 application.conf
文件将与主 jar 应用程序位于同一临时目录中,您可以在代码中假设。
使用上面给出的答案 (https://whosebug.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
我有一个从配置文件中读取数据的 Spark 作业。此文件是类型安全的配置文件。
读取配置的代码如下所示:
ConfigFactory.load().getConfig("com.mycompany")
现在我不 assemble application.conf 作为我的 uber jar 的一部分,因为我想将文件作为外部文件传递
我想使用的外部 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.run(ApplicationMaster.scala:542)
所以我的问题是:有人知道如何使用 spark-submit 和 yarn 加载本地机器上的外部类型安全 application.conf 文件吗?
我尝试了
对于解决此问题的任何指导,我将不胜感激
提前致谢
因此,通过深入研究 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 不需要 extraJavaOpts(正如我的问题中所写)。问题在于 Spark 仅使用传递的最后一个 --files 参数,这就是传递 log4j 的原因。为了使用 log4j.xml 我还必须采取以下步骤
- 像这样向 spark 提交添加另一行:
--conf spark.driver.extraJavaOptions="-Dlog4j.configuration=file:log4j.xml"
- 注意,一旦你使用 --files 传递它,你就可以只引用文件名而不需要任何路径
注意:我还没有尝试过,但从我看到的情况来看,如果你试图在客户端模式下 运行 它,我认为 spark.driver.extraJavaOptions
行应该重命名为 driver- java-选项
而已。如此简单,我希望这些事情能得到更好的记录。我希望这个答案对某人有所帮助
干杯
尽管这是一年前的问题,但我对 ConfigFactor 也有类似的问题。
为了能够读取 application.conf
文件,您必须做两件事。
- 将文件提交给 driver。这是通过以下代码
--files /path/to/file/application.conf
完成的。请注意,您可以根据需要从 HDFS 读取它。 - 提交com.typesafe.config包。这是通过
--packages com.typesafe:config:version
. 完成的
由于 application.conf
文件将与主 jar 应用程序位于同一临时目录中,您可以在代码中假设。
使用上面给出的答案 (https://whosebug.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