我在单机,仅限本地的设置中运行hadoop,而且我正在寻找一种在eclipse中调试映射器和减速器的漂亮,无痛的方法。 Eclipse 运行mapreduce任务没有问题。但是,当我去调试时,它给了我这个错误:
12/03/28 14:03:23 WARN mapred.JobClient:没有工作jar文件集。可能找不到用户类。请参阅JobConf(Class)或JobConf#setJar(String)。
好的,我做了一些研究。显然,我应该使用eclipse的远程调试工具,并将其添加到我的hadoop-env.sh
:
-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5000
我这样做,我可以在eclipse中逐步完成我的代码。唯一的问题是,由于" suspend = y",我无法使用" hadoop"从命令行执行命令来查看作业队列;它挂起,我想象,因为它正在等待调试器附加。另外,我无法运行" hbase shell"当我处于这种模式时,可能是出于同样的原因。
所以基本上,如果我想在"调试模式之间来回翻转"和#34;正常模式" ,我需要更新hadoop-env.sh
并重启我的机器。主要的痛苦。所以我有几个问题:
在eclipse中有更简单的方法来调试mapreduce作业吗?
为什么eclipse可以很好地运行我的mapreduce作业,但是对于调试我需要使用远程调试?
有没有办法告诉hadoop对mapreduce作业使用远程调试,但是在正常模式下运行所有其他任务? (例如" hadoop队列" 或" hbase shell" )。
有没有更简单的方法来切换hadoop-env.sh
配置而无需重启我的机器? hadoop-env.sh默认不可执行。
这是一个更普遍的问题:当我在仅限本地模式下运行hadoop时究竟发生了什么?我的机器上是否有任何进程始终在"并执行hadoop工作?或者hadoop只在我运行" hadoop"从命令行命令?当我从eclipse运行mapreduce工作时,eclipse正在做什么?我必须在我的hadoop-core
中引用pom.xml
才能使我的项目有效。 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);
}
}
答案 0 :(得分:7)
在/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
答案 1 :(得分:5)
在eclipse中调试hadoop的唯一方法是在本地模式下运行hadoop。原因是,每个map reduce任务在ist自己的JVM中运行,当你没有在本地模式下运行时,eclipse将无法调试。
当您将hadoop设置为本地模式时,而不是使用 hdfs API (默认情况下),hadoop文件系统将更改为file:///
。因此,运行hadoop fs -ls
将不是hdfs命令,而是更多hadoop fs -ls file:///
,即本地目录的路径。 JobTracker或NameNode都不会运行。
这些博文可能有所帮助:
答案 2 :(得分:2)
Jumbune的调试器将以最小的努力完成所有这些工作。
调试器提供MapReduce作业的代码级控制流统计信息。
用户可以应用正则表达式验证或其自己的用户定义验证类。根据应用的验证,Flow Debugger分别检查mapper和reducer的数据流。
它还提供了一个全面的表/图表视图,其中输入记录流在作业级别,MR级别和实例级别显示。 不匹配的键/值表示作业执行结果中错误的键/值数据的数量。调试器深入到代码中来检查各种计数器的数据流,如循环和条件if,else-if等。
Jumbune是开源的,可在www.jumbune.org和https://github.com/impetus-opensource/jumbune
获取答案 3 :(得分:1)
除了推荐的MRUnit,我也喜欢用eclipse进行调试。我有一个主程序。它实例化一个Configuration并直接执行MapReduce作业。我只是使用标准的eclipse Debug配置进行调试。因为我在我的mvn规范中包含了hadoop jar,所以我在我的类路径中都有hadoop本身,我没有必要在我安装的hadoop上运行它。我总是使用本地目录中的小数据集进行测试,以简化操作。配置的默认值表现为独立的hadoop(文件系统可用)
答案 4 :(得分:0)
我也喜欢通过MRUnit的单元测试进行调试。我将结合批准测试使用它,这可以轻松地显示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)
此处有一段视频:http://t.co/leExFVrf
答案 5 :(得分:0)
可以通过HADOOP_OPTS env变量将参数添加到hadoop的内部Java命令中:
export HADOOP_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=5005,suspend=y"
答案 6 :(得分:0)
您可以通过-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
我设法以这种方式调试导入。此外,您可以按照 here 所述将映射器的数量限制为 1,但这对我来说不是必需的。
一旦 map-reduve 应用程序启动,切换到您的 IDE 并尝试启动您的调试设置,这将在开始时失败。重复此操作,直到调试器挂接到应用程序中。不要忘记事先设置断点。
如果您不想只调试您的应用程序,也不想调试周围的 HBase/Hadoop 框架,您可以下载它们 here 和 here(通过“切换分支/标签”菜单按钮选择您的版本)。