在网上想找Hadoop远程调试Child子进程的文章,但是都没有见到具体步骤是如何操作的,对于初学者来说,要想真正理解MapReduce的shuffle的过程,对Child子进程的调试是必不可少的一项任务,至少对我来说是这样。费了九牛二虎之力,最后终于调试成功,在这里写下经验,分享给后面的hadoop学习爱好者。
我的环境:hadoop-0.20.2
ubuntu 11.04
在eclipse下安装了hadoop插件进行调试
这里要说一下,我的eclipse版本是很老的eclipse3.3.1,hadoop插件版本是hadoop-0.20.2中自带的插件,路径:/hadoop-0.20.2/contrib/eclipse-plugin/hadoop-0.20.2-eclipse-plugin.jar,直接这个插件拷贝到eclipse的plugin目录后重启eclipse就可。之所以使用eclipse3.3.1版本的eclipse是因为,hadoop-0.20.2的eclipse插件对eclipse版本要求较高,需要版本匹配才能运行,我试过在eclipse helio中安装这个插件,但是不能使用,其他版本的eclipse我暂时还没试过,不好意思。
前言
1、hadoop的安装和启动过程我在这里就不详述了,可以参考官方文档 http://hadoop.apache.org/common/docs/r0.19.2/cn/quickstart.html
2、hadoop的eclipse插件的安装和使用过程我这里也不详述了,可以参考网上的很多文章,比如:http://blog.sina.com.cn/s/blog_537770820100byho.html
一、tasktracker的debug模式配置和Chlid子进程的debug模式配置
1.1 先对tasktracker进行debug,在hadoop.sh中找到 elif [ "$COMMAND" = "tasktracker" ] ,并添加tasktracker的调试端口如下:
elif [ "$COMMAND" = "tasktracker" ] ; then
CLASS=org.apache.hadoop.mapred.TaskTracker
HADOOP_OPTS="$HADOOP_OPTS $HADOOP_TASKTRACKER_OPTS
-agentlib:jdwp=transport=dt_socket,address=8200,server=y,suspend=y"
1.2 看下图,在eclipse hadoop插件的参数配置中,修改mapred.child.java.opts的参数值为(红线部分):-Xmx 200m -agentlib:jdwp=transport=dt_socket,address=8883,server=y,suspend=y
红线部分表示Child子进程的启动端口为8883,这里的suspend=y是必须的,表示Child子进程启动后会等待远程的debug信息发送过来后再执行代码,因此在发送debug信息之前我们可以在eclipse中下断点,这一点很重要。
二、debug模式启动程序和断点
2.1 我使用的是最简单的WordCount例子来进行讲解,如下图
2.2 在JvmManager类的第249行和250行各下一个断点,如下图
spawnNewJvm表示重启一个Child子进程,这里是重点。在ubuntu控制台中执行如下命令:ps -aux | grep java,会发现有一个child子进程启动了,如下图
attempt_201201272353_0003_m_000005_0 -1032262400 这是进程号,在eclipse的debug窗口下,也可以看到这个进程
这时候,进程启动了,但是还没执行代码。在通过eclipse的远程调试链接到我们刚启动的Child子进程之前我们要先在Child.java的代码中下断点,如下:
在113行下个断点,下完断点后我们在我们在eclipse下远程调试,链接到这个进程,我们之前设定的端口是8883,如下图:
注意,按上面的步骤走的话务必在113行这里下断点,JvmTask myTask = umbilical.getTask(jvmId);这段代码是通过taskTracker获取对应的Map任务,但是别忘记我们之前在taskTracker上下了断点,taskTracker正处于debug模式,这时候执行这段代码,Child进程会被阻塞。按F6让debug往下走,Child进程阻塞在了taskTracker处,这时候我们回到eclipse的debug窗口,找到taskTracker进程并选中(如下图),按F5让taskTracker往下走,这时候Child子进程就会解除阻塞走过113行就OK了。
继续在MapTask的run(final JobConf job, final TaskUmbilicalProtocol umbilical)方法里面下断点,Child子进程就能调试到MapReduce的Shffle阶段了。
以上是自己在学习过程中的调试经验,希望对大家有帮助,语言和图解都比较粗糙,有些地方难免有遗漏,还望多多指正。