您好,登錄后才能下訂單哦!
Hadoop 高可用 (High Availability) 分為 HDFS 高可用和 YARN 高可用,兩者的實現(xiàn)基本類似,但 HDFS NameNode 對數(shù)據(jù)存儲及其一致性的要求比 YARN ResourceManger 高得多,所以它的實現(xiàn)也更加復(fù)雜,故下面先進行講解:
HDFS 高可用架構(gòu)如下:
圖片引用自:https://www.edureka.co/blog/how-to-set-up-hadoop-cluster-with-hdfs-high-availability/
HDFS 高可用架構(gòu)主要由以下組件所構(gòu)成:
Active NameNode 和 Standby NameNode:兩臺 NameNode 形成互備,一臺處于 Active 狀態(tài),為主 NameNode,另外一臺處于 Standby 狀態(tài),為備 NameNode,只有主 NameNode 才能對外提供讀寫服務(wù)。
主備切換控制器 ZKFailoverController:ZKFailoverController 作為獨立的進程運行,對 NameNode 的主備切換進行總體控制。ZKFailoverController 能及時檢測到 NameNode 的健康狀況,在主 NameNode 故障時借助 Zookeeper 實現(xiàn)自動的主備選舉和切換,當(dāng)然 NameNode 目前也支持不依賴于 Zookeeper 的手動主備切換。
Zookeeper 集群:為主備切換控制器提供主備選舉支持。
共享存儲系統(tǒng):共享存儲系統(tǒng)是實現(xiàn) NameNode 的高可用最為關(guān)鍵的部分,共享存儲系統(tǒng)保存了 NameNode 在運行過程中所產(chǎn)生的 HDFS 的元數(shù)據(jù)。主 NameNode 和 NameNode 通過共享存儲系統(tǒng)實現(xiàn)元數(shù)據(jù)同步。在進行主備切換的時候,新的主 NameNode 在確認(rèn)元數(shù)據(jù)完全同步之后才能繼續(xù)對外提供服務(wù)。
目前 Hadoop 支持使用 Quorum Journal Manager (QJM) 或 Network File System (NFS) 作為共享的存儲系統(tǒng),這里以 QJM 集群為例進行說明:Active NameNode 首先把 EditLog 提交到 JournalNode 集群,然后 Standby NameNode 再從 JournalNode 集群定時同步 EditLog,當(dāng) Active NameNode 宕機后, Standby NameNode 在確認(rèn)元數(shù)據(jù)完全同步之后就可以對外提供服務(wù)。
需要說明的是向 JournalNode 集群寫入 EditLog 是遵循 “過半寫入則成功” 的策略,所以你至少要有 3 個 JournalNode 節(jié)點,當(dāng)然你也可以繼續(xù)增加節(jié)點數(shù)量,但是應(yīng)該保證節(jié)點總數(shù)是奇數(shù)。同時如果有 2N+1 臺 JournalNode,那么根據(jù)過半寫的原則,最多可以容忍有 N 臺 JournalNode 節(jié)點掛掉。
NameNode 實現(xiàn)主備切換的流程下圖所示:
YARN ResourceManager 的高可用與 HDFS NameNode 的高可用類似,但是 ResourceManager 不像 NameNode ,沒有那么多的元數(shù)據(jù)信息需要維護,所以它的狀態(tài)信息可以直接寫到 Zookeeper 上,并依賴 Zookeeper 來進行主備選舉。
按照高可用的設(shè)計目標(biāo):需要保證至少有兩個 NameNode (一主一備) 和 兩個 ResourceManager (一主一備) ,同時為滿足“過半寫入則成功”的原則,需要至少要有 3 個 JournalNode 節(jié)點。這里使用三臺主機進行搭建,集群規(guī)劃如下:
下載 Hadoop。這里我下載的是 CDH 版本 Hadoop,下載地址為:http://archive.cloudera.com/cdh6/cdh/5/
# tar -zvxf hadoop-2.6.0-cdh6.15.2.tar.gz
編輯 profile
文件:
# vim /etc/profile
增加如下配置:
export HADOOP_HOME=/usr/app/hadoop-2.6.0-cdh6.15.2
export PATH=${HADOOP_HOME}/bin:$PATH
執(zhí)行 source
命令,使得配置立即生效:
# source /etc/profile
進入 ${HADOOP_HOME}/etc/hadoop
目錄下,修改配置文件。各個配置文件內(nèi)容如下:
# 指定JDK的安裝位置
export JAVA_HOME=/usr/java/jdk1.8.0_201/
<configuration>
<property>
<!-- 指定 namenode 的 hdfs 協(xié)議文件系統(tǒng)的通信地址 -->
<name>fs.defaultFS</name>
<value>hdfs://hadoop001:8020</value>
</property>
<property>
<!-- 指定 hadoop 集群存儲臨時文件的目錄 -->
<name>hadoop.tmp.dir</name>
<value>/home/hadoop/tmp</value>
</property>
<property>
<!-- ZooKeeper 集群的地址 -->
<name>ha.zookeeper.quorum</name>
<value>hadoop001:2181,hadoop002:2181,hadoop002:2181</value>
</property>
<property>
<!-- ZKFC 連接到 ZooKeeper 超時時長 -->
<name>ha.zookeeper.session-timeout.ms</name>
<value>10000</value>
</property>
</configuration>
<configuration>
<property>
<!-- 指定 HDFS 副本的數(shù)量 -->
<name>dfs.replication</name>
<value>3</value>
</property>
<property>
<!-- namenode 節(jié)點數(shù)據(jù)(即元數(shù)據(jù))的存放位置,可以指定多個目錄實現(xiàn)容錯,多個目錄用逗號分隔 -->
<name>dfs.namenode.name.dir</name>
<value>/home/hadoop/namenode/data</value>
</property>
<property>
<!-- datanode 節(jié)點數(shù)據(jù)(即數(shù)據(jù)塊)的存放位置 -->
<name>dfs.datanode.data.dir</name>
<value>/home/hadoop/datanode/data</value>
</property>
<property>
<!-- 集群服務(wù)的邏輯名稱 -->
<name>dfs.nameservices</name>
<value>mycluster</value>
</property>
<property>
<!-- NameNode ID 列表-->
<name>dfs.ha.namenodes.mycluster</name>
<value>nn1,nn2</value>
</property>
<property>
<!-- nn1 的 RPC 通信地址 -->
<name>dfs.namenode.rpc-address.mycluster.nn1</name>
<value>hadoop001:8020</value>
</property>
<property>
<!-- nn2 的 RPC 通信地址 -->
<name>dfs.namenode.rpc-address.mycluster.nn2</name>
<value>hadoop002:8020</value>
</property>
<property>
<!-- nn1 的 http 通信地址 -->
<name>dfs.namenode.http-address.mycluster.nn1</name>
<value>hadoop001:50070</value>
</property>
<property>
<!-- nn2 的 http 通信地址 -->
<name>dfs.namenode.http-address.mycluster.nn2</name>
<value>hadoop002:50070</value>
</property>
<property>
<!-- NameNode 元數(shù)據(jù)在 JournalNode 上的共享存儲目錄 -->
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://hadoop001:8485;hadoop002:8485;hadoop003:8485/mycluster</value>
</property>
<property>
<!-- Journal Edit Files 的存儲目錄 -->
<name>dfs.journalnode.edits.dir</name>
<value>/home/hadoop/journalnode/data</value>
</property>
<property>
<!-- 配置隔離機制,確保在任何給定時間只有一個 NameNode 處于活動狀態(tài) -->
<name>dfs.ha.fencing.methods</name>
<value>sshfence</value>
</property>
<property>
<!-- 使用 sshfence 機制時需要 ssh 免密登錄 -->
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/root/.ssh/id_rsa</value>
</property>
<property>
<!-- SSH 超時時間 -->
<name>dfs.ha.fencing.ssh.connect-timeout</name>
<value>30000</value>
</property>
<property>
<!-- 訪問代理類,用于確定當(dāng)前處于 Active 狀態(tài)的 NameNode -->
<name>dfs.client.failover.proxy.provider.mycluster</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>
<property>
<!-- 開啟故障自動轉(zhuǎn)移 -->
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
</configuration>
<configuration>
<property>
<!--配置 NodeManager 上運行的附屬服務(wù)。需要配置成 mapreduce_shuffle 后才可以在 Yarn 上運行 MapReduce 程序。-->
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<!-- 是否啟用日志聚合 (可選) -->
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>
<property>
<!-- 聚合日志的保存時間 (可選) -->
<name>yarn.log-aggregation.retain-seconds</name>
<value>86400</value>
</property>
<property>
<!-- 啟用 RM HA -->
<name>yarn.resourcemanager.ha.enabled</name>
<value>true</value>
</property>
<property>
<!-- RM 集群標(biāo)識 -->
<name>yarn.resourcemanager.cluster-id</name>
<value>my-yarn-cluster</value>
</property>
<property>
<!-- RM 的邏輯 ID 列表 -->
<name>yarn.resourcemanager.ha.rm-ids</name>
<value>rm1,rm2</value>
</property>
<property>
<!-- RM1 的服務(wù)地址 -->
<name>yarn.resourcemanager.hostname.rm1</name>
<value>hadoop002</value>
</property>
<property>
<!-- RM2 的服務(wù)地址 -->
<name>yarn.resourcemanager.hostname.rm2</name>
<value>hadoop003</value>
</property>
<property>
<!-- RM1 Web 應(yīng)用程序的地址 -->
<name>yarn.resourcemanager.webapp.address.rm1</name>
<value>hadoop002:8088</value>
</property>
<property>
<!-- RM2 Web 應(yīng)用程序的地址 -->
<name>yarn.resourcemanager.webapp.address.rm2</name>
<value>hadoop003:8088</value>
</property>
<property>
<!-- ZooKeeper 集群的地址 -->
<name>yarn.resourcemanager.zk-address</name>
<value>hadoop001:2181,hadoop002:2181,hadoop003:2181</value>
</property>
<property>
<!-- 啟用自動恢復(fù) -->
<name>yarn.resourcemanager.recovery.enabled</name>
<value>true</value>
</property>
<property>
<!-- 用于進行持久化存儲的類 -->
<name>yarn.resourcemanager.store.class</name>
<value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value>
</property>
</configuration>
<configuration>
<property>
<!--指定 mapreduce 作業(yè)運行在 yarn 上-->
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
</configuration>
配置所有從屬節(jié)點的主機名或 IP 地址,每行一個。所有從屬節(jié)點上的 DataNode
服務(wù)和 NodeManager
服務(wù)都會被啟動。
hadoop001
hadoop002
hadoop003
將 Hadoop 安裝包分發(fā)到其他兩臺服務(wù)器,分發(fā)后建議在這兩臺服務(wù)器上也配置一下 Hadoop 的環(huán)境變量。
# 將安裝包分發(fā)到hadoop002
scp -r /usr/app/hadoop-2.6.0-cdh6.15.2/ hadoop002:/usr/app/
# 將安裝包分發(fā)到hadoop003
scp -r /usr/app/hadoop-2.6.0-cdh6.15.2/ hadoop003:/usr/app/
分別到三臺服務(wù)器上啟動 ZooKeeper 服務(wù):
zkServer.sh start
分別到三臺服務(wù)器的的 ${HADOOP_HOME}/sbin
目錄下,啟動 journalnode
進程:
hadoop-daemon.sh start journalnode
在 hadop001
上執(zhí)行 NameNode
初始化命令:
hdfs namenode -format
執(zhí)行初始化命令后,需要將 NameNode
元數(shù)據(jù)目錄的內(nèi)容,復(fù)制到其他未格式化的 NameNode
上。元數(shù)據(jù)存儲目錄就是我們在 hdfs-site.xml
中使用 dfs.namenode.name.dir
屬性指定的目錄。這里我們需要將其復(fù)制到 hadoop002
上:
scp -r /home/hadoop/namenode/data hadoop002:/home/hadoop/namenode/
在任意一臺 NameNode
上使用以下命令來初始化 ZooKeeper 中的 HA 狀態(tài):
hdfs zkfc -formatZK
進入到 hadoop001
的 ${HADOOP_HOME}/sbin
目錄下,啟動 HDFS。此時 hadoop001
和 hadoop002
上的 NameNode
服務(wù),和三臺服務(wù)器上的 DataNode
服務(wù)都會被啟動:
start-dfs.sh
進入到 hadoop002
的 ${HADOOP_HOME}/sbin
目錄下,啟動 YARN。此時 hadoop002
上的 ResourceManager
服務(wù),和三臺服務(wù)器上的 NodeManager
服務(wù)都會被啟動:
start-yarn.sh
需要注意的是,這個時候 hadoop003
上的 ResourceManager
服務(wù)通常是沒有啟動的,需要手動啟動:
yarn-daemon.sh start resourcemanager
成功啟動后,每臺服務(wù)器上的進程應(yīng)該如下:
[root@hadoop001 sbin]# jps
4512 DFSZKFailoverController
3714 JournalNode
4114 NameNode
3668 QuorumPeerMain
5012 DataNode
4639 NodeManager
[root@hadoop002 sbin]# jps
4499 ResourceManager
4595 NodeManager
3465 QuorumPeerMain
3705 NameNode
3915 DFSZKFailoverController
5211 DataNode
3533 JournalNode
[root@hadoop003 sbin]# jps
3491 JournalNode
3942 NodeManager
4102 ResourceManager
4201 DataNode
3435 QuorumPeerMain
HDFS 和 YARN 的端口號分別為 50070
和 8080
,界面應(yīng)該如下:
此時 hadoop001 上的 NameNode
處于可用狀態(tài):
而 hadoop002 上的 NameNode
則處于備用狀態(tài):
<br/>
<br/>
hadoop002 上的 ResourceManager
處于可用狀態(tài):
<br/>
<br/>
hadoop003 上的 ResourceManager
則處于備用狀態(tài):
<br/>
<br/>
同時界面上也有 Journal Manager
的相關(guān)信息:
<br/>
上面的集群初次啟動涉及到一些必要初始化操作,所以過程略顯繁瑣。但是集群一旦搭建好后,想要再次啟用它是比較方便的,步驟如下(首選需要確保 ZooKeeper 集群已經(jīng)啟動):
在 hadoop001
啟動 HDFS,此時會啟動所有與 HDFS 高可用相關(guān)的服務(wù),包括 NameNode,DataNode 和 JournalNode:
start-dfs.sh
在 hadoop002
啟動 YARN:
start-yarn.sh
這個時候 hadoop003
上的 ResourceManager
服務(wù)通常還是沒有啟動的,需要手動啟動:
yarn-daemon.sh start resourcemanager
以上搭建步驟主要參考自官方文檔:
關(guān)于 Hadoop 高可用原理的詳細分析,推薦閱讀:
Hadoop NameNode 高可用 (High Availability) 實現(xiàn)解析
更多大數(shù)據(jù)系列文章可以參見 GitHub 開源項目: 大數(shù)據(jù)入門指南
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。