心血之做,在熟悉hadoop2架構的過程耽誤了太長時間,在搭建環境過程遇到一些問題,這些問題一直卡在那兒,不得以解決,耽誤了時間。最後,千尋萬尋,把問題解決,多謝在過程提供幫助的大俠。這篇文章中,我也會把本身遇到的問題給列出來,幫助後來者進一步的學習。java
這篇文章結合本身實際測試過程,花費太多心血整理。node
本文主要經過對hadoop2.5.2集羣配置的過程加以梳理,全部的步驟都是經過本身實際測試。文檔的結構也是根據本身的實際狀況而定,同時也會加入本身在實際過程遇到的問題。搭建環境過程不重要,重要點在於搭建過程當中遇到的問題,解決問題的過程。web
可能本身遇到的問題在一些由經驗的老者手上都不是問題,可是這些問題着實讓本身耽誤了很長時間,最後問題解決也是費了太大心血。也經過這篇文檔,表現出來,算是總結,爲後者提供意見。apache
要想理解本節內容,首先須要瞭解hadoop1的體系結構。這裏不過多的介紹基於hadoop1的體系架構,早在以前,曾搭建hadoop1.2.1僞分佈式集羣,詳細請看hadoop學習(一)hadoop-1.2.1僞分佈式配置及遇到的問題。這裏主要介紹hadoop2的體系架構。bash
hadoop1的核心組成是兩部分,即HDFS和MapReduce。在hadoop2中變爲HDFS和Yarn。服務器
新的HDFS中的NameNode再也不是隻有一個了,能夠有多個(目前只支持2個)。每個都有相同的職能。session
這兩個NameNode的地位如何:一個是active狀態的,一個是standby狀態的。當 集羣運行時,只有active狀態的NameNode是正常工做的,standby狀態的NameNode是處於待命狀態的,時刻同步active狀態 NameNode的數據。一旦active狀態的NameNode不能工做,經過手工或者自動切換,standby狀態的NameNode就能夠轉變爲 active狀態的,就能夠繼續工做了。這就是高可靠。架構
當NameNode發生故障時,他們的數據如何保持一致:在這裏,2個NameNode的數據實際上是實時共享的。新HDFS採用了一種共享機制,JournalNode集羣或者NFS進行共享。NFS是操做系統層面的,JournalNode是hadoop層面的,咱們這裏使用JournalNode集羣進行數據共享。app
如何實現NameNode的自動切換:這就須要使用ZooKeeper集羣進行選擇了。HDFS集羣中的兩個NameNode都在ZooKeeper中註冊,當active狀態的NameNode出故障時,ZooKeeper能檢測到這種狀況,它就會自動把standby狀態的NameNode切換爲active狀態。ssh
HDFS Federation(HDFS聯盟):聯盟的出現是有緣由的。咱們知道 NameNode是核心節點,維護着整個HDFS中的元數據信息,那麼其容量是有限的,受制於服務器的內存空間。當NameNode服務器的內存裝不下數據後,那麼HDFS集羣就裝不下數據了,壽命也就到頭了。所以其擴展性是受限的。HDFS聯盟指的是有多個HDFS集羣同時工做,那麼其容量理論上就不受限了,誇張點說就是無限擴展。你能夠理解成,一個總集羣中,能夠虛擬出兩個或兩個以上的單獨的小集羣,各個小集羣之間數據是實時共享的。由於hadoop集羣中已經不在單獨存在namenode和datanode的概念。當一個其中一個小集羣出故障,能夠啓動另外一個小集羣中的namenode節點,繼續工做。由於數據是實時共享,即便namenode或datanode一塊兒死掉,也不會影響整個集羣的正常工做。
這點很重要,咱們事先必定要先理解,節點之間任務是如何安排的。若是事先不理解爲何是這樣,後面還會遇到更多的問題。這就須要,理解journalnode、zookeeper、datanode、namenode之間關係。本身也是在這上面耽誤了很長時間,但願讀者這點多注意下。
6臺主機。
Journalnode和zookeeper保持奇數點,這點你們要有個概念,最少很多於3個節點。這裏暫不講解。
兩個namenode上面已經說明,其實在hadoop2中幾點之間namenode和datanode之間的劃分已經不是那麼明確了。這只是採用後4臺機器做爲namenode。這裏也存在一個問題:若是把datanode和namenode放在一塊兒,對數據的讀取IO的效率確定會有必定的影響,不一樣機器之間仍是要經過網線和http請求完成數據之間的共享。實際中,二者是能夠在一塊兒。可是我不知道在一塊兒和不在一塊兒之間的主要區別在哪兒,上面的解釋只是我的意見,若是讀者有更好的意見能夠留言,你們一塊兒討論。
下面就進入正式的集羣的安裝過程:
下面全部的過程都是在hadoop1機器上完成的,以後把文件複製到其餘節點中。
下載地址:http://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.4.6/
解壓到指定目錄:這裏目錄:/home/tom/yarn/hadoop-2.5.2/app/
在hadoop目錄中建立app目錄。把文件解壓到hadoop的app目錄中,是爲了之後整個項目能夠總體移植。包括後面,咱們會安裝HBase、Hive等軟件,都是解壓到app的目錄中。
拷貝命名zoo_sample.cfg 爲zoo.cfg。咱們通常不修改配置文件默認的示例文件,修改賦值其子文件。
編輯zoo.cfg
拷貝命名zoo_sample.cfg 爲zoo.cfg。咱們通常不修改配置文件默認的示例文件,修改賦值其子文件。
編輯zoo.cfg
tickTime=2000 initLimit=10 syncLimit=5 dataDir=/home/tom/yarn/hadoop-2.5.0/app/zookeeper-3.4.6/zkdata dataLogDir=/home/tom/yarn/hadoop-2.5.0/app/zookeeper-3.4.6/zkdatalog clientPort=2181 server.1=hadoop1:2888:3888 server.2=hadoop2:2888:3888 server.3=hadoop3:2888:3888 server.4=hadoop4:2888:3888 server.5=hadoop5:2888:3888
在zookeeper的目錄中,建立上述兩個文件夾。進入zkdata文件夾,建立文件myid,填入1。這裏寫入的1,是在zoo.cfg文本中的server.1中的1。當咱們把全部文件都配置完畢,咱們把hadoop1中yarn目錄複製到其它機器中,咱們在修改每臺機器中對應的myid文本,hadoop2中的myid寫入2。其他節點,安照上面配置,依此寫入相應的數字。Zkdatalog文件夾,是爲了指定zookeeper產生日誌指定相應的路徑。
本機環境變量添是在/etc/profile目錄中添加的。也能夠不用添加到環境變量
添加環境變量 本機環境變量添是在/etc/profile目錄中添加的。
添加ZOOKEEPER_HOME/bin目錄能夠在原有的PATH後面加入
:$ZOOKEEPER_HOME/bin
關於環境變量修改/etc目錄下的profile文件,也能夠在根目錄下的.bashrc目錄下添加環境變量。這二者有什麼區別:.bashrc是對當前目錄用戶的環境變量,profile文件是對全部用戶都開放的目錄。當系統加載文件中,先從profile找相應的路勁,若是沒有會在.bashrc文件中找對應的環境變量路徑。這二者你們稍至瞭解。
而後 source /etc/profile
上面3個步驟就安裝zookeeper完畢。而後就是測試zookeeper,這個放到後面等hadoop1上總體配置完畢,scp到其它主機上後,再一塊兒測試。
路徑:http://apache.dataguru.cn/hadoop/common/hadoop-2.5.2/
解壓到:/home/tom/yarn/下。其實這一步應該在解壓zookeeper以前。再也不多講。
這裏要修改配置文件一共包括6個,分別是在hadoop-env.sh、core-site.xml、hdfs-site.xml、mapred-site.xml、 yarn-site.xml和slaves。
修改文件的目錄地址:/home/tom/yarn/hadoop-2.5.2/etc/hadoop/
添加jdk環境變量:
export JAVA_HOME=/usr/lib/jvm/jdk1.7.0_45
<configuration> <property> <name>fs.defaultFS</name> <value>hdfs://cluster1</value> </property> 【這裏的值指的是默認的HDFS路徑。這裏只有一個HDFS集羣,在這裏指定!該值來自於hdfs-site.xml中的配置】 <property> <name>hadoop.tmp.dir</name> <value>/home/tom/yarn/yarn_data/tmp</value> </property> 【這裏的路徑默認是NameNode、DataNode、JournalNode等存放數據的公共目錄。用戶也能夠本身單獨指定這三類節點的目錄。這裏的yarn_data/tmp目錄與文件都是本身建立的】 <property> <name>ha.zookeeper.quorum</name> <value>hadoop1:2181,hadoop2:2181,hadoop3:2181,hadoop4:2181,hadoop5:2181</value> </property> 【這裏是ZooKeeper集羣的地址和端口。注意,數量必定是奇數,且很多於三個節點】 </configuration><span style="font-size:14px;"><span style="font-family:宋體;"></span></span>
重點核心文件: <configuration> <property> <name>dfs.replication</name> <value>3</value> </property> 【指定DataNode存儲block的副本數量。默認值是3個,咱們如今有4個DataNode,該值不大於4便可。】 <property> <name>dfs.permissions</name> <value>false</value> </property> 【設置權限以後能夠控制各用戶之間的權限】 <property> <name>dfs.permissions.enabled</name> <value>false</value> </property> <property> <name>dfs.nameservices</name> <value>cluster1</value> </property> 【給hdfs集羣起名字,這個名字必須和core-site中的統一,且下面也會用到該名字】 <property> <name>dfs.ha.namenodes.cluster1</name> <value>hadoop1,hadoop2</value> </property> 【指定NameService是cluster1時的namenode有哪些,這裏的值也是邏輯名稱,名字隨便起,相互不重複便可】 <property> <name>dfs.namenode.rpc-address.cluster1.hadoop1</name> <value>hadoop1:9000</value> </property> 【指定hadoop101的RPC地址】 <property> <name>dfs.namenode.http-address.cluster1.hadoop1</name> <value>hadoop1:50070</value> </property> 【指定hadoop101的http地址】 <property> <name>dfs.namenode.rpc-address.cluster1.hadoop2</name> <value>hadoop2:9000</value> </property> <property> <name>dfs.namenode.http-address.cluster1.hadoop2</name> <value>hadoop2:50070</value> </property> <property> <name>dfs.namenode.servicerpc-address.cluster1.hadoop1</name> <value>hadoop1:53310</value> </property> <property> <name>dfs.namenode.servicerpc-address.cluster1.hadoop2</name> <value>hadoop2:53310</value> </property> <property> <name>dfs.ha.automatic-failover.enabled.cluster1</name> <value>true</value> </property> 【指定cluster1是否啓動自動故障恢復,即當NameNode出故障時,是否自動切換到另外一臺NameNode】 <!--指定JournalNode --> <property> <name>dfs.namenode.shared.edits.dir</name> <value>qjournal://hadoop1:8485;hadoop2:8485;hadoop3:8485;hadoop4:8485;hadoop5:8485/cluster1</value> </property> 【指定cluster1的兩個NameNode共享edits文件目錄時,使用的JournalNode集羣信息】 <property> <name>dfs.client.failover.proxy.provider.cluster1</name> <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value> </property> 【指定cluster1出故障時,哪一個實現類負責執行故障切換】 <property> <name>dfs.journalnode.edits.dir</name> <value>/home/tom/yarn/yarn_data/tmp/journal</value> </property> 【指定JournalNode集羣在對NameNode的目錄進行共享時,本身存儲數據的磁盤路徑。tmp路徑是本身建立,journal是啓動journalnode自動生成】 <property> <name>dfs.ha.fencing.methods</name> <value>sshfence</value> </property> 【一旦須要NameNode切換,使用ssh方式進行操做】 <property> <name>dfs.ha.fencing.ssh.private-key-files</name> <value>/home/tom/.ssh/id_rsa</value> </property> 【這裏是使用ssh進行故障切換,因此須要配置無密碼登陸,使用ssh通訊時用的密鑰存儲的位置】 <property> <name>dfs.ha.fencing.ssh.connect-timeout</name> <value>10000</value> </property> <property> <name>dfs.namenode.handler.count</name> <value>100</value> </property> </configuration>
<configuration> <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> </configuration> 【指定運行mapreduce的環境是yarn,與hadoop1不一樣的地方】
<configuration> <property> <name>yarn.resourcemanager.hostname</name> <value>hadoop1</value> </property> 【自定義ResourceManager的地址,仍是單點】 <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce.shuffle</value> </property> </configuration>
添加:這裏指定哪臺機器是datanode,這裏指定6臺機器。把集羣全部機器都當作datanode
hadoop1 hadoop2 hadoop3 hadoop4 hadoop5 hadoop6
在hadoop的的根目錄下(即:/home/tom目錄下):由於咱們全部的環境都裝載在hadoop1的tom目錄下。
使用scp -r命令便可
注意點:
一、由於咱們是把整個yarn目錄複製到其餘節點中,zookeeper也包含在內。事先咱們定義zookeeper是在1-5臺機器上部署。這裏咱們雖然把zookeeper拷貝到6機器中,可是咱們再zookeeper配置文件中沒有配置6機器的節點,在啓動zookeeper的時候,6機器也不須要啓動。
二、如今要作的是進入zookeeper目錄下的zkdata目錄,修改myid文件:各個myid內容對應zoo.cfg文件中server對應的編號。
接下來開始啓動集羣
在hadoop1、hadoop2、hadoop3、hadoop四、hadoop5上zookeeper目錄下分別執行命令:bin/zkServer.sh start
在每一臺機器執行完上面的命令後,執行jps,會顯示:這是初步認定啓動沒有問題
當全部機器執行上述命令完畢後,再在每臺機器上執行:bin/zkServer.sh status 查看每臺機器zookeeper的狀態,正確的話,只有一臺機器是leader,其他機器都是顯示folower。1-5臺機器都須要測試一下
在hadoop1機器上,hadoop目錄,執行zkCli.sh 終端上會輸出一連串的信息。最後結束的信息是
Welcome to ZooKeeper! 2015-07-08 16:44:40,028 [myid:] - INFO [main-SendThread(localhost:2181):ClientCnxn$SendThread@966] - Opening socket connection to server localhost/127.0.0.1:2181. Will not attempt to authenticate using SASL (unknown error) 2015-07-08 16:44:40,033 [myid:] - INFO [main-SendThread(localhost:2181):ClientCnxn$SendThread@849] - Socket connection established to localhost/127.0.0.1:2181, initiating session JLine support is enabled 2015-07-08 16:44:40,094 [myid:] - INFO [main-SendThread(localhost:2181):ClientCnxn$SendThread@1207] - Session establishment complete on server localhost/127.0.0.1:2181, sessionid = 0x145407bbc720004, negotiated timeout = 30000 WATCHER:: WatchedEvent state:SyncConnected type:None path:null ls / [zookeeper] [zk: localhost:2181(CONNECTED) 1] [zk: localhost:2181(CONNECTED) 1]
這一步不是必要的,只是爲了測試一下zookeeper是否可以經過客戶端訪問
格式化zookeeper集羣,目的是在ZooKeeper集羣上創建HA的相應節點。
在hadoop1上的hadoop的目錄執行:bin/hdfs zkfc –formatZK
在hadoop一、hadoop2、hadoop3、hadoop四、hadoop5上分別hadoop目錄
執行命令:sbin/hadoop-daemon.sh start journalnode
從hadoop1和hadoop2中任選一個便可,這裏選擇的是hadoop1
在hadoop1上/home/tom/yarn/hadoop-2.5.2/目錄下執行下面命令:
bin/hdfs namenode -format -clusterId c1
6. 啓動ZooKeeperFailoverCotroller
在hadoop1、hadoop2、hadoop3、hadoop4、hadoop五、hadoop6上分別執行命令: sbin/hadoop-daemon.sh start zkfc
在hadoop1上/home/tom/yarn/hadoop-2.5.2/目錄下執行命令:/sbin/hadoop-daemon.sh start namenode
再hadoop2機器上,再使用/sbin/hadoop-daemon.sh start namenode 啓動namenode
Datanode是在slaves文件中配置的。在hadoop1上執行:
sbin/hadoop-daemons.sh start datanode
在hadoop1上執行命令:sbin/start-yarn.sh
全部集羣啓動完畢後,請經過web頁面進行查看狀態
在執行完第8步的時候,在頁面能夠觀察到兩個NameNode的狀態,hadoop1的狀態是standby,hadoop2的狀態是active。原先兩個namenode都是standby的狀態。
在hadoop1上咱們執行:kill -9 23558
23558 NameNode
而後jps:nemenode進程不存在了
而後刷新兩個頁面,能夠看到,兩臺機器的狀態置換了。原先的active變成standby,原先的standby變成active,這說明,HA故障自動轉換是正常的,HDFS是高可用的。
等你順利結束上面全部的步驟,都很順利的話,說明,你集羣搭建基本完成任務。說是基本,由於還有事情要作,就是,你要開始上傳文件開始測試程序,看看hadoop是否應用正常。這就是接下來要作的事情了。