zoukankan      html  css  js  c++  java
  • Hadoop异常解决:Yarn Failed to launch container

    问题

    在服务器上起了HDFS+Yarn,然后提交了一个作业:

    hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.1.jar pi 1 2
    

    但是运行的时候报错,Console的log如下:

    2020-11-03 14:31:44,840 WARN org.apache.hadoop.yarn.server.nodemanager.containermanager.launcher.ContainerLaunch: 
    Failed to launch container.
    
    java.io.FileNotFoundException: 
    
    File /home/hadoop/app/tmp/nm-local-dir/usercache/root/appcache/application_1604385076312_0001/container_1604385076312_0001_02_000001 
    does not exist
    	at org.apache.hadoop.fs.RawLocalFileSystem.deprecatedGetFileStatus(RawLocalFileSystem.java:606)
    	at org.apache.hadoop.fs.RawLocalFileSystem.getFileLinkStatusInternal(RawLocalFileSystem.java:819)
    	at org.apache.hadoop.fs.RawLocalFileSystem.getFileStatus(RawLocalFileSystem.java:596)
    	at org.apache.hadoop.fs.FileSystem.primitiveMkdir(FileSystem.java:1052)
    	at org.apache.hadoop.fs.DelegateToFileSystem.mkdir(DelegateToFileSystem.java:161)
    	at org.apache.hadoop.fs.FilterFs.mkdir(FilterFs.java:197)
    	at org.apache.hadoop.fs.FileContext$4.next(FileContext.java:730)
    	at org.apache.hadoop.fs.FileContext$4.next(FileContext.java:726)
    	at org.apache.hadoop.fs.FSLinkResolver.resolve(FSLinkResolver.java:90)
    	at org.apache.hadoop.fs.FileContext.mkdir(FileContext.java:726)
    	at org.apache.hadoop.yarn.server.nodemanager.DefaultContainerExecutor.createDir(DefaultContainerExecutor.java:562)
    	at org.apache.hadoop.yarn.server.nodemanager.DefaultContainerExecutor.launchContainer(DefaultContainerExecutor.java:161)
    	at org.apache.hadoop.yarn.server.nodemanager.containermanager.launcher.ContainerLaunch.call(ContainerLaunch.java:302)
    	at org.apache.hadoop.yarn.server.nodemanager.containermanager.launcher.ContainerLaunch.call(ContainerLaunch.java:82)
    	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    	at java.lang.Thread.run(Thread.java:748)
    

    查看NodeManager的log,也是类似的信息:

    WARN org.apache.hadoop.yarn.server.nodemanager.containermanager.launcher.ContainerLaunch: Failed to launch container.
    

    简单分析可知:(参考Yarn的作业流程图,)程序在比较早期就挂了,即 RM 在 NM 上启动 Container,但是起不来。

    分析1

    看了一会log,发现有的地方写到关于Container内存大小的,动辄就是1G多。(好像,默认分配给Container的内存大小是1024MB)

    我的服务器的配置是: 1 core + 2GB memory。算上已经运行的程序,剩下的也就600MB的内存。

    所以,我的第一个思路是:会不会Container因为内存不足起不来?

    捣鼓了一阵,把内存使用改小了。

    yarn-site.xml

    <property>
          <name>yarn.nodemanager.resource.memory-mb</name>
          <value>512</value>
    </property>
    	
    <property>
          <name>yarn.scheduler.minimum-allocation-mb</name>
          <value>256</value>
    </property>
    	
    <property>
          <name>yarn.scheduler.maximum-allocation-mb</name>
          <value>256</value>
    </property>
    	
    <property>
          <name>yarn.app.mapreduce.am.resource.mb</name>
          <value>128</value>
    </property>
    

    mapr-site.xml

    <property>
          <name>mapreduce.map.memory.mb</name>
          <value>128</value>
    </property>
    	
    <property>
          <name>mapreduce.reduce.memory.mb</name>
          <value>128</value>
    </property>
    	
    <property>
          <name>mapreduce.map.java.opts</name>
          <value>-Xmx128m</value>
    </property>
    	
    <property>
          <name>mapreduce.reduce.java.opts</name>
          <value>-Xmx128m</value>
    </property>
    

    重启再试一遍,还是不行。看来不是因为这个原因。改回来。

    (后来看log可以知道:Container的内存管理分为实际物理内存占用和虚拟内存占用。运行这个exmaple程序,物理内存可能只有十几MB,虚拟内存占用可达几个GB)

    分析2

    还是回到log中来。

    DefaultContainerExecutor想要launchContainer,但是 somehow 有个文件路径不存在,所以需要createDir

    但是为什么创建文件夹的操作最终会报文件不存在的Error呢?继续分析。

    一路调用Hadoop自带的工具类创建文件夹,最终,到了FileSystem.primitiveMkdir中,会做一个判断,parent dir存不存在,源码如下:

    protected void primitiveMkdir(Path f, FsPermission absolutePermission, 
    				boolean createParent)
    throws IOException {
    
    if (!createParent) { // parent must exist.
      // since the this.mkdirs makes parent dirs automatically
      // we must throw exception if parent does not exist.
      final FileStatus stat = getFileStatus(f.getParent());
      if (stat == null) {
    	throw new FileNotFoundException("Missing parent:" + f);
      }
      if (!stat.isDirectory()) {
    	throw new ParentNotDirectoryException("parent is not a dir");
      }
      // parent does exist - go ahead with mkdir of leaf
    }
    // Default impl is to assume that permissions do not matter and hence
    // calling the regular mkdirs is good enough.
    // FSs that implement permissions should override this.
    if (!this.mkdirs(f, absolutePermission)) {
      throw new IOException("mkdir of "+ f + " failed");
    }
    }
    

    也就是在这个时候,getFileStatus(f.getParent());这里报错了。

    报错的路径是这个:

    /home/hadoop/app/tmp/nm-local-dir/usercache/root/appcache/application_1604385076312_0001/container_1604385076312_0001_02_000001
    

    在系统搜了一下确实没有。除此之外,我们还知道,这个是一个parent dir,里面还有东西的。

    这个container_1604385076312_0001_02_000001到底在哪里呢?

    搜了一圈,发现在这个路径下:

    /home/hadoop/app/tmp/nm-local-dir/nmPrivate/application_1604385076312_0001/container_1604385076312_0001_02_000001
    

    注意:一个是nm-local-dir/usercache,一个是nm-local-dir/nmPrivate

    并且,在container_1604385076312_0001_02_000001路径下,我们可以发现两个文件:

    container_1604385076312_0001_02_000001.tokens
    launch_container.sh
    

    所以,我们大概能猜想到背后发生的事:Yarn想要调用launch_container.sh这个文件启动一个Contianer。但是somehow由于路径不对,没有找到这个文件。

    关于这个default路径,我看了DefaultContainerExecutor.launchContainer的源码,猜想是使用的DEFAULT_CONTAINER_TEMP_DIR

     Path tmpDir = new Path(containerWorkDir,
       YarnConfiguration.DEFAULT_CONTAINER_TEMP_DIR);
     createDir(tmpDir, dirPerm, false, user);
    

    具体是怎么找的我就没有深究了,反正这里把它换了试一下先。

    修改

    这里,我所作的修改是:换一个路径,手动指定 Yarn 的local dir。

    yarn-site.xml

    <property>
          <name>yarn.nodemanager.local-dirs</name>
          <value>/home/hadoop/yarn/nm/localdir</value>
    </property>
    

    重启再试,成功!

    观察 NM 的log,能看到如下语句,显示地指定了运行bash命令的路径。

    INFO org.apache.hadoop.yarn.server.nodemanager.DefaultContainerExecutor: 
    launchContainer: 
    [bash, /home/hadoop/yarn/nm/localdir/usercache/root/appcache/application_1604388443689_0001/container_1604388443689_0001_01_000005/default_container_executor.sh]
    

    参考

  • 相关阅读:
    [刘阳Java]_MyBatis_其他方式来实现多表查询的操作_第9讲
    [刘阳Java]_MyBatis_实体关系映射_第8讲
    [刘阳Java]_MyBatis_动态SQL标签用法_第7讲
    [刘阳Java]_MyBatis_常规标签的用法_第6讲
    nodejs配置nginx 以后链接mongodb数据库
    es6学习
    学生管理系统
    node exprss-session 和connect-mongo
    容错处理try
    node错误中间件处理 express类 带有路由操作
  • 原文地址:https://www.cnblogs.com/maxstack/p/13921239.html
Copyright © 2011-2022 走看看