zoukankan      html  css  js  c++  java
  • /bin/bash: line 0: fg: no job control一般解决方法

    測试版本号:CDH5.0,(Hadoop2.3)

    在使用windows调用Hadoop yarn平台的时候,一般都会遇到例如以下的错误:

    2014-05-28 17:32:19,761 WARN org.apache.hadoop.yarn.server.nodemanager.DefaultContainerExecutor: Exception from container-launch with container ID: container_1401177251807_0034_01_000001 and exit code: 1
    org.apache.hadoop.util.Shell$ExitCodeException: /bin/bash: line 0: fg: no job control
    
    	at org.apache.hadoop.util.Shell.runCommand(Shell.java:505)
    	at org.apache.hadoop.util.Shell.run(Shell.java:418)
    	at org.apache.hadoop.util.Shell$ShellCommandExecutor.execute(Shell.java:650)
    	at org.apache.hadoop.yarn.server.nodemanager.DefaultContainerExecutor.launchContainer(DefaultContainerExecutor.java:195)
    	at org.apache.hadoop.yarn.server.nodemanager.containermanager.launcher.ContainerLaunch.call(ContainerLaunch.java:300)
    	at org.apache.hadoop.yarn.server.nodemanager.containermanager.launcher.ContainerLaunch.call(ContainerLaunch.java:81)
    	at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    	at java.lang.Thread.run(Thread.java:744)
    这个错误在Hadoop mapreduce bug的信息页面(https://issues.apache.org/jira/browse/MAPREDUCE-5655)已经攻克了,且影响的版本号是Hadoop2.2、Hadoop2.3,并且已经解决(并没有说在Hadoop2.4已经修复了)。

    在http://blog.csdn.net/fansy1990/article/details/22896249 博客中,lz依照 https://issues.apache.org/jira/browse/MAPREDUCE-5655的解决方式进行了解决。这里想给出这个问题的一般解决思路。

    1. 首先这个问题是在windows的eclipse作为client提交任务到linux Hadoop集群才会出现的问题,假设是linux的eclipse提交任务到linux Hadoop集群则不会出现这种问题。那么一个非常直观的想法就是同一时候使用两个client执行一个任务,然后每一个步骤都调试,来确定当中的不同点。这么做,肯定是能够的。可是这么做肯定也是比較费时的(并且还要自己在一个linux上装个eclipse,麻烦);

    2. 依照1的做法,一般就能够看到有两点的不同,一个是java命令的不同,另一个就是classpath的不同。先说下断点的地方:

    (1)java命令的断点:

    YarnRunner.java的390行(cdh5.0 Hadoop2.3版本号源代码)

    // Setup the command to run the AM
        List<String> vargs = new ArrayList<String>(8);
        vargs.add(Environment.JAVA_HOME.$() + "/bin/java");
    这里打上断点后,然后执行到445这一行,就能够看到vargs是例如以下的样子(或者看vargsFinal这个变量):

    [%JAVA_HOME%, -Dlog4j.configuration=container-log4j.properties, -Dyarn.app.container.log.dir=<LOG_DIR>, -Dyarn.app.container.log.filesize=0, -Dhadoop.root.logger=INFO,CLA, , -Xmx1024m, org.apache.hadoop.mapreduce.v2.app.MRAppMaster, 1><LOG_DIR>/stdout, 2><LOG_DIR>/stderr, null, null]
    (2)classpath的断点:

    YarnRunner.java的466行,查看environment的值,能够看到起值为:

    {CLASSPATH=%PWD%;$HADOOP_CONF_DIR;$HADOOP_COMMON_HOME/*;$HADOOP_COMMON_HOME/lib/*;$HADOOP_HDFS_HOME/*;$HADOOP_HDFS_HOME/lib/*;$HADOOP_MAPRED_HOME/*;$HADOOP_MAPRED_HOME/lib/*;$HADOOP_YARN_HOME/*;$HADOOP_YARN_HOME/lib/*;%HADOOP_MAPRED_HOME%sharehadoopmapreduce*;%HADOOP_MAPRED_HOME%sharehadoopmapreducelib*;job.jar/job.jar;job.jar/classes/;job.jar/lib/*;%PWD%/*}
    3. 看到2中的两个值就能够确定,windows和linux的不同之处了,主要有两个:

    (1)%%和$的差别;

    (2)正反斜杠的差别(这个好像不差别也行);
    4. 看出上面两个地方的差别后,假设直接把这两个值改为:

    [$JAVA_HOME/bin/java -Dlog4j.configuration=container-log4j.properties -Dyarn.app.container.log.dir=<LOG_DIR> -Dyarn.app.container.log.filesize=0 -Dhadoop.root.logger=INFO,CLA  -Xmx1024m org.apache.hadoop.mapreduce.v2.app.MRAppMaster 1><LOG_DIR>/stdout 2><LOG_DIR>/stderr ]

    {CLASSPATH=$PWD:$HADOOP_CONF_DIR:$HADOOP_COMMON_HOME/*:$HADOOP_COMMON_HOME/lib/*:$HADOOP_HDFS_HOME/*:$HADOOP_HDFS_HOME/lib/*:$HADOOP_MAPRED_HOME/*:$HADOOP_MAPRED_HOME/lib/*:$HADOOP_YARN_HOME/*:$HADOOP_YARN_HOME/lib/*:$HADOOP_MAPRED_HOME/share/hadoop/mapreduce/*:$HADOOP_MAPRED_HOME/share/hadoop/mapreduce/lib/*:job.jar/job.jar:job.jar/classes/:job.jar/lib/*:$PWD/*}
    那么应该是能够执行的;

    5. 怎么改呢?

    (1)在我们的project中新建一个YarnRunner类,该类与源代码的YarnRunner类一模一样(包路径,代码内容都一样);

    (2)把390行替换为(这里默认Hadoop 集群是在linux环境下的):

    即把

     vargs.add(Environment.JAVA_HOME.$() + "/bin/java");

    替换为

    vargs.add("$JAVA_HOME/bin/java");
    (3)在466行加入�:

    replaceEnvironment(environment);
    这种方法放在最后面,为:

    private void replaceEnvironment(Map<String, String> environment) {
    	  String tmpClassPath = environment.get("CLASSPATH");
    	  tmpClassPath=tmpClassPath.replaceAll(";", ":");
    	  tmpClassPath=tmpClassPath.replaceAll("%PWD%", "\$PWD");
    	  tmpClassPath=tmpClassPath.replaceAll("%HADOOP_MAPRED_HOME%", "\$HADOOP_MAPRED_HOME");
    	  tmpClassPath= tmpClassPath.replaceAll("\\", "/" );
    	  environment.put("CLASSPATH",tmpClassPath);
    }
    这样替换完毕后,在windows的eclipse中向linux Hadoop集群中提交任务就能够执行了。


    最后,在执行的时候,eclipse终端没有日志打印出来;直接在src以下加上一个log4j.properties文件(能够在linux 集群的/etc/hadoop/conf/里面下载)。


    分享,成长,快乐

    转载请注明blog地址:http://blog.csdn.net/fansy1990


  • 相关阅读:
    linux 系统层/用户层资源使用信息监控
    人工神经网络学习
    刷题
    使用机器学习进行气象数据分析
    kaggle 从零开始记录遇到的问题
    大数据平台资料收集
    MacOS应用cocoa application问题
    Latex学习手记(持续更新)
    Matplotlib折线图
    Android的系统架构——安卓运行库
  • 原文地址:https://www.cnblogs.com/blfshiye/p/3789872.html
Copyright © 2011-2022 走看看