Hadoop下远程调试Child子进程

2019-03-28 14:05|来源: 网络

在网上想找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的安装和启动过程我在这里就不详述了,可以参考官方文档

2、hadoop的eclipse插件的安装和使用过程我这里也不详述了,可以参考:http://www.linuxidc.com/Linux/2012-01/52553.htm

一、tasktracker的debug模式配置和Chlid子进程的debug模式配置

1.1、先对tasktracker进行debug,在hadoop.sh中找到 elif [ "$COMMAND" = "tasktracker" ] ,并添加tasktracker的调试端口如下:

  1. elif [ "$COMMAND" = "tasktracker" ] ; then   
  2.   CLASS=org.apache.hadoop.mapred.TaskTracker   
  3.   HADOOP_OPTS="$HADOOP_OPTS $HADOOP_TASKTRACKER_OPTS   
  4.     -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例子来进行讲解。

Run on Hadoop后出来的结果如下,让你选择你自己的配置信息,这里要保证1.2节中配置的项处在第一个选择,这样当你要debug代码的时候,可以选择你配置过的那个,默认是第一个配置项。

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阶段了。

以上是自己在学习过程中的调试经验,希望对大家有帮助,语言比较粗糙,有些地方难免有遗漏,还望多多指正。

相关问答

更多
  • 尝试 signal(SIGINT, SIG_IGN); 在A.根据man signal (强调我的), 通过fork(2)创建的子项继承其父级信号处置的副本。 在execve(2)期间,处理信号的处置被重置为默认值; 忽略信号的配置保持不变 。 Try signal(SIGINT, SIG_IGN); in A. According to man signal (emphasis mine), A child created via fork(2) inherits a copy of ...
  • 好的,对于用例,我实际上找到了调试分叉进程的一种非常好的方法。 我会把它写下来以供将来参考有类似需求的人: 我从主进程中分离了子进程的开发。 两者都只通过process.on('message', handler)和child.send(...) 。 所以基本上我在子进程中调用我的process.on调用条件是否我设置process.env.NODE_ENV==='DEBUG' 。 然后我为子进程做了一个启动配置,就像这样 { "type": "node2", "request": "lau ...
  • 如果你的意思是任何代码,那可能很困难。 您可以使用CLONE_STOPPED而不是fork来使用clone来启动应用程序进入停止状态(需要SIGCONT才能再次运行)。 但是,如果你只是想要孩子中的特定代码并且你可以修改子代码,你可以,作为main的第一件事,只需为USR1信号设置一个处理程序(任何IPC可能会做,但信号似乎是最简单的在这种特殊情况下)然后在继续之前等待它开火。 这样,进程本身就会运行,但还没有做任何事情。 然后让父母编织它需要做的任何魔法,然后将SIGUSR1发送给孩子。 但是,根据评论, ...
  • 你应该传递signal.SIGKILL (9), signal.SIGTERM (15)之类的signal.SIGKILL来杀死进程。 import signal ... os.kill(logProc, signal.SIGKILL) 根据Linux kill(2) : 如果sig为0 , 则不发送信号 ,但仍然执行错误检查; 这可用于检查是否存在进程ID或进程组ID。 You should pass signals like signal.SIGKILL (9), signal.SIGTERM ( ...
  • 您可以轻松地向launch.json添加新的启动配置,允许您使用特定端口连接到正在运行的节点实例: { "name": "Attach to Node", "type": "node", "address": "localhost", "port": 5870, } 只需确保使用--debug或--debug-brk参数派生/生成节点进程。 You can easily add a new launch configuration to la ...
  • 您应该在信号处理程序内部的循环中使用带有WNOHANG的waitpid() 。 可能发生的是,并非所有信号都被传递 - 因为它们中的一些信号彼此靠得太近。 你也许可以通过使用sigaction()而不是signal()来缓解这个问题。 You should probably use waitpid() with WNOHANG in a loop inside the signal handler. What probably happens is that not all the signals are ...
  • 从Windows API的角度来看,没有暂停进程的事情。 只能挂起线程 ,但线程之间没有父子关系。 由于没有“子线程”,因此在父项被挂起时没有自动挂起它们的机制。 (您可以创建一个暂停的进程,但那是因为当它首次创建时,只有一个线程,并且它被创建为暂停。) 如果要挂起子进程的所有线程,则枚举它们并以挂起父进程的线程的方式挂起它们。 您也可以尝试使用未记录的NtSuspendProcess函数,如Windows中所述:以原子方式暂停整个过程? From the Windows API perspective, ...
  • 读我的问题,我找到了答案 - 让初始断点设置真正的断点: .childdbg 1 sxe -c "bm b!*MyMethod*;g" ibp sxd epr Reading my question, I found the answer - let the initial breakpoint set the real breakpoint: .childdbg 1 sxe -c "bm b!*MyMethod*;g" ibp sxd epr
  • 看起来像一个bug; 以WEB-12528登录,请投票 Looks like a bug; logged as WEB-12528, please vote for it
  • 在孩子退出后调用wait (通过调用exit或获取致命信号)时,父级将获得退出状态。 exec无关紧要。 The parent will get the exit status when it calls wait after the child has exited (either by calling exit or getting a fatal signal). exec is irrelevant.