将我们的应用程序从2.6.0更新到2.7.1时,我无法正确运行映射器作业,并在作业日志中显示以下内容:
SEVERE: Error starting MRAppMaster
java.lang.NoClassDefFoundError: Could not initialize class org.apache.log4j.LogManager
at org.slf4j.impl.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:64)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:285)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:305)
at org.apache.hadoop.security.authentication.util.KerberosName.<clinit>(KerberosName.java:43)
at org.apache.hadoop.security.UserGroupInformation.initialize(UserGroupInformation.java:275)
at org.apache.hadoop.security.UserGroupInformation.setConfiguration(UserGroupInformation.java:311)
at org.apache.hadoop.mapreduce.v2.app.MRAppMaster.initAndStartAppMaster(MRAppMaster.java:1492)
at org.apache.hadoop.mapreduce.v2.app.MRAppMaster.main(MRAppMaster.java:1448)
我认为最初这是一个特别在我们的作业中的类路径问题,我们的库被复制到分布式缓存,然后在每个作业运行之前添加到作业的类路径中。虽然所有的库都已到位并且在作业运行之前已添加到类路径中,但确认了一些验证。
hadoop classpath
和yarn classpath
都显示hadoop/share/hadoop
下的所有内容都在类路径上,其中包含有问题的类所属的lib(log4j)。
我们有点想法。正在执行的代码在我们的2.6.0分支上运行得非常好。我们可能会缺少什么?
答案 0 :(得分:1)
所以这最终成为一个微妙的问题,在类路径中提供了有问题的类 ,但是当它最初被加载时,它引发了一个空变量,并且后续的异常/堆栈跟踪表明这在Hadoop的深处某处丢失了!
在Hadoop 2.7.x中,ContainerLogAppender获得了setContainerLogFile的功能。不幸的是,如果log4j.appender.CLA.containerLogFile=${hadoop.root.logfile}
中没有设置log4j.appender.CRLA.containerLogFile=${hadoop.root.logfile}
和hadoop/etc/hadoop/container-log4j.properties
,那么NPE就会爆炸。如果之前它默认为&#34; syslog&#34;,它现在没有默认值,并且很乐意让你自己挖洞。因此,当类在被类加载器加载时爆炸时,它们实际上被移除了,因此,为什么作业报告NoClassDefFoundError
而不是ClassNotFoundException
进一步下线。
答案 1 :(得分:0)
我认为,因为Hadoop发布2.7.1版本https://ahmetalpbalkan.com/blog/azure-rest-api-with-oauth2/,您面临的问题可能是因为较旧的sl4j jar。您能否尝试将sl4j.jar更新为最新版本。