使用Hadoop配置的应用程序配置

时间:2015-09-16 01:46:22

标签: java hadoop log4j hdfs slf4j

我使用Maven构建了一个Java应用程序。它使用Maven Shade插件打包为可执行jar。此应用程序可以执行多项操作 - 其中一项是将数据上载到Hadoop集群。我使用以下命令执行程序:

$ hadoop jar <app_name>.jar <app_arg1> <app_arg2> ...

我的应用程序使用SLF4J和Log4J绑定进行日志记录 - ,Hadoop 也是如此。

使用hadoop jar命令时,Hadoop自己的Log4J配置文件会覆盖我的应用程序的Log4J配置文件。

如何阻止我的应用程序的Log4J配置文件被覆盖?

注意:

  • 相关依赖项:hadoop-core:1.2.1slf4j-api:1.7.12slf4j-log4j12:1.7.12
  • 我使用的是hadoop jar命令,而不是java -jar。与Hadoop集群交互的应用程序代码仅在使用hadoop jar命令时才有效。我在a previous SO question
  • 中概述了这个问题

编辑1:(2015年2月10日)

我做了一些事情。

首先,我更改了Log4J配置文件的名称,以避免名称与Hadoop使用的默认log4j.properties文件冲突:

log4j-<app_name>.properties

其次,我设置了HADOOP_OPTS环境变量来告诉Log4J配置文件的名称是什么:

HADOOP_OPTS=-Dlog4j.configurationi=log4j-<app_name>.properties

第三,我设置了HADOOP_CLASSPATH环境变量,以确保hadoop jar命令可以获取打包在uber jar中的配置文件:

HADOOP_CLASSPATH=/absolute/path/to/<app_name>.jar

通过这些更改,我的应用程序现在可以按预期使用它自己的Log4J配置文件。感觉像黑客(因为我更喜欢使用java -jar命令),但它解决了我的问题。

1 个答案:

答案 0 :(得分:0)

默认情况下,Hadoop框架jar出现在classpath中用户的jar之前。您可以使用命令中的 -Dmapreduce.job.user.classpath.first=true 参数设置(用户)jar的首选项。新命令如下所示。

hadoop jar <app_name>.jar -Dmapreduce.job.user.classpath.first=true <<app_arg1>> <<app_arg2>> ...

或者您可以将以下配置放在mapred-site.xml中,以便始终优先考虑用户classpath

<property>
    <name>mapreduce.job.user.classpath.first</name>
    <value>true</value>
</property>

您可以在作业配置中以编程方式设置此项。

job.getConfiguration().set("mapreduce.job.user.classpath.first", "true");

你可以通过任何方式设置它,它永远不会迟到。