上一节我们已经成功编译了hadoop源码,这样我们就可以根据需要在源代码里增加调试信息,跟踪hadoop的执行。这种方式需要对跟踪的对应模块代码进行修改,还要重新编译jar包,并替换share/hadoop目录下对应的jar包,然后重新启动要调试的hadoop服务才行,比较麻烦。所以我学习了一下如何用eclipse远程调试,这样就可以设置断点,十分方便。
1.关于JAVA远程调试的原理和设置,下面这篇文章讲解十分详细,可以先了解下:
http://www.ibm.com/developerworks/cn/opensource/os-eclipse-javadebug/
2.hadoop2.6.0版本主要是
sbin/start-dfs.sh
sbin/start-yarn.sh这两个脚本。
简单了解一下这两个脚本的工作,下面以start-dfs.sh为例:
下面只列出关键代码:
DEFAULT_LIBEXEC_DIR="$bin"/../libexec
HADOOP_LIBEXEC_DIR=${HADOOP_LIBEXEC_DIR:-$DEFAULT_LIBEXEC_DIR}
. $HADOOP_LIBEXEC_DIR/hdfs-config.sh //执行libexec/hdfs-config.sh脚本设置CLASSPATH,JAVA_OPTS等变量
#---------------------------------------------------------
# namenodes
NAMENODES=$($HADOOP_PREFIX/bin/hdfs getconf -namenodes) //获取hdfs namenodes相关配置
echo "Starting namenodes on [$NAMENODES]"
"$HADOOP_PREFIX/sbin/hadoop-daemons.sh" \
--config "$HADOOP_CONF_DIR" \
--hostnames "$NAMENODES" \
--script "$bin/hdfs" start namenode $nameStartOpt //启动namenode
#---------------------------------------------------------
# datanodes (using default slaves file)
if [ -n "$HADOOP_SECURE_DN_USER" ]; then
echo \
"Attempting to start secure cluster, skipping datanodes. " \
"Run start-secure-dns.sh as root to complete startup."
else
"$HADOOP_PREFIX/sbin/hadoop-daemons.sh" \
--config "$HADOOP_CONF_DIR" \
--script "$bin/hdfs" start datanode $dataStartOpt //启动datanode
fi
# eof
主要列出了其中的4个部分,我们现在以/bin/hdfs getconf -namenodes这部分代码为例,进行调试跟踪,这部分代码主要是从hdfs-site.xml配置文件里读取我们的配置。
3.再简单了解一下bin/hdfs代码,可以看到这个代码是根据不同的COMMAND参数执行不同的JAR包完成不同的工作。我们现在执行的COMMAND=getconf,所以只关注这部分的代码:
elif [ "$COMMAND" = "getconf" ] ; then
CLASS=org.apache.hadoop.hdfs.tools.GetConf
HADOOP_OPTS="$HADOOP_OPTS -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8103"
红色的部分为为了调试所加的内容,suspend=y表示等待调试器(这里是eclipse)连接,这样我们才能在启动时跟踪代码.其它部分的含义,可以参考:
http://www.ibm.com/developerworks/cn/opensource/os-eclipse-javadebug/
这样我们就可以执行sbin/start-dfs.sh脚本,脚本会在执行到NAMENODES=$($HADOOP_PREFIX/bin/hdfs getconf -namenodes) 这里是停止,等待eclipse调试器连接后继续调试方式运行,所以下面需要启动eclipse调试器连接上来。
4.eclipse端设置
Run->Debug Configurations->Remote Java Application里新建一项远程调试项:
Name:随便命名,因为跟踪的是hdfs-tools-getconf所以命名这个,便于区分
Project:选择跟踪的模块即可
Host,Port为我们在bin/hdfs里启动的调试地址和端口。
配置完成后,我们来设置一个断点:
这里我们跟踪GetConf.java里的
HdfsConfiguration.init();
设置好断点后,我们执行Debug,然后断点就断住了,然后我们就可以跟踪调试了。
如果想要调试其它命令或模块,原理相同,只要修改脚本对要调试跟踪的Jar包设置HADOOP_OPTS即可。
HADOOP_OPTS="$HADOOP_OPTS -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8103"