Hadoop學習筆記(9) ——源碼初窺

Hadoop學習筆記(9) java

——源碼初窺 node

以前咱們把Hadoop算是入了門,下載的源碼,寫了HelloWorld,簡要分析了其編程要點,而後也編了個較複雜的示例。接下來其實就有兩條路可走了,一條是繼續深刻研究其編程及部署等,讓其功能使用的淋漓盡致。二是停下來,先看看其源碼,研究下如何實現的。在這裏我就選擇第二條路。 linux

研究源碼,那咱們就來先看一下整個目錄裏有點啥: c++

這個是剛下完代碼後,目錄列表中的內容。 web

目錄/文件apache

說明編程

binwindows

下面存放着可執行的sh命名,全部操做都在這裏app

confeclipse

配置文件所在目錄

ivy

Apache Ivy是專門用來管理項目的jar包依賴的,這個是ivy的主要目錄

lib

引用的庫文件目錄,裏面存放用到的jar包

src

這個裏面就是主要的源碼了

build.xml

用於編譯的配置文件。 編譯咱們用的是ant

CHANGES.txt

文本文件,記錄着本版本的變動歷史

ivy.xml

Ivy的配置文件

LICENSE.txt

文件本文件,

NOTICE.txt

文本文件,記錄着須要注意的地方

README.txt

說明文件。

 

進入src目錄,咱們看到了:

目錄/文件

說明

ant

爲ant命令編寫的擴展指定

benchmarks

筆者也沒弄明白L

build

就存放一個打包信息文件

c++

linuxamd64-64位系統以及i386-32位系統提供的庫文件集合

contrib

是開源界或第三方爲hadoop編寫的一些擴展程序,如eclipse插件等

core

Hadoop的核心代碼

docs

文檔

examples

示例程序

hdfs

HDFS模塊的代碼

marped

MapReduce模塊代碼

native

筆者也沒弄明白L

test

測試程序

tools

工具集

webapps

網頁管理工具的代碼,主要是jsp文件。

fixFontsPath.sh

用於修正字體路徑的批處理命令。

saveVersion.sh

用於生成打包信息文件批處理命令。

 

這些目錄及文件命名及分佈仍是很清晰的,基本上根據命名也能猜出其意思來了。當咱們拿到這些文件時,作了兩件事,編譯運行,接下來咱們一塊塊仔細來看看。

 

編譯

當咱們拿到手時,第一章中講到,咱們用瞭如下命令就完成了編譯:

~/hadoop-0.20.2$ant

~/hadoop-0.20.2$ant jar

~/hadoop-0.20.2$ant examples

在編譯完後,咱們發現,目錄中多了一個build文件夾。這個文件夾下,咱們發現有大量的子文件夾,再深刻看,能夠找到了N多個.class文件。那這個正是java程序的編譯產出物。

咱們在第5章中,簡要的描述了java程序與.net的差異。一個.java程序對應一個.class文件,手動的話用javac來編譯。咱們要將這麼多的java文件都要編譯成一個個的.class文件,敲javac命令確定是不行的,咱們得找個打包處理的辦法。這個就是ant。簡單的說ant就是將編譯命名進行打包處理的程序,這個程序有一個配置文件就是build.xml。因此咱們進入hadoop根目錄後輸入了ant後就開始運行了,由於它在當前目錄下找到了build.xml文件。那ant能作啥,其實百度上一搜就有不少了。這裏就不詳述了。咱們簡要的來看一下build.xml。 打開一看,build.xml文件貌似很複雜,有1千8百多行。不要怕,簡單看下:

一上來,定義了一個project,看來這是一個工程,有名稱和default屬性(default後面看是啥)。

接下來發現是一堆的property,而後是name-value的健值。應該猜的出,這些就是後面真正執行用的一些變量或參數。

再往下,看到有這些:

看到有target,而後取了個名,字面意思是目標,而後看看子結點,發現是mkdir,好熟悉的字眼,這不是在建立目錄麼,看下第一個dir是啥,${build.dir}。而後當即跑回上面property中,看下是否有呢?

果真,這個就是在編譯後的產生的目錄,第一步建立之,很正常。

既然這樣,這個target就是一個個目標,而後往下拖一下,發現下面的都是一個個的目錄,全文搜索一下:

發現裏面有106個。

繼續搜,發現了亮點:

這個target(目標)好眼熟,~/hadoop-0.20.2$ant jar 沒錯,當時在編譯時,輸入這個命令後,就產出了一個jar文件。看來這個target就是在造成jar文件,略看下其子命令,的確就是在生成jar包了。

簡單瞭解了這個target後,就能夠繼續找找,咱們的examples命令了。現回想起來,在編譯時第一個命令是~/hadoop-0.20.2$ant,而這個好象沒有寫target麼?又想到了:

難道這個default就是傳說中的默認目標? compile。 熬不住了,當即展開搜索:

果真,猜的沒錯。找到了這個默認目錄,而後發現好多target後還有depends,字面意思,依賴吧,而後能夠繼續找,依賴裏面的目錄,也是一個個的target。

瞭解了這個以後,咱們又在想,如今知道的target也就 默認、jar、example,還有哪些呢,咱們就能夠搜target name="這個字符。固然會發現有不少,可是不是每一個都對咱們有用,由於好可能是爲了編寫方便,將一個大的拆成多個小的,以便於維護。至於哪些有用的,這裏我就不一一列出。能夠本身看看。 好比clean就不錯,能夠把編譯後的結果清理掉,還原到開始狀態。

 

編譯成.class包括jar包如今都沒問題了。咱們知道hadoop是用java寫的,在src下可找到大量java類文件。難道這個hadoop就沒有引用一個第三方的組件?答案是有的,一開始沒看到幾個,在lib下就只有幾個。 可是在ant完後,在build下搜,發現有好多個jar文件。 哪來的? 下載的。誰負責下載的,爲何知道要下載這些文件?

咱們發現,在build.xml中,第一個target init就有depends:

而後就能夠一級級查到,是通用ivy進行下載的,至於下載哪些,在ivy.xml中就有配置。好了,這塊並非咱們的重點,瞭解到這裏就夠了,反正所用到的lib文件都下來了。

 

運行

在第一章中,咱們瞭解到啓用整個hadoop,全到了這個命令:bin/start-all.sh,關閉是用到了bin/stop-all.sh。而這個又是什麼文件,咱們來研究一下看。

不急看start-all, 咱們打開bin目錄看一下:

在bin下有不少個sh文件,hadoop這個命令,雖然沒有後綴,但打開看後,發現跟其餘sh文件樣,相似的腳本。

什麼是sh文件? 在windows中咱們知道bat文件,就是將若干個命令放到一個文件中,依次執行,稱之爲批處理文件。在Linux中,這個bat文件就是sh文件了。

先不急着打開文件內容,咱們觀察下因此文件,看到下面8個,頗有規律,4個startXXX.sh而後4個stopXXX.sh文件。看來這些就是用戶啓動和關閉hadoop用的。

打開start-all.sh,發現內容並很少,也很好理解:

 

這裏,先調了一下hadoop-config.sh,字面意思,設置配置文件。而後再調了start-dfs 和start-mapred。這裏就很明顯了,start-all是啓動整個hadoop,而後裏面包含了兩個動做,啓動dfs和mapreduce。 同理,若是我想只啓動dfs,那麼只須要運行start-dfs.sh便可。

一樣,打開stop-all.sh文件,也能夠看到比較簡單,

發現是分別調了stop-mapred.sh和stop-dfs.sh這兩個文件。

這裏咱們就不每一個文件進行分析了,咱們只挑幾個關鍵文件看一下。

 

繼續前行,打開start-dfs.sh和stop-dfs.sh文件,發現裏面

 

你們能夠打開其餘全部的startXX和stopXX文件,發現全部的操做都又轉入了hadoop-daemon.sh和hadoop-daemons.sh這兩個命令,同時傳入了參數—config stop/start 名稱 (opt參數)。

繼續,打開hadoop-daemons.sh,發現內容也很簡單:

這裏,先調用了slaves.sh後,又調回來hadoop-daemon.sh,因此如今目標焦點就只有兩個了hadoop-daemon.sh和slaves.sh了。打開slaves.sh看一下:

這個文件的字面意思應該就是啓動各分佈式子機的hadoop咯。看一下代碼,第一個if與fi之間,能夠看到是取得conf文件夾下的slaves文件。記得在配置分配布式裏面,在slaves中配置寫了是node1 node2用回車換行隔開。 因此第二段代碼,for循環slaves中的文件,而後調用ssh命令,調到了子系統中的相應的命令,這裏,就徹底能夠想通了,爲何子系統中部署的hadoop目錄須要與主目錄相同,而後slaves中配置的是子系統機器的名稱。

到這裏,整個bin目錄的腳本,就集中在剩下的兩個hadoop-daemon.sh和hadoop了。勝利在望了。先看hadoop-daemon.sh。

一開始,代碼是在取參數,startstop和command,從前面的傳入能夠看到,startstop參數傳的是start和stop,看來是啓動和關閉, command是namenode、datanode之類的。

繼續往下看:

case語句下進行了分類,將start和stop命令分開處理。在start時,先是建立一個文件夾PID_DIR,具體值能夠看上面,而後第一段if,是在判斷進程有沒有啓動,而後最關健是執行nohup nice …. /bin/hadoop。也就是說歸根到底又都是在執行hadoop命令了。這裏nohup,是指啓動進程後不被卡住,即轉爲後臺進程,又稱守護進程,因此該sh文件命名爲daemon也不爲過。

而後stop段時,把進程進行kill掉。這裏有疑問了,啓動的命令kill裏須要知道進程的PID,而kill裏哪裏獲取呢,在啓動時,將啓動進程後的pid記錄在PID文件夾內,而後kill時就能夠跟據這些PID來處理了。這塊在代碼中,也比較清晰的體現了。

 

在執行hadoop命令時,又將namenode、datanode、secondarynamenode等命令傳入。因此如今能夠打開hadoop命令文件了:(這裏直接跳入重點看)

這裏,看到有大量的if語句,條件是command判斷,而後執行中對class和hadoop_opts進行了賦值。 繼續往下看:(在最後)

咱們發現,是在執行java命令,傳入的main函數入口正是上面條件處理中的CLASS變量。換句話說,這個CLASS應該對應一個個的main函數咯? 驗證一下,找一個,好比dataNode,其CLASS是org.apache.hadoop.hdfs.server.datanode.DataNode。按這路徑在src中找到文件DataNode.java,打開,而後搜main:

果真,徹底應正了咱們的想法。

總結一下:整個hadoop程序,是一個java爲主的程序,在編譯是將.class文件生成在build目錄,在運行時,雖然執行的是.sh文件,但一步步,最終都是在執行java命令,傳入的入口,就是各個子程序的main函數入口。

 

想法1:看了這個sh命令後,又有一個想法,以前經過starg-all.sh就把整個程序啓動起來了,並且是在後臺運行的,輸出內容只能從log文件夾內看,可否直接從命令行啓動呢? 固然行,輸入 bin/hadoop namenode試試,果真,啓動了namenode程序,而後日誌信息也直接打印在屏幕上了。

想法2:既然從hadoop這個sh文件夾內,能夠看到全部的入口,那就能夠整理一下,全部的入口成一個列表,方便之後找到其main函數。

命令

入口

namenode

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

secondarynamenode

org.apache.hadoop.hdfs.server.namenode.SecondaryNameNode

datanode

org.apache.hadoop.hdfs.server.datanode.DataNode

fs / dfs

org.apache.hadoop.fs.FsShell

dfsadmin

org.apache.hadoop.hdfs.tools.DFSAdmin

mradmin

org.apache.hadoop.mapred.tools.MRAdmin

fsck

org.apache.hadoop.hdfs.tools.DFSck

balancer

org.apache.hadoop.hdfs.server.balancer.Balancer

jobtracker

org.apache.hadoop.mapred.JobTracker

tasktracker

org.apache.hadoop.mapred.TaskTracker

job

org.apache.hadoop.mapred.JobClient

queue

org.apache.hadoop.mapred.JobQueueClient

pipes

org.apache.hadoop.mapred.pipes.Submitter

version

org.apache.hadoop.util.VersionInfo

jar

org.apache.hadoop.util.RunJar

distcp

org.apache.hadoop.tools.DistCp

daemonlog

org.apache.hadoop.log.LogLevel

archive

org.apache.hadoop.tools.HadoopArchives

sampler

org.apache.hadoop.mapred.lib.InputSampler

 

至此整個目錄有了一個初步的瞭解,接下來,那就能夠順着這些入口深刻研究了。且慢,還差個調試環境呢! 下一章來。

相關文章
相關標籤/搜索