@[TOC](kettlet5.4提交MapReduce程序出现log4j:ERROR setFile(null,true) call failed.问题解决)
一、问题描述
当在kettle中设计好mapreduce程序后,运行提交程序到Hadoop集群,在kettle这边提升都是执行成功的,但是在Hadoop的yarn web页面(即访问hadoop001:8088端口)会看到程序一直处于RUNNING状态,查看日志后,发现如下的错误:
log4j:ERROR setFile(null,true) call failed.
java.io.FileNotFoundException: /training/hadoop-2.7.3/logs/userlogs/application_1623326307589_0001/container_162000001 (Is a directory)
at java.io.FileOutputStream.open0(Native Method)
at java.io.FileOutputStream.open(FileOutputStream.java:270)
at java.io.FileOutputStream.<init>(FileOutputStream.java:213)
at java.io.FileOutputStream.<init>(FileOutputStream.java:133)
at org.apache.log4j.FileAppender.setFile(FileAppender.java:294)
at org.apache.log4j.FileAppender.activateOptions(FileAppender.java:165)
at org.apache.hadoop.yarn.ContainerLogAppender.activateOptions(ContainerLogAppender.java:55)
at org.apache.log4j.config.PropertySetter.activate(PropertySetter.java:307)
at org.apache.log4j.config.PropertySetter.setProperties(PropertySetter.java:172)
at org.apache.log4j.config.PropertySetter.setProperties(PropertySetter.java:104)
at org.apache.log4j.PropertyConfigurator.parseAppender(PropertyConfigurator.java:842)
at org.apache.log4j.PropertyConfigurator.parseCategory(PropertyConfigurator.java:768)
at org.apache.log4j.PropertyConfigurator.configureRootCategory(PropertyConfigurator.java:648)
at org.apache.log4j.PropertyConfigurator.doConfigure(PropertyConfigurator.java:514)
at org.apache.log4j.PropertyConfigurator.doConfigure(PropertyConfigurator.java:580)
at org.apache.log4j.helpers.OptionConverter.selectAndConfigure(OptionConverter.java:526)
at org.apache.log4j.LogManager.<clinit>(LogManager.java:127)
at org.apache.log4j.Logger.getLogger(Logger.java:104)
at org.apache.commons.logging.impl.Log4JLogger.getLogger(Log4JLogger.java:262)
at org.apache.commons.logging.impl.Log4JLogger.<init>(Log4JLogger.java:108)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.apache.commons.logging.impl.LogFactoryImpl.createLogFromClass(LogFactoryImpl.java:1025)
at org.apache.commons.logging.impl.LogFactoryImpl.discoverLogImplementation(LogFactoryImpl.java:844)
at org.apache.commons.logging.impl.LogFactoryImpl.newInstance(LogFactoryImpl.java:541)
at org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:292)
at org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:269)
at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:657)
at org.apache.hadoop.service.AbstractService.<clinit>(AbstractService.java:43)
二、问题产生原因
- 主要原因:虚拟机资源不足,导致配置文件相关属性参数值过低导致。
经过检查发现,这个错误是并不是因为权限问题,而是因为yarn配置文件中有些配置属性的参数值过低,导致其无法分配container,往往MapReduce程序在启动的时候会启动两个container,一个container用于启动MR Application Master,另外一个用于启动mapreduce。发生上述错误时的参数的yarn-site.xml(包含虚拟机中配置和kettle中配置
)参数配置如下:
<configuration>
<property>
<name>yarn.resourcemanager.hostname</name>
<value>hadoop001</value>
</property>
<property>
<name>yarn.nodemanager.hostname</name>
<value>hadoop001</value>
</property>
<property>
<name>yarn.resourcemanager.address</name>
<value>hadoop001:8032</value>
</property>
<!-- 由于虚拟机内存有限,需要设置NodeManager内存为2G或者更小些,但不要小于1G -->
<property>
<name>yarn.nodemanager.resource.memory-mb</name>
<value>2048</value>
</property>
<!-- 由于Hadoop默认该配置为1024M,由于虚拟机内存有限,故设置最小分配内存为256M -->
<property>
<name>yarn.scheduler.minimum-allocation-mb</name>
<value>256</value>
</property>
<property>
<name>yarn.nodemanager.vmem-pmem-ratio</name>
<value>6</value>
</property>
<!-- mapreduce_shuffle -->
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
</configuration>
其中属性【yarn.nodemanager.resource.memory-mb
】和 【yarn.scheduler.minimum-allocation-mb
】配置过低,不足以在程序提交到ReourceManager后,启动MR App Master和让NodeManager启动MapReduce程序。
三、解决办法
经过重新修改yarn-site.xml配置,并经过测试,结果是可以正常启动mapreduce程序了,具体配置如下:
<configuration>
<property>
<name>yarn.resourcemanager.hostname</name>
<value>hadoop001</value>
</property>
<property>
<name>yarn.nodemanager.hostname</name>
<value>hadoop001</value>
</property>
<property>
<name>yarn.resourcemanager.address</name>
<value>hadoop001:8032</value>
</property>
<!-- 当前节点nodemanager进程分配内存大小。由于虚拟机内存有限,需要设置NodeManager内存为2G或者更小些,但不要小于1G -->
<property>
<name>yarn.nodemanager.resource.memory-mb</name>
<value>8192</value>
</property>
<!-- 由于Hadoop默认该配置为1024M,由于虚拟机内存有限,故设置最小分配内存为256M -->
<property>
<name>yarn.scheduler.minimum-allocation-mb</name>
<value>1024</value>
</property>
<property>
<name>yarn.scheduler.maximum-allocation-mb</name>
<value>8192</value>
<discription>单个任务可申请最大内存,默认8192MB</discription>
</property>
<!--该属性为容器设置内存限制时,虚拟内存与物理内存之间的比率。
容器分配以物理内存表示,允许虚拟内存使用以这个比例超过这个分配。
Ratio between virtual memory to physical memory when setting memory limits for containers. Container allocations are expressed in terms of physical memory, and virtual memory usage is allowed to exceed this allocation by this ratio.
默认是2.1 -->
<property>
<name>yarn.nodemanager.vmem-pmem-ratio</name>
<value>6</value>
</property>
<property>
<name>yarn.nodemanager.resource.cpu-vcores</name>
<value>4</value>
</property>
<!-- mapreduce_shuffle -->
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
</configuration>