Java 如何从eclipse调试hadoop mapreduce作业?
我在一台机器上运行hadoop,只在本地安装,我正在寻找一种在eclipse中调试映射器和还原器的好方法。Eclipse在运行mapreduce任务时没有问题。但是,当我转到调试时,它会给我以下错误: 12/03/28 14:03:23 WARN mapred.JobClient:未设置作业jar文件。可能找不到用户类。请参阅JobConf(类)或JobConf#setJar(字符串) 好的,我做了一些调查。显然,我应该使用eclipse的远程调试工具,并将其添加到我的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 env.sh
:
-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5000
我这样做,就可以在eclipse中逐步完成我的代码。唯一的问题是,由于“suspend=y”,我无法使用命令行中的“hadoop”命令查看作业队列;我想它挂起是因为它在等待调试器连接。此外,在这种模式下,我无法运行“hbase shell”,原因可能与此相同
因此,基本上,如果我想在“调试模式”和“正常模式”之间来回切换,我需要更新hadoop env.sh并重新启动我的机器。严重疼痛。所以我有几个问题:
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均未运行
这些博客帖子可能会有帮助:
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的建议