為什么要搭建NameNode HA坯墨?
因?yàn)閔adoop中NameNode存在單節(jié)點(diǎn)故障堤魁。hadoop1.x 中的Secondarynamenode僅僅使用了合并namenode中的edit文件和fsimage文件(并做備份)精置,防止edit文件過(guò)大丧慈,NameNode重啟時(shí)會(huì)讀取大量的編輯文件,導(dǎo)致啟動(dòng)很慢玩祟。但是它只是namenode的一個(gè)協(xié)助節(jié)點(diǎn)靡馁,在namenode出現(xiàn)故障后欲鹏,不能由它來(lái)接手namenode。
NameNode HA原理
- 首先由兩個(gè)namenode節(jié)點(diǎn)奈嘿,為了保持兩個(gè)NameNode內(nèi)存中存儲(chǔ)文件系統(tǒng)的系統(tǒng)元數(shù)據(jù)要同步(fsimage和edit等文件)貌虾。所以通過(guò)配置Quorum Journal Node節(jié)點(diǎn),一個(gè)namenode節(jié)點(diǎn)向JN節(jié)點(diǎn)寫入要共享的數(shù)據(jù)裙犹,另外一個(gè)namenode節(jié)點(diǎn)從JN節(jié)點(diǎn)讀數(shù)據(jù)。為了保證共享數(shù)據(jù)的安全性衔憨,JN節(jié)點(diǎn)也為多個(gè)叶圃。
- 如果同時(shí)又兩個(gè)namenode節(jié)點(diǎn)對(duì)外提供訪問(wèn),會(huì)導(dǎo)致數(shù)據(jù)的不一致性践图。所以要保證一個(gè)為active狀態(tài)掺冠,另外一個(gè)為standby(備用)狀態(tài)。同時(shí)當(dāng)active宕掉,為了standby能夠迅速轉(zhuǎn)換為active狀態(tài)德崭,所以datanode需要同時(shí)向這兩個(gè)namenode節(jié)點(diǎn)發(fā)送數(shù)據(jù)位置信息和心跳斥黑。
- 需要配置隔離機(jī)制來(lái)保證有且僅有一個(gè)namenode對(duì)外提供服務(wù)。防止裂腦(兩個(gè)namenode節(jié)點(diǎn)都可以命令datanode)的發(fā)生眉厨。
- 客戶端不知道向哪一個(gè)namenode為活動(dòng)狀態(tài)锌奴,所以也不知道向哪一個(gè)節(jié)點(diǎn)發(fā)送請(qǐng)求。需要在前面加一層代理憾股,讓代理來(lái)決定訪問(wèn)哪一臺(tái)機(jī)器鹿蜀。
- 前面的問(wèn)題解決后,active和standby之前的切換必須手動(dòng)服球。結(jié)合Zookeeper集群中Zookeeper faileover controller(ZKFC)故障轉(zhuǎn)移監(jiān)控器 來(lái)監(jiān)控節(jié)點(diǎn)并自動(dòng)的將standby切換到active茴恰。
HA配置步驟
- 對(duì)hdfs-site.xml文件進(jìn)行配置,并分發(fā)到其余兩個(gè)節(jié)點(diǎn)
<!-- 為這個(gè)namenode集群設(shè)置一個(gè)命名-->
<property>
<name>dfs.nameservices</name>
<value>ns1</value>
</property>
<!-- 這個(gè)nameservices節(jié)點(diǎn)下namenode的命名 -->
<property>
<name>dfs.ha.namenodes.ns1</name>
<value>nn1,nn2</value>
</property>
<!-- 配置兩個(gè)namenode節(jié)點(diǎn)的位置 -->
<property>
<name>dfs.namenode.rpc-address.ns1.nn1</name>
<value>bigdata-00:8020</value>
</property>
<property>
<name>dfs.namenode.rpc-address.ns1.nn2</name>
<value>bigdata-01:8020</value>
</property>
<!-- 配置兩臺(tái)namenode外部web UI 端口 -->
<property>
<name>dfs.namenode.http-address.ns1.nn1</name>
<value>bigdata-00:50070</value>
<property>
</property>
</property>
<property>
<name>dfs.namenode.http-address.ns1.nn2</name>
<value>bigdata-01:50070</value>
</property>
<!-- 編輯日志文件存儲(chǔ)的節(jié)點(diǎn)(JN) -->
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://bigdata-00:8485;bigdata-01:8485;bigdata-02:8485/ns1</value>
</property>
<!-- 各個(gè)JN節(jié)點(diǎn)存放日志文件位置 -->
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/opt/app/hadoop-2.5.0/data/dfs/jn</value>
</property>
<!-- 配置HDFS客戶端去連接active namenode節(jié)點(diǎn) -->
<property>
<name>dfs.client.failover.proxy.provider.ns1</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</va
lue>
</property>
<!-- 配置隔離機(jī)制-->
<property>
<name>dfs.ha.fencing.methods</name>
<value>sshfence</value>
</property>
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/home/wulei/.ssh/id_rsa</value>
</property>
- 對(duì)core-site.xml文件進(jìn)行配置
<!-- 指定namenode存儲(chǔ)元數(shù)據(jù)和日志文件的目錄 -->
<property>
<name>hadoop.tmp.dir</name>
<value>/opt/app/hadoop-2.5.0/data/tmp</value>
</property>
<!-- 配置nameservices作為文件系統(tǒng)-->
<property>
<name>fs.defaultFS</name>
<value>hdfs://ns1</value>
</property>
- 每個(gè)節(jié)點(diǎn)啟動(dòng)journalnode和namenode服務(wù)
-
三個(gè)節(jié)點(diǎn)啟動(dòng)journalnode服務(wù)斩熊。
jn1.png - 對(duì)其中一個(gè)namenode進(jìn)行格式化
[wulei@bigdata-00 hadoop-2.5.0]$ bin/hdfs namenode -format
- 啟動(dòng)namenode服務(wù),查看節(jié)點(diǎn)狀態(tài)
[wulei@bigdata-00 hadoop-2.5.0]$ sbin/hadoop-daemon.sh start namenode
starting namenode, logging to /opt/app/hadoop-2.5.0/logs/hadoop-wulei-namenode-bigdata-00.out
[wulei@bigdata-00 hadoop-2.5.0]$ jps
5095 JournalNode
5338 NameNode
5406 Jps
-
把nn1的fsimage文件同步到nn2上,再啟動(dòng)nn2中的namenode查看狀態(tài)往枣。
nn2.png
nn3.png - 手動(dòng)切換nn1的狀態(tài)為active,并啟動(dòng)三個(gè)datanode節(jié)點(diǎn)
$ bin/hdfs haadmin -transitionToActive nn1
- 測(cè)試兩個(gè)namenode之間數(shù)據(jù)是否能同步(在active節(jié)點(diǎn)上創(chuàng)建目錄粉渠,然后結(jié)束這個(gè)active nemenode節(jié)點(diǎn)婉商,把另外一個(gè)standby節(jié)點(diǎn)轉(zhuǎn)換為active節(jié)點(diǎn),看是否能訪問(wèn)目錄)
[wulei@bigdata-00 hadoop-2.5.0]$ bin/hdfs dfs -mkdir /test
[wulei@bigdata-00 hadoop-2.5.0]$ bin/hdfs dfs -ls /
Found 1 items
drwxr-xr-x - wulei supergroup 0 2016-10-21 10:31 /test
[wulei@bigdata-01 hadoop-2.5.0]$ bin/hdfs haadmin -transitionToActive nn2 --forceactive
[wulei@bigdata-01 hadoop-2.5.0]$ bin/hdfs dfs -ls /
Found 1 items
drwxr-xr-x - wulei supergroup 0 2016-10-21 10:31 /test
- 借助zookeeper集群來(lái)配置namenode HA自動(dòng)故障轉(zhuǎn)移
- 在部署好zookeeper集群后并啟動(dòng)進(jìn)程
[wulei@bigdata-00 hadoop-2.5.0]$ jps
9155 QuorumPeerMain
[wulei@bigdata-01 hadoop-2.5.0]$ jps
5195 QuorumPeerMain
[wulei@bigdata-02 hadoop-2.5.0]$ jps
3886 QuorumPeerMain
- 對(duì)文件增加配置渣叛,并分發(fā)給其他節(jié)點(diǎn)
hdfs-site.xml
<!-- 啟動(dòng)自動(dòng)故障轉(zhuǎn)移功能-->
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
core-site.xml
<!-- zookeeper高可用的主機(jī)和端口-->
<property>
<name>ha.zookeeper.quorum</name>
<value>bigdata-00:2181,bigdata-01:2181,bigdata-02:2181</value>
</property>
- 初始化zookeeper HA狀態(tài)丈秩,生成znode節(jié)點(diǎn)(每個(gè)節(jié)點(diǎn)對(duì)應(yīng)一個(gè)目錄)
[wulei@bigdata-00 hadoop-2.5.0]$ bin/hdfs zkfc -formatZK
- 客戶端連接zookeeper,查看節(jié)點(diǎn)是否創(chuàng)建成功
[wulei@bigdata-00 hadoop-2.5.0]$ zookeeper-3.4.6/bin/zkCli.sh
[zk: localhost:2181(CONNECTED) 3] ls /
[zookeeper, hadoop-ha]
[zk: localhost:2181(CONNECTED) 4] ls /hadoop-ha
[ns1]
- 啟動(dòng)集群服務(wù)進(jìn)程后淳衙,在兩個(gè)namonode節(jié)點(diǎn)上啟動(dòng)ZKFC服務(wù)
[wulei@bigdata-00 hadoop-2.5.0]$ sbin/hadoop-daemon.sh start zkfc
[wulei@bigdata-01 hadoop-2.5.0]$ sbin/hadoop-daemon.sh start zkfc
-
查看兩個(gè)namenode節(jié)點(diǎn)狀態(tài)蘑秽。可以發(fā)現(xiàn)已經(jīng)通過(guò)選舉自動(dòng)選出了一個(gè)active箫攀,另外一個(gè)作為standby肠牲。
zk1.png
zk2.png - 啟動(dòng)resourcemanager和nodemanager。在active上運(yùn)行mapreduce程序靴跛,中途關(guān)閉active的節(jié)點(diǎn)后缀雳,查看程序運(yùn)行情況和nn2的狀態(tài)。會(huì)發(fā)現(xiàn)程序任然可以執(zhí)行梢睛,為standby狀態(tài)的節(jié)點(diǎn)自動(dòng)轉(zhuǎn)換為active肥印。
[wulei@bigdata-00 hadoop-2.5.0]$ bin/yarn jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.5.0.jar wordcount /test/in/ /test/out