Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/387.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何从eclipse调试hadoop mapreduce作业?_Java_Eclipse_Debugging_Hadoop_Remote Debugging - Fatal编程技术网

Java 如何从eclipse调试hadoop mapreduce作业?

Java 如何从eclipse调试hadoop mapreduce作业?,java,eclipse,debugging,hadoop,remote-debugging,Java,Eclipse,Debugging,Hadoop,Remote Debugging,我在一台机器上运行hadoop,只在本地安装,我正在寻找一种在eclipse中调试映射器和还原器的好方法。Eclipse在运行mapreduce任务时没有问题。但是,当我转到调试时,它会给我以下错误: 12/03/28 14:03:23 WARN mapred.JobClient:未设置作业jar文件。可能找不到用户类。请参阅JobConf(类)或JobConf#setJar(字符串) 好的,我做了一些调查。显然,我应该使用eclipse的远程调试工具,并将其添加到我的hadoop env.sh

我在一台机器上运行hadoop,只在本地安装,我正在寻找一种在eclipse中调试映射器和还原器的好方法。Eclipse在运行mapreduce任务时没有问题。但是,当我转到调试时,它会给我以下错误:

12/03/28 14:03:23 WARN mapred.JobClient:未设置作业jar文件。可能找不到用户类。请参阅JobConf(类)或JobConf#setJar(字符串)

好的,我做了一些调查。显然,我应该使用eclipse的远程调试工具,并将其添加到我的
hadoop env.sh

-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5000
我这样做,就可以在eclipse中逐步完成我的代码。唯一的问题是,由于“suspend=y”,我无法使用命令行中的“hadoop”命令查看作业队列;我想它挂起是因为它在等待调试器连接。此外,在这种模式下,我无法运行“hbase shell”,原因可能与此相同

因此,基本上,如果我想在“调试模式”和“正常模式”之间来回切换,我需要更新hadoop env.sh并重新启动我的机器。严重疼痛。所以我有几个问题:

  • 在eclipse中调试mapreduce作业有更简单的方法吗

  • 为什么eclipse可以很好地运行我的mapreduce作业,但对于调试,我需要使用远程调试

  • 有没有办法告诉hadoop对mapreduce作业使用远程调试,但对所有其他任务使用正常模式?(例如“hadoop队列”或“hbase外壳”)

  • 有没有更简单的方法可以在不重新启动我的机器的情况下切换hadoop env.sh配置?默认情况下,hadoop-env.sh不可执行

  • 这是一个更一般的问题:当我在仅本地模式下运行hadoop时,到底发生了什么?我的机器上是否有“始终打开”并执行hadoop作业的进程?或者hadoop只是在我从命令行运行“hadoop”命令时才运行?当我从eclipse运行mapreduce作业时,eclipse在做什么?我必须在我的
    pom.xml
    中引用
    hadoop核心
    ,以使我的项目能够工作。eclipse是向我安装的hadoop实例提交作业,还是从maven缓存中的
    hadoop-core-1.0.0.jar
    运行所有作业

  • 这是我的主要课程:

    public class Main {
          public static void main(String[] args) throws Exception {     
            Job job = new Job();
            job.setJarByClass(Main.class);
            job.setJobName("FirstStage");
    
            FileInputFormat.addInputPath(job, new Path("/home/sangfroid/project/in"));
            FileOutputFormat.setOutputPath(job, new Path("/home/sangfroid/project/out"));
    
            job.setMapperClass(FirstStageMapper.class);
            job.setReducerClass(FirstStageReducer.class);
    
            job.setOutputKeyClass(Text.class);
            job.setOutputValueClass(Text.class);
    
            System.exit(job.waitForCompletion(true) ? 0 : 1);
          }
    }
    

    除了推荐的MRUnit之外,我还喜欢使用eclipse进行调试。我有一个主程序。它实例化配置并直接执行MapReduce作业。我只是用标准的eclipse调试配置进行调试。因为我在mvn规范中包含了hadoop JAR,所以我的类路径中包含了所有hadoop本身,我不需要对我安装的hadoop运行它。我总是使用本地目录中的小数据集进行测试,以使事情变得简单。配置的默认行为类似于独立的hadoop(文件系统可用)

    在eclipse中调试hadoop的唯一方法是在本地模式下运行hadoop。原因是,每个MapReduce任务都在自己的JVM中运行,当您不在本地模式下运行hadoop时,eclipse将无法进行调试

    将hadoop设置为本地模式时,hadoop文件系统将更改为
    file://
    ,而不是使用hdfs API(默认设置)。因此,运行
    hadoop fs-ls
    将不是一个hdfs命令,而是更多的
    hadoop fs-ls文件://
    ,一个指向本地目录的路径。JobTracker或NameNode均未运行

    这些博客帖子可能会有帮助:


    我也喜欢通过带有MRUnit的单元测试进行调试。我将把它与approvaltests结合使用,approvaltests可以创建Map Reduce过程的简单可视化,并且可以轻松地通过失败的场景。它还可以从eclipse无缝运行

    例如:

    HadoopApprovals.verifyMapReduce(new WordCountMapper(), 
                             new WordCountReducer(), 0, "cat cat dog");
    
    将产生以下输出:

    [cat cat dog] 
    -> maps via WordCountMapper to ->
    (cat, 1) 
    (cat, 1) 
    (dog, 1)
    
    -> reduces via WordCountReducer to ->
    (cat, 2) 
    (dog, 1)
    

    这里有一个关于这个过程的视频:

    /bin/hadoop
    hadoop env.sh
    )脚本中进行更改。检查以查看已触发的命令。如果命令为
    jar
    ,则仅添加远程调试配置

    if [ "$COMMAND" = "jar" ] ; then
      exec "$JAVA" -Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=8999 $JAVA_HEAP_MAX $HADOOP_OPTS $CLASS "$@"
    else
      exec "$JAVA" $JAVA_HEAP_MAX $HADOOP_OPTS $CLASS "$@"
    fi
    

    可以通过hadoop_OPTS env变量向hadoop的内部java命令添加参数:

    export HADOOP_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=5005,suspend=y"
    

    您可以通过-Dmapreduce.map.java.opts传递调试参数。 例如,您可以在调试模式下运行HBase导入和映射程序:

    yarn jar your/path/to/hbase-mapreduce-2.2.5.jar import
         -Dmapreduce.map.speculative=false 
         -Dmapreduce.reduce.speculative=false 
         -Dmapreduce.map.java.opts="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=5005,suspend=y" 
         my_table /path/in/hdfs
    
    请注意,必须将其放置在一行中,不带新行。 其他map reduce应用程序也可以以同样的方式启动,诀窍是通过-Dmapreduce.map.java.opts传递调试派生

    在Eclipse或IntelliJ中,您必须创建一个调试远程连接

    Host=127.0.0.1 (or even a remote IP address in case Hadoop runs elsewhere)
    Port=5005
    
    我设法用这种方式调试导入。此外,您可以将映射器的数量限制为1(如上所述),但这对我来说不是必需的

    启动map reduve应用程序后,切换到IDE,尝试启动调试设置,但一开始就会失败。重复该操作,直到调试器钩住应用程序。不要忘记在手之前设置断点

    如果您不想只调试应用程序,也不想调试周围的HBase/Hadoop框架,您可以下载它们
    和(通过“切换分支/标记”菜单按钮选择您的版本)。

    另外,如果您只是尝试调试映射器/还原器逻辑,您应该考虑使用MRUnit(),因为@Chris White建议从MRUnit开始测试映射/还原逻辑是一个好主意:谢谢您的回答。一、 同样,在我的POM中将hadoop核心设置为依赖项。既然如此,为什么会出现“无作业jar文件集”错误?是因为我在调用job.setJarByClass()吗?您可以发布一些示例代码吗?我并没有完全尝试这一点,但我用jdb替换了$JAVA(我试图使用jdb进行调试)。jdb从未识别出我试图放置在希望程序停止位置的断点。我假设问题是我没有在本地模式下运行。我还没试过,但我想是Kapil D的建议