1. 程式人生 > >關於Hadoop-HA的配置---從零開始

關於Hadoop-HA的配置---從零開始

寫在文前,可能我說的有不對的地方,希望各位老鳥批評指正,本著虛心接受的態度分享這篇文章!

關於hadoop-ha大家配置的時候可能會遇到這樣或者那樣的報錯,實在很讓人頭疼,因為操作有點多,也很多人不知道到底要執行的步驟順序,今天給大家分享一下自己的愚見,我的hadoop是2.5.0的版本。

我們來看看,HA的原理圖:


我的叢集規劃是:

PC01--------------PC02-------------------PC03 NameNode-------NameNode ZKFC--------------ZKFC ----------------------------------------------ResourceManager DataNode--------DataNode-------------DataNode JournalNode-----JournalNode---------JournalNode NodeManager---NodeManager-------NodeManager ZooKeeper-------ZooKeeper-----------ZooKeeper

如圖:


這裡會有兩種狀態

1、故障了要手動切換

2、自動故障轉移

但是在下面的配置中,是完整的配置(就是包括自動故障轉移的配置,但是其實操作的步驟並沒有一開始就配置好自動故障轉移,所以配置檔案中我會標出,然後大家有幾個屬性先別配置)

1、前期準備環境:

三臺虛擬機器(最少)

hosts檔案要配置好,三臺都可以相互通過主機名ping通(以下是我的,三臺都要一樣)

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.163.103   bigdata-03
192.168.163.101   bigdata-01
192.168.163.102   bigdata-02

防火牆都關了

server iptables stop(關閉防火牆)

chkconfig iptables off(開機不自啟動)

免金鑰登入(這個一定要,不然你啟動的時候,老是要讓你輸入各種密碼)

其實就兩條命令,但是注意,三臺機器都要用相同的使用者去執行,不然會出問題!!!出問題了就去把.ssh這個目錄下的檔案刪除,重新生成

在三臺機器上都執行ssh-keygen -t rsa 然後三次回車,執行結束會在~/.ssh下生成兩個新檔案:id_rsa.pub和id_rsa就是公鑰和私鑰

然後也是在三臺機器上都執行:ssh-copy-id bigdata-01;ssh-copy-id bigdata-02;ssh-copy-id bigdata-03(你的公鑰和私鑰要發給別人,也要發給自己,切記!!)

同步時間

這個方法挺多的,大概思路就是第一臺機器去訪問外網同步時間,然後另外幾臺通過指令碼去同步第一臺(時間會有幾秒甚至幾分鐘誤差,這個沒關係),但是其實時間不一樣,我發現也沒什麼影響,所以。。。這裡就不給出具體的方法了,大家自行百度腦補下。

2、我們來理下思路,首先給出配置檔案裡寫什麼:

最首先需要依賴zookeeper把,所以zookeeper配置如下(我有三臺zookeeper):

dataDir=/opt/modules/App/zookeeper-3.4.5/zkData
server.1=bigdata-01:2888:3888
server.2=bigdata-02:2888:3888
server.3=bigdata-03:2888:3888

然後在dataDir目錄下(其實就是我這裡寫的zkData下面)寫上一個檔案叫myid,裡面的值就是第一臺機器寫1,第二臺寫2,第三臺寫3,就可以了,要跟你的server.1這裡的1,對應上就好,然後開啟zookeeper,看到是一臺leader,兩臺follower,這裡zookeeper開啟要給他點時間,因為他要三臺相互感知到,所以別急。。一般5分鐘內就沒問題了,如果5分鐘過了,還沒好的話,可以去看日誌了,因為應該是報錯了。

現在可以開始配置我們的hadoop叢集了,第一步在hadoop-env.sh和mapred-env.sh還有yarn-env.sh中寫上你的jdk路徑(有可能這條屬性被註釋掉了,記得解開,把前面的#去掉就可以了)export JAVA_HOME=/opt/modules/jdk1.7.0_67

然後core-site.xml

<configuration>
<property>
	<name>fs.defaultFS</name>
	<value>hdfs://ns1</value>
</property>
<property>
	<name>hadoop.tmp.dir</name>
	<value>/opt/modules/App/hadoop-2.5.0/data/tmp</value>
</property>
<property>
	<name>hadoop.http.staticuser.user</name>
	<value>beifeng</value>
</property>
<property>
	<name>ha.zookeeper.quorum</name>
	<value>bigdata-01:2181,bigdata-02:2181,bigdata-03:2181</value>
</property>
</configuration>

然後是hdfs-site.xml
<configuration>
<property>
	<name>dfs.replication</name>
	<value>3</value>
</property>
property>
	<name>dfs.permissions.enabled</name>
	<value>false</value>
</property>
<property>
	<name>dfs.nameservices</name>
	<value>ns1</value>
</property>
<property>
	<name>dfs.blocksize</name>
	<value>134217728</value>
</property>
<property>
	<name>dfs.ha.namenodes.ns1</name>
	<value>nn1,nn2</value>
</property>
<!-- nn1的RPC通訊地址,nn1所在地址  -->
<property>
	<name>dfs.namenode.rpc-address.ns1.nn1</name>
	<value>bigdata-01:8020</value>
</property>
<!-- nn1的http通訊地址,外部訪問地址 -->
<property>
	<name>dfs.namenode.http-address.ns1.nn1</name>
	<value>bigdata-01:50070</value>
</property>
<!-- nn2的RPC通訊地址,nn2所在地址 -->
<property>
	<name>dfs.namenode.rpc-address.ns1.nn2</name>
	<value>bigdata-02:8020</value>
</property>
<!-- nn2的http通訊地址,外部訪問地址 -->
<property>
	<name>dfs.namenode.http-address.ns1.nn2</name>
	<value>bigdata-02:50070</value>
</property>
<!-- 指定NameNode的元資料在JournalNode日誌上的存放位置(一般和zookeeper部署在一起) -->
<property>
	<name>dfs.namenode.shared.edits.dir</name>
	<value>qjournal://bigdata-01:8485;bigdata-02:8485;bigdata-03:8485/ns1</value>
</property>
<!-- 指定JournalNode在本地磁碟存放資料的位置 -->
<property>
	<name>dfs.journalnode.edits.dir</name>
	<value>/opt/modules/App/hadoop-2.5.0/data/journal</value>
</property>
<!--客戶端通過代理訪問namenode,訪問檔案系統,HDFS 客戶端與Active 節點通訊的Java 類,使用其確定Active 節點是否活躍  -->
<property>
	<name>dfs.client.failover.proxy.provider.ns1</name>
	<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>
<!--這是配置自動切換的方法,有多種使用方法,具體可以看官網,在文末會給地址,這裡是遠端登入殺死的方法  -->
<property>
	<name>dfs.ha.fencing.methods</name>
	<value>sshfence</value>     ----這個引數的值可以有多種,你也可以換成shell(/bin/true)試試,也是可以的,這個指令碼do nothing 返回0
</property>
<!-- 這個是使用sshfence隔離機制時才需要配置ssh免登陸 -->
<property>
	<name>dfs.ha.fencing.ssh.private-key-files</name>
	<value>/home/beifeng/.ssh/id_rsa</value>
</property>
<!-- 配置sshfence隔離機制超時時間,這個屬性同上,如果你是用指令碼的方法切換,這個應該是可以不配置的 -->
<property>
	<name>dfs.ha.fencing.ssh.connect-timeout</name>
	<value>30000</value>
</property>
<!-- 這個是開啟自動故障轉移,如果你沒有自動故障轉移,這個可以先不配 -->
<property>
	<name>dfs.ha.automatic-failover.enabled</name>
	<value>true</value>
</property>
</configuration>


然後是mapred-site.xml

<configuration>
<property>
        <name>mapreduce.framework.name</name>
        <value>yarn</value>
</property>
<property>
	<name>mapreduce.jobhistory.address</name>
	<value>bigdata-01:10020</value>
</property>
<property>
	<name>mapreduce.jobhistory.webapp.address</name>
	<value>bigdata-01:19888</value>
</property>
</configuration>

然後是yarn-site.xml
<configuration>
    <property>
        <name>yarn.nodemanager.aux-services</name>
        <value>mapreduce_shuffle</value>
    </property>
	<property>
        <name>yarn.resourcemanager.hostname</name>
        <value>bigdata-03</value>
    </property>
	<property>
        <name>yarn.log-aggregation-enable</name>
        <value>true</value>
    </property>
		<property>
        <name>yarn.log-aggregation.retain-seconds</name>
        <value>106800</value>
    </property>
</configuration>

然後slave裡面寫上自己的datanode的節點名稱(例如:以下)
bigdata-01
bigdata-02
bigdata-03
注:只要配置一臺,配置完了,把配置分發給其他機器,使用如下命令(scp命令):
提醒下,你傳送前可以把hadoop中的share/doc這個目錄下的東西刪掉,因為是些幫助文件,太大了,影響傳輸速度所以。。。rm -rf share/doc
scp -r hadoop2.5.0/ bigdata-02:/opt/modules/
scp -r hadoop2.5.0/ bigdata-03:/opt/modules/

-----------------好,配置就給到這裡-----------------------

2、啟動過程

1)首先zookeeper已經啟動好了吧(三臺都要啟動)
開啟命令 bin/zkServer.sh start
2)啟動三臺journalnode(這個是用來同步兩臺namenode的資料的)
sbin/hadoop-deamon.sh start journalnode
3)操作namenode(只要格式化一臺,另一臺同步,兩臺都格式化,你就做錯了!!)
格式化第一臺:bin/hdfs namenode -format
啟動剛格式化好的namenode:sbin/hadoop-deamon.sh start namenode
在第二臺機器上同步namenode的資料:bin/hdfs namenode -bootstrapStandby
啟動第二臺的namenode:sbin/hadoop-deamon.sh start namenode
4)檢視web(這裡應該兩臺都是stanby)
http://bigdata-01:50070
http://bigdata-01:50070
5)然後手動切換namenode狀態
手動切換namenode狀態(也可以在第一臺切換第二臺為active,畢竟一個叢集)
$ bin/hdfs haadmin -transitionToActive nn1 ##切換成active
$ bin/hdfs haadmin -transitionToStandby nn1 ##切換成standby
注: 如果不讓你切換的時候,bin/hdfs haadmin -transitionToActive nn2 --forceactive
也可以直接通過命令列檢視namenode狀態, bin/hdfs haadmin -getServiceState nn1

--------------------------到這裡你的手動故障轉移已經配置成功了-----------------------------------------

6)這時候就應該配置自動故障轉移了!(其實完整的配置我在上面已經給過了)
首先你要把你的叢集完整的關閉,一定要全關了!!
自動故障轉移的配置其實要在zookeeper上生成一個節點 hadoop-ha,這個是自動生成的,通過下面的命令生成:
bin/hdfs zkfc -formatZK
然後你登入zookeeper的客戶端,就是bin/zkCli.sh裡面通過 “ls /” 可以看到多了個節點
這時候講道理叢集應該是沒問題了!
你可以直接通過sbin/start-dfs.sh去啟動hdfs,預設會啟動zkfc的,其實就是一個自動故障轉移的程序,會在你的namenode存在的兩臺機器上有這麼一個節點。
等到完全啟動了之後,就可以kill掉active的namenode,你就會發現stanby的機器變成active,然後再去啟動那臺被你kill掉的namenode(啟動起來是stanby的狀態),然後你再去kill掉active,stanby的機器又會變成active,到此你的HA自動故障轉移已經完成了。
這是官網的幫助文件:http://hadoop.apache.org/docs/r2.5.2/hadoop-project-dist/hadoop-hdfs/HDFSHighAvailabilityWithQJM.html
後話:其實也可以做resourcemanager的HA,但是其實你能搭出namenode的HA,對於你來說,resourcemanager的HA就很簡單了。

====================分割線===========================

然後我們再來看下resourcemanager的HA
官網文件:http://hadoop.apache.org/docs/r2.5.2/hadoop-yarn/hadoop-yarn-site/ResourceManagerHA.html



所以當看到如上的圖時,應該想到resourcemanager的HA也是要依賴zookeeper的

叢集規劃

其實就跟上面一樣,只是我在第三臺機器上也啟動一個resourcemanager的備用節點

配置:

修改yarn-site.xml檔案

<!--啟用resourcemanager ha-->
<!--是否開啟RM ha,預設是開啟的-->
<property>
   <name>yarn.resourcemanager.ha.enabled</name>
   <value>true</value>
</property>
<!--宣告兩臺resourcemanager的地址-->
<property>
   <name>yarn.resourcemanager.cluster-id</name>
   <value>rmcluster</value>
</property>
<property>
   <name>yarn.resourcemanager.ha.rm-ids</name>
   <value>rm1,rm2</value>
</property>
<property>
   <name>yarn.resourcemanager.hostname.rm1</name>
   <value>bigdata-02</value>
</property>
<property>
   <name>yarn.resourcemanager.hostname.rm2</name>
   <value>bigdata-03</value>
</property>
 
<!--指定zookeeper叢集的地址--> 
<property>
   <name>yarn.resourcemanager.zk-address</name>
<value>bigdata-01:2181,bigdata-02:2181,bigdata-03:2181</value>
</property>
<!--啟用自動恢復,當任務進行一半,rm壞掉,就要啟動自動恢復,預設是false--> 
<property>
   <name>yarn.resourcemanager.recovery.enabled</name>
   <value>true</value>
</property>
 
<!--指定resourcemanager的狀態資訊儲存在zookeeper叢集,預設是存放在FileSystem裡面。--> 
<property>
   <name>yarn.resourcemanager.store.class</name>
   <value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value>
</property>

將yarn-site.xml檔案分發到其他主機上
$ scp yarn-site.xml bigdata-02:/opt/modules/hadoop-2.5.0/etc/hadoop/
$ scp yarn-site.xml bigdata-03:/opt/modules/hadoop-2.5.0/etc/hadoop/

啟動ResourceManager

在bigdata-02上:
sbin/start-yarn.sh

在bigdata-03上:
sbin/yarn-daemon.sh start resourcemanager


bigdata-01:
14168 DataNode
14338 JournalNode
15276 Jps
15241 NodeManager
14071 NameNode
12151 QuorumPeerMain
14485 DFSZKFailoverController

bigdata-02:
10094 ResourceManager
10183 NodeManager
10213 Jps
9212 DataNode
9279 JournalNode
9143 NameNode
8136 QuorumPeerMain

bigdata-03:
7177 Jps
6449 DataNode
5935 QuorumPeerMain
7147 ResourceManager
6512 JournalNode
7020 NodeManager

觀察web 8088埠


當PC02的ResourceManager是Active狀態的時候,訪問PC03的ResourceManager會自動跳轉到PC02的web頁面
測試HA的可用性


./yarn rmadmin -getServiceState rm1 ##檢視rm1的狀態
./yarn rmadmin -getServiceState rm2 ##檢視rm2的狀態
然後你可以提交一個job到yarn上面,當job執行一半(比如map執行了100%),然後kill -9 掉active的rm
這時候如果job還能夠正常執行完,結果也是正確的,證明你rm自動切換成功了,並且不影響你的job執行!!!
結束。。。。。。。。

後話:
其實正常情況下,主節點是不會直接壞掉的(除非機器壞掉,那我無話可說),往往是比如某個程序佔用cpu或者記憶體極大,有可能被linux直接kill掉
這種時候,ha並沒有那麼靈敏,就是說,不一定能馬上切換過去,可能有幾分鐘延遲,所以我們應該做的是避免一些主節點掛掉的情況。
所以可以使用spark或者storm做預警系統,當hadoop的日誌檔案裡面出現warning的時候,能夠實時報警(比如向維護人員發簡訊,發郵件之類的功能)
在事故發生之前,處理可能發生的故障!

再次宣告,如果本文有什麼說的不對之處,希望大神們可以指出!!謝謝各位~