其實參看Hadoop官方文檔已經能夠很容易配置分佈式框架運行環境了,不過這裏既然寫了就再多寫一點,同時有一些細節需要注意的也說明一下,其實也就是這些細節會讓人摸索半天。Hadoop可以單機跑,也可以配置集羣跑,單機跑就不需要多說了,只需要按照Demo的運行說明直接執行命令即可。這裏主要重點說一下集羣配置運行的過程。
環境
7臺普通的機器,操作系統都是Linux。內存和CPU就不說了,反正Hadoop一大特點就是機器在多不在精。JDK必須是1.5以上的,這個切記。7臺機器的機器名務必不同,後續會談到機器名對於MapReduce有很大的影響。
部署考慮
正如上面我描述的,對於Hadoop的集羣來說,可以分成兩大類角色:Master和Slave,前者主要配置NameNode和JobTracker的角色,負責總管分佈式數據和分解任務的執行,後者配置DataNode和TaskTracker的角色,負責分佈式數據存儲以及任務的執行。本來我打算看看一臺機器是否可以配置成Master,同時也作爲Slave使用,不過發現在NameNode初始化的過程中以及TaskTracker執行過程中機器名配置好像有衝突(NameNode和TaskTracker對於Hosts的配置有些衝突,究竟是把機器名對應IP放在配置前面還是把Localhost對應IP放在前面有點問題,不過可能也是我自己的問題吧,這個大家可以根據實施情況給我反饋)。最後反正決定一臺Master,六臺Slave,後續複雜的應用開發和測試結果的比對會增加機器配置。
實施步驟
在所有的機器上都建立相同的目錄,也可以就建立相同的用戶,以該用戶的home路徑來做hadoop的安裝路徑。例如我在所有的機器上都建立了
/home/wenchu
。下載Hadoop,先解壓到Master上。這裏我是下載的0.17.1的版本。此時Hadoop的安裝路徑就是
/home/wenchu/hadoop-0.17.1
。解壓後進入conf目錄,主要需要修改以下文件:
hadoop-env.sh
,hadoop-site.xml
、masters
、slaves
。Hadoop的基礎配置文件是
hadoop-default.xml
,看Hadoop的代碼可以知道,默認建立一個Job的時候會建立Job的Config,Config首先讀入hadoop-default.xml
的配置,然後再讀入hadoop-site.xml
的配置(這個文件初始的時候配置爲空),hadoop-site.xml
中主要配置你需要覆蓋的hadoop-default.xml
的系統級配置,以及你需要在你的MapReduce過程中使用的自定義配置(具體的一些使用例如final等參考文檔)。以下是一個簡單的
hadoop-site.xml
的配置:<?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <!-- Put site-specific property overrides in this file. --> <configuration> <property> <name>fs.default.name</name>//你的namenode的配置,機器名加端口 <value>hdfs://10.2.224.46:54310/</value> </property> <property> <name>mapred.job.tracker</name>//你的JobTracker的配置,機器名加端口 <value>hdfs://10.2.224.46:54311/</value> </property> <property> <name>dfs.replication</name>//數據需要備份的數量,默認是三 <value>1</value> </property> <property> <name>hadoop.tmp.dir</name>//Hadoop的默認臨時路徑,這個最好配置,如果在新增節點或者其他情況下莫名其妙的DataNode啓動不了,就刪除此文件中的tmp目錄即可。不過如果刪除了NameNode機器的此目錄,那麼就需要重新執行NameNode格式化的命令。 <value>/home/wenchu/hadoop/tmp/</value> </property> <property> <name>mapred.child.java.opts</name>//java虛擬機的一些參數可以參照配置 <value>-Xmx512m</value> </property> <property> <name>dfs.block.size</name>//block的大小,單位字節,後面會提到用處,必須是512的倍數,因爲採用crc作文件完整性校驗,默認配置512是checksum的最小單元。 <value>5120000</value> <description>The default block size for new files.</description> </property> </configuration>
hadoop-env.sh
文件只需要修改一個參數:# The java implementation to use. Required.
export JAVA_HOME=/usr/ali/jdk1.5.0_10
配置你的Java路徑,記住一定要1.5版本以上,免得莫名其妙出現問題。
Masters中配置Masters的IP或者機器名,如果是機器名那麼需要在
/etc/hosts
中有所設置。Slaves中配置的是Slaves的IP或者機器名,同樣如果是機器名需要在/etc/hosts
中有所設置。範例如下,我這裏配置的都是IP:Masters: 10.2.224.46 Slaves: 10.2.226.40 10.2.226.39 10.2.226.38 10.2.226.37 10.2.226.41 10.2.224.36
建立Master到每一臺Slave的SSH受信證書。由於Master將會通過SSH啓動所有Slave的Hadoop,所以需要建立單向或者雙向證書保證命令執行時不需要再輸入密碼。在Master和所有的Slave機器上執行:
ssh-keygen -t rsa
。執行此命令的時候,看到提示只需要回車。然後就會在/root/.ssh/
下面產生id_rsa.pub
的證書文件,通過scp將Master機器上的這個文件拷貝到Slave上(記得修改名稱),例如:scp root@masterIP:/root/.ssh/id_rsa.pub /root/.ssh/46_rsa.pub
,然後執行cat /root/.ssh/46_rsa.pub >>/root/.ssh/authorized_keys
,建立authorized_keys
文件即可,可以打開這個文件看看,也就是rsa的公鑰作爲key,user@IP作爲value。此時可以試驗一下,從master ssh到slave已經不需要密碼了。由slave反向建立也是同樣。爲什麼要反向呢?其實如果一直都是Master啓動和關閉的話那麼沒有必要建立反向,只是如果想在Slave也可以關閉Hadoop就需要建立反向。將Master上的Hadoop通過scp拷貝到每一個Slave相同的目錄下,根據每一個Slave的
Java_HOME
的不同修改其hadoop-env.sh
。修改Master上
/etc/profile:
新增以下內容:(具體的內容根據你的安裝路徑修改,這步只是爲了方便使用)export HADOOP_HOME=/home/wenchu/hadoop-0.17.1
export PATH=$PATH:$HADOOP_HOME/bin
修改完畢後,執行
source /etc/profile
來使其生效。在Master上執行
Hadoop namenode –format
,這是第一需要做的初始化,可以看作格式化吧,以後除了在上面我提到過刪除了Master上的hadoop.tmp.dir
目錄,否則是不需要再次執行的。然後執行Master上的
start-all.sh
,這個命令可以直接執行,因爲在6中已經添加到了path路徑,這個命令是啓動hdfs和mapreduce兩部分,當然你也可以分開單獨啓動hdfs和mapreduce,分別是bin目錄下的start-dfs.sh
和start-mapred.sh
。檢查Master的logs目錄,看看Namenode日誌以及JobTracker日誌是否正常啓動。
檢查Slave的logs目錄看看Datanode日誌以及TaskTracker日誌是否正常。
如果需要關閉,那麼就直接執行
stop-all.sh
即可。
以上步驟就可以啓動Hadoop的分佈式環境,然後在Master的機器進入Master的安裝目錄,執行hadoop jar hadoop-0.17.1-examples.jar wordcount
輸入路徑和輸出路徑,就可以看到字數統計的效果了。此處的輸入路徑和輸出路徑都指的是HDFS中的路徑,因此你可以首先通過拷貝本地文件系統中的目錄到HDFS中的方式來建立HDFS中的輸入路徑:
hadoop dfs -copyFromLocal /home/wenchu/test-in test-in。
其中/home/wenchu/test-in
是本地路徑,test-in
是將會建立在HDFS中的路徑,執行完畢以後可以通過hadoop dfs –ls
看到test-in目錄已經存在,同時可以通過hadoop dfs –ls test-in
查看裏面的內容。輸出路徑要求是在HDFS中不存在的,當執行完那個demo以後,就可以通過hadoop dfs –ls
輸出路徑看到其中的內容,具體文件的內容可以通過hadoop dfs –cat
文件名稱來查看。
經驗總結和注意事項(這部分是我在使用過程中花了一些時間走的彎路):
Master和Slave上的幾個conf配置文件不需要全部同步,如果確定都是通過Master去啓動和關閉,那麼Slave機器上的配置不需要去維護。但如果希望在任意一臺機器都可以啓動和關閉Hadoop,那麼就需要全部保持一致了。
Master和Slave機器上的
/etc/hosts
中必須把集羣中機器都配置上去,就算在各個配置文件中使用的是IP。這個吃過不少苦頭,原來以爲如果配成IP就不需要去配置Host,結果發現在執行Reduce的時候總是卡住,在拷貝的時候就無法繼續下去,不斷重試。另外如果集羣中如果有兩臺機器的機器名如果重複也會出現問題。如果在新增了節點或者刪除節點的時候出現了問題,首先就去刪除Slave的
hadoop.tmp.dir
,然後重新啓動試試看,如果還是不行那就乾脆把Master的hadoop.tmp.dir
刪除(意味着dfs上的數據也會丟失),如果刪除了Master的hadoop.tmp.dir
,那麼就需要重新namenode –format
。Map任務個數以及Reduce任務個數配置。前面分佈式文件系統設計提到一個文件被放入到分佈式文件系統中,會被分割成多個block放置到每一個的DataNode上,默認
dfs.block.size
應該是64M,也就是說如果你放置到HDFS上的數據小於64,那麼將只有一個Block,此時會被放置到某一個DataNode中,這個可以通過使用命令:hadoop dfsadmin –report
就可以看到各個節點存儲的情況。也可以直接去某一個DataNode查看目錄:hadoop.tmp.dir/dfs/data/current
就可以看到那些block了。Block的數量將會直接影響到Map的個數。當然可以通過配置來設定Map和Reduce的任務個數。Map的個數通常默認和HDFS需要處理的blocks相同。也可以通過配置Map的數量或者配置minimum split size來設定,實際的個數爲:max(min(block_size,data/#maps),min_split_size)
。Reduce可以通過這個公式計算:0.95*num_nodes*mapred.tasktracker.tasks.maximum
。
總的來說出了問題或者啓動的時候最好去看看日誌,這樣心裏有底。
Hadoop中的命令(Command)總結
這部分內容其實可以通過命令的Help以及介紹瞭解,我主要側重於介紹一下我用的比較多的幾個命令。Hadoop dfs 這個命令後面加參數就是對於HDFS的操作,和Linux操作系統的命令很類似,例如:
Hadoop dfs –ls
就是查看/usr/root目錄下的內容,默認如果不填路徑這就是當前用戶路徑;Hadoop dfs –rmr xxx
就是刪除目錄,還有很多命令看看就很容易上手;Hadoop dfsadmin –report
這個命令可以全局的查看DataNode的情況;Hadoop job
後面增加參數是對於當前運行的Job的操作,例如list,kill等;Hadoop balancer
就是前面提到的均衡磁盤負載的命令。
其他就不詳細介紹了。