文章目錄
一、HA概述
HA
(High Available
)即高可用(7*24小時不中斷服務),實現高可用最關鍵的策略就是消除單點故障。HA
嚴格地來說應該分成各個組件的HA
機制,HDFS
的HA
和YARN
的HA
。
Hadoop2.0
之前,在HDFS
集羣中NameNode
存在單點故障(SPOF
)。NameNode
主要在以下兩個方面影響HDFS
集羣:
NameNode
機器發生意外,如宕機,集羣將無法使用,直到管理員重啓NameNode
機器需要升級,包括軟件、硬件升級,此時集羣也將無法使用
HDFS HA
功能通過配置Active/Standby
兩個NameNodes
實現在集羣中對NameNode
的熱備來解決上述問題。如果出現故障,如機器崩潰或機器需要升級維護,這時可通過此種方式將NameNode
很快的切換到另外一臺機器。
二、HDFS-HA工作機制
通過雙NameNode
消除單點故障
2.1 HDFS-HA工作要點
- 元數據管理方式需要改變
內存中各自保存一份元數據,Edit
日誌只有Active
狀態的NameNode
節點纔可以做寫操作,兩個NameNode
都可以讀取Edits
。共享的Edits
放在一個共享存儲中管理(qjournal
和NFS
兩個主流實現) - 需要一個狀態管理功能模塊
實現了一個zkfailover
常駐在每一個NameNode
所在的節點,每一個zkfailover
負責監控自己所在NameNode
節點,利用ZooKeeper
進行狀態標識,當需要進行狀態切換時,由zkfailover
來負責切換,切換時需要防止brain split
現象的發生。 - 必須保證兩個
NameNode
之間能夠ssh
無密碼登錄 - 隔離(
Fence
),即同一時刻僅僅有一個NameNode
對外提供服務
2.2 HDFS-HA自動故障轉移工作機制
使用命令hdfs haadmin failover
手動進行故障轉移,在該模式下,即使現役NameNode
已經失效,系統也不會自動從現役NameNode
轉移到待機NameNode
,下面學習如何配置部署HA
自動進行故障轉移。
自動故障轉移爲HDFS
部署增加了兩個新組件:ZooKeeper
和ZKFailoverController
(ZKFC
)進程。
如圖所示:ZooKeeper
是維護少量協調數據,通知客戶端這些數據的改變和監視客戶端故障的高可用服務。HA
的自動故障轉移依賴於ZooKeeper
的以下功能:
①故障檢測 :集羣中的每個NameNode
在ZooKeeper
中維護了一個持久會話,如果機器崩潰,ZooKeeper
中的會話將終止,ZooKeeper
通知另一個DataNode
需要觸發故障轉移。
②現役NameNode
選擇: ZooKeeper
提供了一個簡單的機制用於唯一的選擇一個節點爲active
狀態。如果目前現役NameNode
崩潰,另一個節點可能從ZooKeeper
獲得特殊的排外鎖以表明它應該稱爲現役NameNode
。
ZKFC
是自動故障轉移的另一個新組件,是ZooKeeper
的客戶端,也監視和管理NameNode
的狀態。每個運行NameNode
的主機也運行一個ZKFC
進程,ZKFC
負責:
①健康監測:ZKFC
使用一個健康檢查命令定期地ping
與之在相同主機的NameNode
,只要該NameNode
及時地回覆健康狀態,ZKFC
認爲該節點是健康的。如果該節點崩潰,凍結或進入不健康狀態,健康監測器標識該節點爲非健康的。
②ZooKeeper會話管理: 當本地NameNode
是健康的,ZKFC
保持一個在ZooKeeper
中打開的會話。如果本地NameNode
處於active
狀態,ZKFC
也保持一個特殊的znode
鎖,該鎖使用了ZooKeeper
對短暫節點的支持,如果會話終止,鎖節點將自動刪除。
③基於ZooKeeper的選擇: 如果本地NameNode
是健康的,且ZKFC
發現沒有其它的節點當前持有znode
鎖,它將爲自己獲取該鎖。如果成功,則它已經贏得了選擇,並負責運行故障轉移進程以使它的本地NameNode
爲Active
。故障轉移進程與前面描述的手動故障轉移相似,首先如果必要保護之前的現役NameNode
,然後本地NameNode
轉換爲Active
狀態。
三、HDFS-HA集羣配置
3.1 環境基礎
ZooKeeper
集羣和完全分佈運行模式Hadoop
集羣的搭建。
3.2 集羣規劃
JournalNode:兩個NameNode
爲了數據同步,會通過一組稱作JournalNodes
的獨立進程進行相互通信。
hadoop100 | hadoop101 | hadoop1042 |
---|---|---|
NameNode | NameNode | |
JournalNode | JournalNode | JournalNode |
DataNode | DataNode | DataNode |
ZooKeeper | ZK | ZK |
ResourceManager | ResourceManager | SecondaryNameNode |
NodeManager | NodeManager | NodeManager |
3.3 配置HDFS-HA集羣
①拷貝之前的Hadoop
文件到HA
文件夾
[root@hadoop100 hadoop-2.7.2]# cp -r hadoop-2.7.2/ /opt/module/HA/
②配置core-site.xml
<!-- 指定HDFS中NameNode的地址 -->
<property>
<name>fs.defaultFS</name>
<value>hdfs://mycluster</value>
</property>
<!-- 指定Hadoop運行時產生文件的存儲目錄 -->
<property>
<name>hadoop.tmp.dir</name>
<value>/opt/module/HA/hadoop-2.7.2/data/tmp</value>
</property>
③配置hdfs-site.xml
<!-- 完全分佈式集羣名稱 -->
<property>
<name>dfs.nameservices</name>
<value>mycluster</value>
</property>
<!--指定NameNode節點的名稱-->
<property>
<name>dfs.ha.namenodes.mycluster</name>
<value>nn1,nn2</value>
</property>
<!-- nn1的RPC通信地址 -->
<property>
<name>dfs.namenode.rpc-address.mycluster.nn1</name>
<value>hadoop100:9000</value>
</property>
<!-- nn2的RPC通信地址 -->
<property>
<name>dfs.namenode.rpc-address.mycluster.nn2</name>
<value>hadoop101:9000</value>
</property>
<!-- nn1的http通信地址 -->
<property>
<name>dfs.namenode.http-address.mycluster.nn1</name>
<value>hadoop100:50070</value>
</property>
<!-- nn2的http通信地址 -->
<property>
<name>dfs.namenode.http-address.mycluster.nn2</name>
<value>hadoop101:50070</value>
</property>
<!-- 指定NameNode元數據在JournalNode上的存放位置 -->
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://hadoop100:8485;hadoop101:8485;hadoop102:8485/mycluster</value>
</property>
<!-- 配置隔離機制,即同一時刻只能有一臺服務器對外響應 -->
<property>
<name>dfs.ha.fencing.methods</name>
<value>sshfence</value>
</property>
<!-- 使用隔離機制時需要ssh無祕鑰登錄-->
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/root/.ssh/id_rsa</value>
</property>
<!-- 聲明journalnode服務器存儲目錄-->
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/opt/module/HA/hadoop-2.7.2/data/jn</value>
</property>
<!-- 關閉權限檢查-->
<property>
<name>dfs.permissions.enable</name>
<value>false</value>
</property>
<!-- 訪問代理類:client,mycluster,active配置失敗自動切換實現方式-->
<property>
<name>dfs.client.failover.proxy.provider.mycluster</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>
④分發HA
[root@hadoop100 HA]# xsync ./HA/
3.4 啓動HDFS-HA集羣
①在各個節點上啓動JournalNode
服務
[root@hadoop100 hadoop-2.7.2]# sbin/hadoop-daemon.sh start journalnode
②在nn1
上,對其進行格式化並啓動
[root@hadoop100 hadoop-2.7.2]# bin/hdfs namenode -format
[root@hadoop100 hadoop-2.7.2]# sbin/hadoop-daemon.sh start namenode
③在nn2
上,同步nn1
的元數據信息
[root@hadoop101 hadoop-2.7.2]# bin/hdfs namenode -bootstrapStandby
④啓動nn2
[root@hadoop101 hadoop-2.7.2]# sbin/hadoop-daemon.sh start namenod
⑤將nn1
切換爲Active
[root@hadoop100 hadoop-2.7.2]# bin/hdfs haadmin -transitionToActive nn1
⑥查看是否Active
[root@hadoop100 hadoop-2.7.2]# bin/hdfs haadmin -getServiceState nn1
3.5 配置HDFS-HA自動故障轉移
①具體配置
【hdfs-site.xml
】
<!--配置HDFS-HA自動故障轉移-->
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
【core-site.xml
】
<property>
<name>ha.zookeeper.quorum</name>
<value>hadoop102:2181,hadoop103:2181,hadoop104:2181</value>
</property>
②關閉所有HDFS
服務
[root@hadoop100 hadoop-2.7.2]# sbin/stop-dfs.sh
③啓動ZooKeeper
集羣
[root@hadoop100 hadoop-2.7.2]# bin/zkServer.sh start
[root@hadoop100 hadoop-2.7.2]# cat zkServer.sh
#!/bin/bash
if (($#==0))
then
exit 1;
fi
for i in hadoop100 hadoop101 hadoop102
do
echo Starting zk in $i
ssh $i "source /etc/profile && /opt/module/zookeeper-3.4.10/bin/zkServer.sh $1" > /dev/null
done
④初始化HA
在Zookeeper
中狀態
[root@hadoop100 hadoop-2.7.2]# bin/hdfs zkfc -formatZK
⑤啓動HDFS
服務
[root@hadoop100 hadoop-2.7.2]# sbin/start-dfs.sh
⑥驗證:殺死NameNode
進程
[root@hadoop100 hadoop-2.7.2]# kill -9 2883
殺死nn1
後,此時NamaNode
已經切換爲nn2
3.6 故障轉移失敗
通過查看zkfc
的日誌,可以發現沒有fuser
命令,安裝fuser
命令後重啓HDFS
後即能完成故障轉移
四、YARN-HA配置
4.1YARN-HA工作機制
4.2配置YARN-HA集羣
規劃集羣:
hadoop100 | hadoop101 | hadoop1042 |
---|---|---|
NameNode | NameNode | |
JournalNode | JournalNode | JournalNode |
DataNode | DataNode | DataNode |
ZooKeeper | ZK | ZK |
ResourceManager | ResourceManager | SecondaryNameNode |
NodeManager | NodeManager | NodeManager |
具體配置:
①配置【yarn-site.xml
】
<!-- Reducer獲取數據的方式 -->
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<!--啓用resourcemanager ha-->
<property>
<name>yarn.resourcemanager.ha.enabled</name>
<value>true</value>
</property>
<!--聲明兩臺resourcemanager的地址-->
<property>
<name>yarn.resourcemanager.cluster-id</name>
<value>cluster-yarn1</value>
</property>
<property>
<name>yarn.resourcemanager.ha.rm-ids</name>
<value>rm1,rm2</value>
</property>
<property>
<name>yarn.resourcemanager.hostname.rm1</name>
<value>hadoop100</value>
</property>
<property>
<name>yarn.resourcemanager.hostname.rm2</name>
<value>hadoop101</value>
</property>
<!--指定zookeeper集羣的地址-->
<property>
<name>yarn.resourcemanager.zk-address</name>
<value>hadoop100:2181,hadoop101:2181,hadoop102:2181</value>
</property>
<!--啓用自動恢復-->
<property>
<name>yarn.resourcemanager.recovery.enabled</name>
<value>true</value>
</property>
<!--指定resourcemanager的狀態信息存儲在zookeeper集羣-->
<property>
<name>yarn.resourcemanager.store.class</name>
<value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value>
</property>
②同步更新其他節點的配置信息
③啓動YARN
[root@hadoop100 hadoop-2.7.2]# sbin/start-yarn.sh
[root@hadoop101 hadoop-2.7.2]# sbin/yarn-daemon.sh start resourcemanager
[root@hadoop101 hadoop-2.7.2]# bin/yarn rmadmin -getServiceState rm1
active
[root@hadoop101 hadoop-2.7.2]# bin/yarn rmadmin -getServiceState rm2
standby