Hadoop HA 高可用

第一章 HA 概述

(1)所謂 HA(High Availablity),即高可用(7*24 小時不中斷服務)。

(2)實現高可用最關鍵的策略是消除單點故障。HA 嚴格來說應該分成各個組件的 HA機制:HDFS 的 HA 和 YARN 的 HA。

(3)NameNode 主要在以下兩個方面影響 HDFS 集羣

  • NameNode 機器發生意外,如宕機,集羣將無法使用,直到管理員重啓
  • NameNode 機器需要升級,包括軟件、硬件升級,此時集羣也將無法使用

HDFS HA 功能通過配置多個 NameNodes(Active/Standby)實現在集羣中對 NameNode 的熱備來解決上述問題。如果出現故障,如機器崩潰或機器需要升級維護,這時可通過此種方式將 NameNode 很快的切換到另外一臺機器。

第二章 HDFS-HA 集羣搭建

當前 HDFS 集羣的規劃

hadoop102 hadoop103 hadoop104
NameNode   Secondarynamenode
DataNode DataNode DataNode

HA 的主要目的是消除 namenode 的單點故障,需要將 hdfs 集羣規劃成以下模樣

hadoop102 hadoop103 hadoop104
NameNode NameNode NameNode
DataNode DataNode DataNode

2.1 HDFS-HA 核心問題

1)怎麼保證三臺 namenode 的數據一致

  •  a.Fsimage:讓一臺 nn 生成數據,讓其他機器 nn 同步
  •  b.Edits:需要引進新的模塊 JournalNode 來保證 edtis 的文件的數據一致性

https://www.cnblogs.com/wkfvawl/p/15475122.html#scroller-28

2)怎麼讓同時只有一臺 nn 是 active,其他所有是 standby 的

  • a.手動分配
  • b.自動分配

3)2nn 在 ha 架構中並不存在,定期合併 fsimage 和 edtis 的活誰來幹

由 standby 的 nn 來幹

4)如果 nn 真的發生了問題,怎麼讓其他的 nn 上位幹活

  •  a.手動故障轉移
  •  b.自動故障轉移

第三章 HDFS-HA 手動模式

3.1 環境準備

(1)修改 IP
(2)修改主機名及主機名和 IP 地址的映射
(3)關閉防火牆
(4)ssh 免密登錄
(5)安裝 JDK,配置環境變量等

3.2 規劃集羣

hadoop102 hadoop103 hadoop104
NameNode NameNode NameNode
JournalNode JournalNode JournalNode
DataNode DataNode DataNode


3.3 配置 HDFS-HA 集羣

1)官方地址:http://hadoop.apache.org/

2)在 opt 目錄下創建一個 ha 文件夾

[atguigu@hadoop102 ~]$ cd /opt
[atguigu@hadoop102 opt]$ sudo mkdir ha
[atguigu@hadoop102 opt]$ sudo chown atguigu:atguigu /opt/ha


3)將/opt/module/下的 hadoop-3.1.3 拷貝到/opt/ha 目錄下(記得刪除 data 和 log 目錄)

[atguigu@hadoop102 opt]$ cp -r /opt/module/hadoop-3.1.3 /opt/ha/

4)配置 core-site.xml

<configuration>
<!-- 把多個 NameNode 的地址組裝成一個集羣 mycluster -->
 <property>
 <name>fs.defaultFS</name>
 <value>hdfs://mycluster</value>
 </property>
<!-- 指定 hadoop 運行時產生文件的存儲目錄 -->
 <property>
 <name>hadoop.tmp.dir</name>
 <value>/opt/ha/hadoop-3.1.3/data</value>
 </property>
</configuration>

5)配置 hdfs-site.xml

<configuration>
<!-- NameNode 數據存儲目錄 -->
 <property>
 <name>dfs.namenode.name.dir</name>
 <value>file://${hadoop.tmp.dir}/name</value>
 </property>
<!-- DataNode 數據存儲目錄 -->
 <property>
 <name>dfs.datanode.data.dir</name>
 <value>file://${hadoop.tmp.dir}/data</value>
 </property>
<!-- JournalNode 數據存儲目錄 -->
 <property>
 <name>dfs.journalnode.edits.dir</name>
 <value>${hadoop.tmp.dir}/jn</value>
 </property>
<!-- 完全分佈式集羣名稱 -->
 <property>
 <name>dfs.nameservices</name>
 <value>mycluster</value>
 </property>
<!-- 集羣中 NameNode 節點都有哪些 -->
 <property>
 <name>dfs.ha.namenodes.mycluster</name>
 <value>nn1,nn2,nn3</value>
 </property>
<!-- NameNode 的 RPC 通信地址 -->
 <property>
 <name>dfs.namenode.rpc-address.mycluster.nn1</name>
 <value>hadoop102:8020</value>
 </property>
 <property>
 <name>dfs.namenode.rpc-address.mycluster.nn2</name>
 <value>hadoop103:8020</value>
 </property>
 <property>
 <name>dfs.namenode.rpc-address.mycluster.nn3</name>
 <value>hadoop104:8020</value>
 </property>
<!-- NameNode 的 http 通信地址 -->
 <property>
 <name>dfs.namenode.http-address.mycluster.nn1</name>
 <value>hadoop102:9870</value>
 </property>
 <property>
 <name>dfs.namenode.http-address.mycluster.nn2</name>
 <value>hadoop103:9870</value>
 </property>
 <property>
 <name>dfs.namenode.http-address.mycluster.nn3</name>
 <value>hadoop104:9870</value>
 </property>
<!-- 指定 NameNode 元數據在 JournalNode 上的存放位置 -->
 <property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://hadoop102:8485;hadoop103:8485;hadoop104:8485/myclus
ter</value>
 </property>
<!-- 訪問代理類:client 用於確定哪個 NameNode 爲 Active -->
 <property>
 <name>dfs.client.failover.proxy.provider.mycluster</name>
 
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyP
rovider</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>/home/atguigu/.ssh/id_rsa</value>
 </property>
</configuration>

6)分發配置好的 hadoop 環境到其他節點

3.4 啓動 HDFS-HA 集羣

1)將 HADOOP_HOME 環境變量更改到 HA 目錄(三臺機器)

[atguigu@hadoop102 ~]$ sudo vim /etc/profile.d/my_env.sh

將 HADOOP_HOME 部分改爲如下

#HADOOP_HOME
export HADOOP_HOME=/opt/ha/hadoop-3.1.3
export PATH=$PATH:$HADOOP_HOME/bin
export PATH=$PATH:$HADOOP_HOME/sbin

 去三臺機器上 source 環境變量

[atguigu@hadoop102 ~]$source /etc/profile

2)在各個 JournalNode 節點上,輸入以下命令啓動 journalnode 服務

[atguigu@hadoop102 ~]$ hdfs --daemon start journalnode
[atguigu@hadoop103 ~]$ hdfs --daemon start journalnode
[atguigu@hadoop104 ~]$ hdfs --daemon start journalnode

3)在[nn1]上,對其進行格式化,並啓動

[atguigu@hadoop102 ~]$ hdfs namenode -format
[atguigu@hadoop102 ~]$ hdfs --daemon start namenode

4)在[nn2]和[nn3]上,同步 nn1 的元數據信息

[atguigu@hadoop103 ~]$ hdfs namenode -bootstrapStandby
[atguigu@hadoop104 ~]$ hdfs namenode -bootstrapStandby

5)啓動[nn2]和[nn3]

[atguigu@hadoop103 ~]$ hdfs --daemon start namenode
[atguigu@hadoop104 ~]$ hdfs --daemon start namenode

6)查看 web 頁面顯示

圖 hadoop102(standby)

圖 hadoop103(standby)

圖 hadoop104(standby)

7)在所有節點上,啓動 datanode

[atguigu@hadoop102 ~]$ hdfs --daemon start datanode
[atguigu@hadoop103 ~]$ hdfs --daemon start datanode
[atguigu@hadoop104 ~]$ hdfs --daemon start datanode

8)將[nn1]切換爲 Active

[atguigu@hadoop102 ~]$ hdfs haadmin -transitionToActive nn1

9)查看是否 Active

[atguigu@hadoop102 ~]$ hdfs haadmin -getServiceState nn1

第四章 HDFS-HA 自動模式

4.1 HDFS-HA 自動故障轉移工作機制

自動故障轉移爲 HDFS 部署增加了兩個新組件:ZooKeeper 和 ZKFailoverController(ZKFC)進程,如圖所示。ZooKeeper 是維護少量協調數據,通知客戶端這些數據的改變和監視客戶端故障的高可用服務。

 

 

4.2 HDFS-HA 自動故障轉移的集羣規劃

hadoop102 hadoop103 hadoop104
NameNode NameNode NameNode
JournalNode JournalNode JournalNode
DataNode DataNode DataNode
Zookeeper Zookeeper Zookeeper
ZKFC ZKFC ZKFC


4.3 配置 HDFS-HA 自動故障轉移

1)具體配置
(1)在 hdfs-site.xml 中增加

<!-- 啓用 nn 故障自動轉移 -->
<property>
  <name>dfs.ha.automatic-failover.enabled</name>
  <value>true</value>
</property>

(2)在 core-site.xml 文件中增加

<!-- 指定 zkfc 要連接的 zkServer 地址 -->
<property>
  <name>ha.zookeeper.quorum</name>
  <value>hadoop102:2181,hadoop103:2181,hadoop104:2181</value>
</property>

2181:zookeeper對Client端提供服務的端口。
(3)修改後分發配置文件

[atguigu@hadoop102 etc]$ pwd
/opt/ha/hadoop-3.1.3/etc
[atguigu@hadoop102 etc]$ xsync hadoop/

2)啓動
(1)關閉所有 HDFS 服務:

[atguigu@hadoop102 ~]$ stop-dfs.sh

(2)啓動 Zookeeper 集羣:

[atguigu@hadoop102 ~]$ zkServer.sh start
[atguigu@hadoop103 ~]$ zkServer.sh start
[atguigu@hadoop104 ~]$ zkServer.sh start

(3)啓動 Zookeeper 以後,然後再初始化 HA 在 Zookeeper 中狀態:

[atguigu@hadoop102 ~]$ hdfs zkfc -formatZK

(4)啓動 HDFS 服務:

[atguigu@hadoop102 ~]$ start-dfs.sh

(5)可以去 zkCli.sh 客戶端查看 Namenode 選舉鎖節點內容:

[zk: localhost:2181(CONNECTED) 7] get -s
/hadoop-ha/mycluster/ActiveStandbyElectorLock
myclusternn2 hadoop103 �>(�>
cZxid = 0x10000000b
ctime = Tue Jul 14 17:00:13 CST 2020
mZxid = 0x10000000b
mtime = Tue Jul 14 17:00:13 CST 2020
pZxid = 0x10000000b
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x40000da2eb70000
dataLength = 33
numChildren = 0

3)驗證
(1)將 Active NameNode 進程 kill,查看網頁端三臺 Namenode 的狀態變化

[atguigu@hadoop102 ~]$ kill -9 namenode 的進程 id

4.3 解決 NN 連接不上 JN 的問題

自動故障轉移配置好以後,然後使用 start-dfs.sh 羣起腳本啓動 hdfs 集羣,有可能會遇到 NameNode 起來一會後,進程自動關閉的問題。查看 NameNode 日誌,報錯信
息如下:

2020-08-17 10:11:40,658 INFO org.apache.hadoop.ipc.Client: Retrying connect to server: hadoop104/192.168.6.104:8485. Already tried 0 time(s); retry policy is RetryUpToMaximumCountWithFixedSleep(maxRetries=10, sleepTime=1000 MILLISECONDS)
2020-08-17 10:11:40,659 INFO org.apache.hadoop.ipc.Client: Retrying connect to server: hadoop102/192.168.6.102:8485. Already tried 0 time(s); retry policy is RetryUpToMaximumCountWithFixedSleep(maxRetries=10, sleepTime=1000 MILLISECONDS)
2020-08-17 10:11:40,659 INFO org.apache.hadoop.ipc.Client: Retrying connect to server: hadoop103/192.168.6.103:8485. Already tried 0 time(s); retry policy is RetryUpToMaximumCountWithFixedSleep(maxRetries=10,
sleepTime=1000 MILLISECONDS)
2020-08-17 10:11:49,678 WARN org.apache.hadoop.hdfs.server.namenode.FSEditLog: Unable to determine input streams from QJM to [192.168.6.102:8485, 192.168.6.103:8485, 192.168.6.104:8485]. Skipping.org.apache.hadoop.hdfs.qjournal.client.QuorumException: Got too many exceptions to achieve quorum size 2/3. 3 exceptions thrown:192.168.6.103:8485: Call From hadoop102/192.168.6.102 to hadoop103:8485 failed on connection exception: java.net.ConnectException: 拒絕連接; For more details see: http://wiki.apache.org/hadoop/ConnectionRefused

查看報錯日誌,可分析出報錯原因是因爲 NameNode 連接不上 JournalNode,而利用 jps 命令查看到三臺 JN 都已經正常啓動,爲什麼 NN 還是無法正常連接到 JN 呢?這是因爲 start-dfs.sh 羣起腳本默認的啓動順序是先啓動 NN,再啓動 DN,然後再啓動 JN,並且默認的 rpc 連接參數是重試次數爲 10,每次重試的間隔是 1s,也就是說啓動完 NN以後的 10s 中內,JN 還啓動不起來,NN 就會報錯了。

core-default.xml 裏面有兩個參數如下:

<!-- NN 連接 JN 重試次數,默認是 10 次 -->
<property>
 <name>ipc.client.connect.max.retries</name>
 <value>10</value>
</property>
<!-- 重試時間間隔,默認 1s -->
<property>
 <name>ipc.client.connect.retry.interval</name>
 <value>1000</value>
</property>

解決方案:遇到上述問題後,可以稍等片刻,等 JN 成功啓動後,手動啓動下三臺NN:

[atguigu@hadoop102 ~]$ hdfs --daemon start namenode
[atguigu@hadoop103 ~]$ hdfs --daemon start namenode
[atguigu@hadoop104 ~]$ hdfs --daemon start namenode

 也可以在 core-site.xml 裏面適當調大上面的兩個參數:

<!-- NN 連接 JN 重試次數,默認是 10 次 -->
<property>
 <name>ipc.client.connect.max.retries</name>
 <value>20</value>
</property>
<!-- 重試時間間隔,默認 1s -->
<property>
 <name>ipc.client.connect.retry.interval</name>
 <value>5000</value>
</property>

第五章 YARN-HA 配置

5.1 YARN-HA 工作機制

1)官方文檔:
http://hadoop.apache.org/docs/r3.1.3/hadoop-yarn/hadoop-yarn-site/ResourceManagerHA.htm

2)YARN-HA 工作機制

5.2 配置 YARN-HA 集羣

1)環境準備
(1)修改 IP
(2)修改主機名及主機名和 IP 地址的映射
(3)關閉防火牆
(4)ssh 免密登錄
(5)安裝 JDK,配置環境變量等
(6)配置 Zookeeper 集羣

2)規劃集羣

hadoop102 hadoop103 hadoop104
ResourceManager ResourceManager ResourceManager
NodeManager NodeManager NodeManager
Zookeeper Zookeeper Zookeeper


3)核心問題
a .如果當前 active rm 掛了,其他 rm 怎麼將其他 standby rm 上位?

核心原理跟 hdfs 一樣,利用了 zk 的臨時節點
b. 當前 rm 上有很多的計算程序在等待運行,其他的 rm 怎麼將這些程序接手過來接着跑?

rm 會將當前的所有計算程序的狀態存儲在 zk 中,其他 rm 上位後會去讀取,然後接着跑

4)具體配置
(1)yarn-site.xml

<configuration>
 <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>
 <!--指定 resourcemanager 的邏輯列表-->
 <property>
 <name>yarn.resourcemanager.ha.rm-ids</name>
 <value>rm1,rm2,rm3</value>
</property>
<!-- ========== rm1 的配置 ========== -->
<!-- 指定 rm1 的主機名 -->
 <property>
 <name>yarn.resourcemanager.hostname.rm1</name>
 <value>hadoop102</value>
</property>
<!-- 指定 rm1 的 web 端地址 -->
<property>
 <name>yarn.resourcemanager.webapp.address.rm1</name>
 <value>hadoop102:8088</value>
</property>
<!-- 指定 rm1 的內部通信地址 -->
<property>
 <name>yarn.resourcemanager.address.rm1</name>
 <value>hadoop102:8032</value>
</property>
<!-- 指定 AM 向 rm1 申請資源的地址 -->
<property>
 <name>yarn.resourcemanager.scheduler.address.rm1</name>
 <value>hadoop102:8030</value>
</property>
<!-- 指定供 NM 連接的地址 -->
<property>
 <name>yarn.resourcemanager.resource-tracker.address.rm1</name>
 <value>hadoop102:8031</value>
</property>
<!-- ========== rm2 的配置 ========== -->
 <!-- 指定 rm2 的主機名 -->
 <property>
 <name>yarn.resourcemanager.hostname.rm2</name>
 <value>hadoop103</value>
</property>
<property>
 <name>yarn.resourcemanager.webapp.address.rm2</name>
 <value>hadoop103:8088</value>
</property>
<property>
 <name>yarn.resourcemanager.address.rm2</name>
 <value>hadoop103:8032</value>
</property>
<property>
 <name>yarn.resourcemanager.scheduler.address.rm2</name>
 <value>hadoop103:8030</value>
</property>
<property>
 <name>yarn.resourcemanager.resource-tracker.address.rm2</name>
 <value>hadoop103:8031</value>
</property>
<!-- ========== rm3 的配置 ========== -->
<!-- 指定 rm1 的主機名 -->
 <property>
 <name>yarn.resourcemanager.hostname.rm3</name>
 <value>hadoop104</value>
</property>
<!-- 指定 rm1 的 web 端地址 -->
<property>
 <name>yarn.resourcemanager.webapp.address.rm3</name>
 <value>hadoop104:8088</value>
</property>
<!-- 指定 rm1 的內部通信地址 -->
<property>
 <name>yarn.resourcemanager.address.rm3</name>
 <value>hadoop104:8032</value>
</property>
<!-- 指定 AM 向 rm1 申請資源的地址 -->
<property>
 <name>yarn.resourcemanager.scheduler.address.rm3</name>
 <value>hadoop104:8030</value>
</property>
<!-- 指定供 NM 連接的地址 -->
<property>
 <name>yarn.resourcemanager.resource-tracker.address.rm3</name>
 <value>hadoop104:8031</value>
</property>
 <!-- 指定 zookeeper 集羣的地址 -->
 <property>
 <name>yarn.resourcemanager.zk-address</name>
 <value>hadoop102:2181,hadoop103:2181,hadoop104: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.ZKRMStateSt
ore</value>
</property>
<!-- 環境變量的繼承 -->
<property>
 <name>yarn.nodemanager.env-whitelist</name>
 <value>JAVA_HOME,HADOOP_COMMON_HOME,HADOOP_HDFS_HOME,HADOOP_CONF_DIR,CLASSPATH_PREPEND_DISTCACHE,HADOOP_YARN_HOME,HADOOP_MAPRED_HOME</value>
 </property>
</configuration>

(2)同步更新其他節點的配置信息,分發配置文件

[atguigu@hadoop102 etc]$ xsync hadoop/

4)啓動 YARN
(1)在 hadoop102 或者 hadoop103 中執行:

[atguigu@hadoop102 ~]$ start-yarn.sh

(2)查看服務狀態

[atguigu@hadoop102 ~]$ yarn rmadmin -getServiceState rm1

(3)可以去 zkCli.sh 客戶端查看 ResourceManager 選舉鎖節點內容:

[atguigu@hadoop102 ~]$ zkCli.sh
[zk: localhost:2181(CONNECTED) 16] get -s
/yarn-leader-election/cluster-yarn1/ActiveStandbyElectorLock
cluster-yarn1rm1
cZxid = 0x100000022
ctime = Tue Jul 14 17:06:44 CST 2020
mZxid = 0x100000022
mtime = Tue Jul 14 17:06:44 CST 2020
pZxid = 0x100000022
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x30000da33080005
dataLength = 20
numChildren = 0

(4)web 端查看 hadoop102:8088 和 hadoop103:8088 的 YARN 的狀態

5.3 HADOOP HA 的最終規劃

將整個 ha 搭建完成後,集羣將形成以下模樣

hadoop102 hadoop103 hadoop104
NameNode NameNode NameNode
JournalNode JournalNode JournalNode
DataNode DataNode DataNode
Zookeeper Zookeeper Zookeeper
ZKFC ZKFC ZKFC
ResourceManager ResourceManager ResourceManager
NodeManager NodeManager NodeManager
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章