spark-submit 到 Amazon EMR 时如何指定自定义 log4j.configuration 的位置?
How to specify the location of custom log4j.configuration when spark-submit to Amazon EMR?
我正在尝试 运行 EMR 集群中的 spark 作业。
我的 spark-submit 我已经添加了配置以从 log4j.properties
中读取
--files log4j.properties --conf "spark.executor.extraJavaOptions=-Dlog4j.configuration=file:/log4j.properties"
我也添加了
log4j.rootLogger=INFO, file
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=/log/test.log
log4j.appender.file.MaxFileSize=10MB
log4j.appender.file.MaxBackupIndex=10
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %5p %c{7} - %m%n
在我的 log4j 配置中。
无论如何,我在控制台中看到了日志,尽管我没有看到生成的日志文件。我在这里做错了什么?
引用 spark-submit --help
:
--files FILES Comma-separated list of files to be placed in the working directory of each executor. File paths of these files in executors can be accessed via SparkFiles.get(fileName)
.
如果您不能使用 SparkFiles.get(fileName)
(对于 log4j 则不能),那么如何处理 FILES
并没有太多说明。
引用 SparkFiles.get
的 scaladoc:
Get the absolute path of a file added through SparkContext.addFile()
.
那也不会给你太多,但是建议看看source code of SparkFiles.get:
def get(filename: String): String =
new File(getRootDirectory(), filename).getAbsolutePath()
它的好处是 getRootDirectory()
uses an optional property or just the current working directory:
def getRootDirectory(): String =
SparkEnv.get.driverTmpDir.getOrElse(".")
这提供了一些工作,不是吗?
在驱动程序上,所谓的 driverTmpDir
目录应该很容易在 Web UI 的环境选项卡中找到(在 spark.files
属性 或类路径的 Spark 属性下在源列中标记为 "Added By User" 的条目)。
在执行器上,我会假设一个本地目录,所以我不会使用file:/log4j.properties
,而是使用
-Dlog4j.configuration=file://./log4j.properties
或
-Dlog4j.configuration=file:log4j.properties
注意指定本地工作目录的点(在第一个选项中)或无前导 /
(在后者中)。
如果您还没有考虑过,请不要忘记 spark.driver.extraJavaOptions
为驱动程序设置 Java 选项。到目前为止,您一直只关注执行者。
您可能想要将 -Dlog4j.debug=true
添加到 spark.executor.extraJavaOptions
中,它应该打印 log4j 用于查找 log4j.properties
.
的位置
我自己还没有在 EMR 或 YARN 集群上检查过这个答案,但相信这可能会给你一些提示,告诉你在哪里可以找到答案。 双手合十!
这是我用来 运行 我在 EMR 中的 uber-jar 的完整命令,我看到在驱动程序和执行程序节点中生成的日志文件。
spark-submit --class com.myapp.cloud.app.UPApp --master yarn --deploy-mode client --driver-memory 4g --executor-memory 2g --executor-cores 8 --文件 log4j.properties --conf "spark.executor.extraJavaOptions=-Dlog4j.configuration=file:log4j.properties" --conf "spark.driver.extraJavaOptions=-Dlog4j.configuration=file:log4j.properties -Dlog4j.debug=true" --conf "spark.executor.extraJavaOptions=-Dlog4j.configuration=file:log4j.properties" --conf "spark.eventLog.dir=/mnt/var/log/" uber-up-0.0.1.jar
其中 log4j.properties 在我的本地文件系统中。
使用 Spark 2.2.0 独立集群,执行器 JVM 首先启动,然后 Spark 分发应用程序 jar 和 --files
这意味着通过
spark.executor.extraJavaOptions=-Dlog4j.configuration=file:log4j-spark.xml
没有意义,因为该文件在执行程序 JVM 启动和 log4j 初始化时尚不存在(未下载)
如果你通过了
spark.executor.extraJavaOptions=-Dlog4j.debug -Dlog4j.configuration=file:log4j-spark.xml
您会在执行程序的 stderr 开始时发现加载 log4j 配置文件失败的尝试
log4j:ERROR Could not parse url [file:log4j-spark.xml].
java.io.FileNotFoundException: log4j-spark.xml (No such file or directory)
...
Using Spark's default log4j profile: org/apache/spark/log4j-defaults.properties
稍后记录从驱动程序下载 --files
18/07/18 17:24:12 INFO Utils: Fetching spark://123.123.123.123:35171/files/log4j-spark.xml to /ca/tmp-spark/spark-49815375-3f02-456a-94cd-8099a0add073/executor-7df1c819-ffb7-4ef9-b473-4a2f7747237a/spark-0b50a7b9-ca68-4abc-a05f-59df471f2d16/fetchFileTemp5898748096473125894.tmp
18/07/18 17:24:12 INFO Utils: Copying /ca/tmp-spark/spark-49815375-3f02-456a-94cd-8099a0add073/executor-7df1c819-ffb7-4ef9-b473-4a2f7747237a/spark-0b50a7b9-ca68-4abc-a05f-59df471f2d16/-18631083971531927447443_cache to /opt/spark-2.2.0-bin-hadoop2.7/work/app-20180718172407-0225/2/./log4j-spark.xml
它可能与 yarn 或其他集群管理器的工作方式不同,但对于独立集群,您似乎无法在 spark-submit 上为执行程序指定自己的日志记录配置。
您可以在您的作业代码中动态重新配置 log4j (override log4j configuration programmatically: file location for FileAppender),但您需要在执行程序的 JVM 中执行的某些 mapPartition lambda 中仔细执行此操作。或者,也许您可以将工作的第一阶段投入其中。尽管一切都很糟糕...
我正在尝试 运行 EMR 集群中的 spark 作业。
我的 spark-submit 我已经添加了配置以从 log4j.properties
中读取--files log4j.properties --conf "spark.executor.extraJavaOptions=-Dlog4j.configuration=file:/log4j.properties"
我也添加了
log4j.rootLogger=INFO, file
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=/log/test.log
log4j.appender.file.MaxFileSize=10MB
log4j.appender.file.MaxBackupIndex=10
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %5p %c{7} - %m%n
在我的 log4j 配置中。
无论如何,我在控制台中看到了日志,尽管我没有看到生成的日志文件。我在这里做错了什么?
引用 spark-submit --help
:
--files FILES Comma-separated list of files to be placed in the working directory of each executor. File paths of these files in executors can be accessed via
SparkFiles.get(fileName)
.
如果您不能使用 SparkFiles.get(fileName)
(对于 log4j 则不能),那么如何处理 FILES
并没有太多说明。
引用 SparkFiles.get
的 scaladoc:
Get the absolute path of a file added through
SparkContext.addFile()
.
那也不会给你太多,但是建议看看source code of SparkFiles.get:
def get(filename: String): String =
new File(getRootDirectory(), filename).getAbsolutePath()
它的好处是 getRootDirectory()
uses an optional property or just the current working directory:
def getRootDirectory(): String =
SparkEnv.get.driverTmpDir.getOrElse(".")
这提供了一些工作,不是吗?
在驱动程序上,所谓的 driverTmpDir
目录应该很容易在 Web UI 的环境选项卡中找到(在 spark.files
属性 或类路径的 Spark 属性下在源列中标记为 "Added By User" 的条目)。
在执行器上,我会假设一个本地目录,所以我不会使用file:/log4j.properties
,而是使用
-Dlog4j.configuration=file://./log4j.properties
或
-Dlog4j.configuration=file:log4j.properties
注意指定本地工作目录的点(在第一个选项中)或无前导 /
(在后者中)。
如果您还没有考虑过,请不要忘记 spark.driver.extraJavaOptions
为驱动程序设置 Java 选项。到目前为止,您一直只关注执行者。
您可能想要将 -Dlog4j.debug=true
添加到 spark.executor.extraJavaOptions
中,它应该打印 log4j 用于查找 log4j.properties
.
我自己还没有在 EMR 或 YARN 集群上检查过这个答案,但相信这可能会给你一些提示,告诉你在哪里可以找到答案。 双手合十!
这是我用来 运行 我在 EMR 中的 uber-jar 的完整命令,我看到在驱动程序和执行程序节点中生成的日志文件。
spark-submit --class com.myapp.cloud.app.UPApp --master yarn --deploy-mode client --driver-memory 4g --executor-memory 2g --executor-cores 8 --文件 log4j.properties --conf "spark.executor.extraJavaOptions=-Dlog4j.configuration=file:log4j.properties" --conf "spark.driver.extraJavaOptions=-Dlog4j.configuration=file:log4j.properties -Dlog4j.debug=true" --conf "spark.executor.extraJavaOptions=-Dlog4j.configuration=file:log4j.properties" --conf "spark.eventLog.dir=/mnt/var/log/" uber-up-0.0.1.jar
其中 log4j.properties 在我的本地文件系统中。
使用 Spark 2.2.0 独立集群,执行器 JVM 首先启动,然后 Spark 分发应用程序 jar 和 --files 这意味着通过
spark.executor.extraJavaOptions=-Dlog4j.configuration=file:log4j-spark.xml
没有意义,因为该文件在执行程序 JVM 启动和 log4j 初始化时尚不存在(未下载)
如果你通过了
spark.executor.extraJavaOptions=-Dlog4j.debug -Dlog4j.configuration=file:log4j-spark.xml
您会在执行程序的 stderr 开始时发现加载 log4j 配置文件失败的尝试
log4j:ERROR Could not parse url [file:log4j-spark.xml].
java.io.FileNotFoundException: log4j-spark.xml (No such file or directory)
...
Using Spark's default log4j profile: org/apache/spark/log4j-defaults.properties
稍后记录从驱动程序下载 --files
18/07/18 17:24:12 INFO Utils: Fetching spark://123.123.123.123:35171/files/log4j-spark.xml to /ca/tmp-spark/spark-49815375-3f02-456a-94cd-8099a0add073/executor-7df1c819-ffb7-4ef9-b473-4a2f7747237a/spark-0b50a7b9-ca68-4abc-a05f-59df471f2d16/fetchFileTemp5898748096473125894.tmp
18/07/18 17:24:12 INFO Utils: Copying /ca/tmp-spark/spark-49815375-3f02-456a-94cd-8099a0add073/executor-7df1c819-ffb7-4ef9-b473-4a2f7747237a/spark-0b50a7b9-ca68-4abc-a05f-59df471f2d16/-18631083971531927447443_cache to /opt/spark-2.2.0-bin-hadoop2.7/work/app-20180718172407-0225/2/./log4j-spark.xml
它可能与 yarn 或其他集群管理器的工作方式不同,但对于独立集群,您似乎无法在 spark-submit 上为执行程序指定自己的日志记录配置。
您可以在您的作业代码中动态重新配置 log4j (override log4j configuration programmatically: file location for FileAppender),但您需要在执行程序的 JVM 中执行的某些 mapPartition lambda 中仔细执行此操作。或者,也许您可以将工作的第一阶段投入其中。尽管一切都很糟糕...