為什么要搭建NameNode HA?
因為hadoop中NameNode存在單節點故障。hadoop1.x 中的Secondarynamenode僅僅使用了合并namenode中的edit文件和fsimage文件(并做備份),防止edit文件過大,NameNode重啟時會讀取大量的編輯文件,導致啟動很慢。但是它只是namenode的一個協助節點,在namenode出現故障后,不能由它來接手namenode。
NameNode HA原理
- 首先由兩個namenode節點,為了保持兩個NameNode內存中存儲文件系統的系統元數據要同步(fsimage和edit等文件)。所以通過配置Quorum Journal Node節點,一個namenode節點向JN節點寫入要共享的數據,另外一個namenode節點從JN節點讀數據。為了保證共享數據的安全性,JN節點也為多個。
- 如果同時又兩個namenode節點對外提供訪問,會導致數據的不一致性。所以要保證一個為active狀態,另外一個為standby(備用)狀態。同時當active宕掉,為了standby能夠迅速轉換為active狀態,所以datanode需要同時向這兩個namenode節點發送數據位置信息和心跳。
- 需要配置隔離機制來保證有且僅有一個namenode對外提供服務。防止裂腦(兩個namenode節點都可以命令datanode)的發生。
- 客戶端不知道向哪一個namenode為活動狀態,所以也不知道向哪一個節點發送請求。需要在前面加一層代理,讓代理來決定訪問哪一臺機器。
- 前面的問題解決后,active和standby之前的切換必須手動。結合Zookeeper集群中Zookeeper faileover controller(ZKFC)故障轉移監控器 來監控節點并自動的將standby切換到active。
HA配置步驟
- 對hdfs-site.xml文件進行配置,并分發到其余兩個節點
<!-- 為這個namenode集群設置一個命名-->
<property>
<name>dfs.nameservices</name>
<value>ns1</value>
</property>
<!-- 這個nameservices節點下namenode的命名 -->
<property>
<name>dfs.ha.namenodes.ns1</name>
<value>nn1,nn2</value>
</property>
<!-- 配置兩個namenode節點的位置 -->
<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>
<!-- 配置兩臺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>
<!-- 編輯日志文件存儲的節點(JN) -->
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://bigdata-00:8485;bigdata-01:8485;bigdata-02:8485/ns1</value>
</property>
<!-- 各個JN節點存放日志文件位置 -->
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/opt/app/hadoop-2.5.0/data/dfs/jn</value>
</property>
<!-- 配置HDFS客戶端去連接active namenode節點 -->
<property>
<name>dfs.client.failover.proxy.provider.ns1</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</va
lue>
</property>
<!-- 配置隔離機制-->
<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>
- 對core-site.xml文件進行配置
<!-- 指定namenode存儲元數據和日志文件的目錄 -->
<property>
<name>hadoop.tmp.dir</name>
<value>/opt/app/hadoop-2.5.0/data/tmp</value>
</property>
<!-- 配置nameservices作為文件系統-->
<property>
<name>fs.defaultFS</name>
<value>hdfs://ns1</value>
</property>
- 每個節點啟動journalnode和namenode服務
-
三個節點啟動journalnode服務。
jn1.png - 對其中一個namenode進行格式化
[wulei@bigdata-00 hadoop-2.5.0]$ bin/hdfs namenode -format
- 啟動namenode服務,查看節點狀態
[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上,再啟動nn2中的namenode查看狀態。
nn2.png
nn3.png - 手動切換nn1的狀態為active,并啟動三個datanode節點
$ bin/hdfs haadmin -transitionToActive nn1
- 測試兩個namenode之間數據是否能同步(在active節點上創建目錄,然后結束這個active nemenode節點,把另外一個standby節點轉換為active節點,看是否能訪問目錄)
[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集群來配置namenode HA自動故障轉移
- 在部署好zookeeper集群后并啟動進程
[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
- 對文件增加配置,并分發給其他節點
hdfs-site.xml
<!-- 啟動自動故障轉移功能-->
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
core-site.xml
<!-- zookeeper高可用的主機和端口-->
<property>
<name>ha.zookeeper.quorum</name>
<value>bigdata-00:2181,bigdata-01:2181,bigdata-02:2181</value>
</property>
- 初始化zookeeper HA狀態,生成znode節點(每個節點對應一個目錄)
[wulei@bigdata-00 hadoop-2.5.0]$ bin/hdfs zkfc -formatZK
- 客戶端連接zookeeper,查看節點是否創建成功
[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]
- 啟動集群服務進程后,在兩個namonode節點上啟動ZKFC服務
[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
-
查看兩個namenode節點狀態。可以發現已經通過選舉自動選出了一個active,另外一個作為standby。
zk1.png
zk2.png - 啟動resourcemanager和nodemanager。在active上運行mapreduce程序,中途關閉active的節點后,查看程序運行情況和nn2的狀態。會發現程序任然可以執行,為standby狀態的節點自動轉換為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