对hadoop namenode -format执行过程的探究

 

引言java

本文出于一个疑问:hadoop namenode -format到底在个人linux系统里面作了些什么?node

步骤linux

1个文件bin/hadoopapache

Hadoop脚本位于hadoop根目录下的bin目录下,分布式

打开以后阅读源代码:函数


 

 

 

 

 

 

 

 

 

 

在这里$1即为参数namenode工具

COMMAND赋值为$1,那么COMMAND=namenodeoop

条件判断语句的执行流到达#hdfs下的一行:网站

由于这一行判断COMMAND是否等于namenode secondarynamenode等之一;spa

接着往下读:


 

 

 

 

 

判断"${HADOOP_HDFS_HOME}"/bin/hdfs存在,且为一个文件,那么就会执行

${HADOOP_HDFS_HOME}/bin/hdfs ${COMMAND/dfsgroups/groups} $@


在这里${HADOOP_HDFS_HOME}/bin/hdfs 就是根目录下的bin目录下的hdfs脚本,${COMMAND/dfsgroups/groups}就是namenode,而$@则是-format

2个文件bin/hdfs

注意文件中间:


 

 

设置了2个变量CLASS 以及HADOOP_OTS

和文件末尾:


 

 

经过使用echo指令,能够查看这些参数:


 

 

 

 

 

 

/usr/jdk1.8.0_51/bin/java

namenode

-Xmx1000m

-Djava.library.path=/usr/local/hadoop-2.6.0/lib -Djava.net.preferIPv4Stack=true -Dhadoop.log.dir=/usr/local/hadoop-2.6.0/logs -Dhadoop.log.file=hadoop.log -Dhadoop.home.dir=/usr/local/hadoop-2.6.0 -Dhadoop.id.str=hadoop -Dhadoop.root.logger=INFO,console -Dhadoop.policy.file=hadoop-policy.xml -Djava.net.preferIPv4Stack=true -Djava.net.preferIPv4Stack=true -Dhadoop.log.dir=/usr/local/hadoop-2.6.0/logs -Dhadoop.log.file=hadoop.log -Dhadoop.home.dir=/usr/local/hadoop-2.6.0 -Dhadoop.id.str=hadoop -Dhadoop.root.logger=INFO,console -Dhadoop.policy.file=hadoop-policy.xml -Djava.net.preferIPv4Stack=true -Dhadoop.security.logger=INFO,RFAS -Dhdfs.audit.logger=INFO,NullAppender -Dhadoop.security.logger=INFO,RFAS -Dhdfs.audit.logger=INFO,NullAppender -Dhadoop.security.logger=INFO,NullAppender

org.apache.hadoop.hdfs.server.namenode.NameNode

-format

这是一个完整的java指令,

其中-D<名称>=<> 设置系统属性,Xmx1000m设置JVM最大可用内存为1GB

这个不是重点,重点在后面:CLASS

org.apache.hadoop.hdfs.server.namenode.NameNode

也就是说java要经过一系列的选项和参数运行

org.apache.hadoop.hdfs.server.namenode.NameNode.class

接下来就是查看这个CLASS的源代码了

3个文件NameNode.java

这个文件位于

hadoop-2.6.0-src/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/

其中hadoop-2.6.0-srchadoop2.6.0的源码,能够直接在apache hadoop网站上下载,而后解压就能够了。

首先,找到main函数:

位于源码第1497行,


 

 

 

 

 

 

 

 

 

 

没错,就是这样一段短小精悍的代码!

作了什么呢?

第一部分,if条件语句暂时无视;

第二部分,try -catch模块,

StringUtils.startupShutdownMessage(NameNode.class, argv, LOG);

根据名字分析,这个是用来显示Message.先无视.

重点在这一行代码:


调用函数createNameNode(a,b);

找这个函数,1365:


 

 

返回类型为NameNode的静态成员函数.

依次作了这样几件事情:

1.LOG

2.建立一个HdfsConfiguration对象

3.建立一个StartupOption类的对象

4.设置StartupOption

5.switch-case

在这个条件语句模块里面找到FORMAT,


 

 

 

 

 

执行format函数,意思就是这个函数用来格式化namenode的了?

903,找到了:


 

 

 

 

 

跳到真正执行format指令的那一步


 

 

 

 

 

 

 

 

 

 

使用了2个对象fsnfsImage,

留意在932,

FSImage fsImage = new FSImage(conf, nameDirsToFormat, editDirsToFormat) ;

如今就须要弄明白FSImage是怎样的一个类,以及format方法实现了怎样的功能.

说明:如下步骤均在bluefish工具的协助下进行

138:


 

 

 

 

 

 

 

 

 

 

 

对应运行hadoop namenode -format时的log:





 

 

 

工做是由storage.format(ns);”这行代码完成的

打开NNStorage.java,找到format(ns)方法;


 

 

 

 

 

 

 

打开Storage.java,找到clearDirectory()方法:


 

 

 

 

 

 

 

 

 

 

 

 

 

接下来就是FileUtil.fullyDelete(curDir).

在源码中没有找到fs.FileUtil,hadoop API中查找到了

public static void fullyDelete(FileSystem fs,Path dir);


 

 

 

 

 

 

 

 

 

 

这样就删除了一个目录树了,运行时,dir显示为:

/tmp/hadoop-hadoop/dfs/name

经检查发现这个目录依然存在,而且目录下存在文件:


 

 

 

 

 

 

 

 

 

 

 

 

为何会出现这种状况?

并且,hadoop2.6.0的源代码中为何找不到fs.FileUtil?

这些问题有待解决.


尽管如此,format先后,对比文件占用容量大小:

Namenode Format前:













NameNode Format后:



 

 

 

 

 

 

 

 

 

能够看出,在执行了hadoop namenode -format以后,name目录占用的空间从1.1M 下降至24K

总结

本文的初衷是摸索出一条命令执行的流程,从而加深对hadoop系统的认识。

不过,这些步骤只是作了一点皮毛的功夫,并没能触及hadoop最核心的部分,无论是做为一个分布式系统也好,仍是一个java开源项目也好。

尽管如此,咱们能够以此为切入点,如同滚雪球同样一点一点加深对这个生态系统的把握。

相关文章
相关标签/搜索