對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開源項目也好。

儘管如此,咱們能夠以此爲切入點,如同滾雪球同樣一點一點加深對這個生態系統的把握。

相關文章
相關標籤/搜索