基于 ZooKeeper 搭建 Hadoop 高可用集群 的教程圖解
一、高可用簡(jiǎn)介
Hadoop 高可用 (High Availability) 分為 HDFS 高可用和 YARN 高可用,兩者的實(shí)現(xiàn)基本類似,但 HDFS NameNode 對(duì)數(shù)據(jù)存儲(chǔ)及其一致性的要求比 YARN ResourceManger 高得多,所以它的實(shí)現(xiàn)也更加復(fù)雜,故下面先進(jìn)行講解:
1.1 高可用整體架構(gòu)
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:兩臺(tái) NameNode 形成互備,一臺(tái)處于 Active 狀態(tài),為主 NameNode,另外一臺(tái)處于 Standby 狀態(tài),為備 NameNode,只有主 NameNode 才能對(duì)外提供讀寫(xiě)服務(wù)。
- 主備切換控制器 ZKFailoverController:ZKFailoverController 作為獨(dú)立的進(jìn)程運(yùn)行,對(duì) NameNode 的主備切換進(jìn)行總體控制。ZKFailoverController 能及時(shí)檢測(cè)到 NameNode 的健康狀況,在主 NameNode 故障時(shí)借助 Zookeeper 實(shí)現(xiàn)自動(dòng)的主備選舉和切換,當(dāng)然 NameNode 目前也支持不依賴于 Zookeeper 的手動(dòng)主備切換。
- Zookeeper 集群:為主備切換控制器提供主備選舉支持。共享存儲(chǔ)系統(tǒng):共享存儲(chǔ)系統(tǒng)是實(shí)現(xiàn) NameNode 的高可用最為關(guān)鍵的部分,共享存儲(chǔ)系統(tǒng)保存了 NameNode 在運(yùn)行過(guò)程中所產(chǎn)生的 HDFS 的元數(shù)據(jù)。
- 主 NameNode 和 NameNode 通過(guò)共享存儲(chǔ)系統(tǒng)實(shí)現(xiàn)元數(shù)據(jù)同步。在進(jìn)行主備切換的時(shí)候,新的主 NameNode 在確認(rèn)元數(shù)據(jù)完全同步之后才能繼續(xù)對(duì)外提供服務(wù)。
- DataNode 節(jié)點(diǎn):除了通過(guò)共享存儲(chǔ)系統(tǒng)共享 HDFS 的元數(shù)據(jù)信息之外,主 NameNode 和備 NameNode 還需要共享 HDFS 的數(shù)據(jù)塊和 DataNode 之間的映射關(guān)系。
- DataNode 會(huì)同時(shí)向主 NameNode 和備 NameNode 上報(bào)數(shù)據(jù)塊的位置信息。
1.2 基于 QJM 的共享存儲(chǔ)系統(tǒng)的數(shù)據(jù)同步機(jī)制分析
目前 Hadoop 支持使用 Quorum Journal Manager (QJM) 或 Network File System (NFS) 作為共享的存儲(chǔ)系統(tǒng),這里以 QJM 集群為例進(jìn)行說(shuō)明:Active NameNode 首先把 EditLog 提交到 JournalNode 集群,然后 Standby NameNode 再?gòu)?JournalNode 集群定時(shí)同步 EditLog,當(dāng) Active NameNode 宕機(jī)后, Standby NameNode 在確認(rèn)元數(shù)據(jù)完全同步之后就可以對(duì)外提供服務(wù)。
需要說(shuō)明的是向 JournalNode 集群寫(xiě)入 EditLog 是遵循 “過(guò)半寫(xiě)入則成功” 的策略,所以你至少要有3個(gè) JournalNode 節(jié)點(diǎn),當(dāng)然你也可以繼續(xù)增加節(jié)點(diǎn)數(shù)量,但是應(yīng)該保證節(jié)點(diǎn)總數(shù)是奇數(shù)。同時(shí)如果有 2N+1 臺(tái) JournalNode,那么根據(jù)過(guò)半寫(xiě)的原則,最多可以容忍有 N 臺(tái) JournalNode 節(jié)點(diǎn)掛掉。

1.3 NameNode 主備切換
NameNode 實(shí)現(xiàn)主備切換的流程下圖所示:

HealthMonitor 初始化完成之后會(huì)啟動(dòng)內(nèi)部的線程來(lái)定時(shí)調(diào)用對(duì)應(yīng) NameNode 的 HAServiceProtocol RPC 接口的方法,對(duì) NameNode 的健康狀態(tài)進(jìn)行檢測(cè)。
HealthMonitor 如果檢測(cè)到 NameNode 的健康狀態(tài)發(fā)生變化,會(huì)回調(diào) ZKFailoverController 注冊(cè)的相應(yīng)方法進(jìn)行處理。
如果 ZKFailoverController 判斷需要進(jìn)行主備切換,會(huì)首先使用 ActiveStandbyElector 來(lái)進(jìn)行自動(dòng)的主備選舉。
ActiveStandbyElector 與 Zookeeper 進(jìn)行交互完成自動(dòng)的主備選舉。
ActiveStandbyElector 在主備選舉完成后,會(huì)回調(diào) ZKFailoverController 的相應(yīng)方法來(lái)通知當(dāng)前的 NameNode 成為主 NameNode 或備 NameNode。
ZKFailoverController 調(diào)用對(duì)應(yīng) NameNode 的 HAServiceProtocol RPC 接口的方法將 NameNode 轉(zhuǎn)換為 Active 狀態(tài)或 Standby 狀態(tài)。
1.4 YARN高可用
YARN ResourceManager 的高可用與 HDFS NameNode 的高可用類似,但是 ResourceManager 不像 NameNode ,沒(méi)有那么多的元數(shù)據(jù)信息需要維護(hù),所以它的狀態(tài)信息可以直接寫(xiě)到 Zookeeper 上,并依賴 Zookeeper 來(lái)進(jìn)行主備選舉。

二、集群規(guī)劃
按照高可用的設(shè)計(jì)目標(biāo):需要保證至少有兩個(gè) NameNode (一主一備) 和 兩個(gè) ResourceManager (一主一備) ,同時(shí)為滿足“過(guò)半寫(xiě)入則成功”的原則,需要至少要有3個(gè) JournalNode 節(jié)點(diǎn)。這里使用三臺(tái)主機(jī)進(jìn)行搭建,集群規(guī)劃如下:

三、前置條件所有服務(wù)器都安裝有JDK,安裝步驟可以參見(jiàn):Linux下JDK的安裝;搭建好ZooKeeper集群,搭建步驟可以參見(jiàn):Zookeeper單機(jī)環(huán)境和集群環(huán)境搭建所有服務(wù)器之間都配置好SSH免密登錄。
四、集群配置
4.1 下載并解壓
下載Hadoop。這里我下載的是CDH版本Hadoop,下載地址為:http://archive.cloudera.com/cdh5/cdh/5/
# tar -zvxf hadoop-2.6.0-cdh5.15.2.tar.gz
4.2 配置環(huán)境變量
編輯profile文件:
# vim /etc/profile
增加如下配置:
export HADOOP_HOME=/usr/app/hadoop-2.6.0-cdh5.15.2export PATH=${HADOOP_HOME}/bin:$PATH
執(zhí)行source命令,使得配置立即生效:
# source /etc/profile
4.3 修改配置
進(jìn)入${HADOOP_HOME}/etc/hadoop目錄下,修改配置文件。各個(gè)配置文件內(nèi)容如下:
1. hadoop-env.sh
# 指定JDK的安裝位置export JAVA_HOME=/usr/java/jdk1.8.0_201/
2. core-site.xml
<configuration> <property> <!-- 指定namenode的hdfs協(xié)議文件系統(tǒng)的通信地址 --> <name>fs.defaultFS</name> <value>hdfs://hadoop001:8020</value> </property> <property> <!-- 指定hadoop集群存儲(chǔ)臨時(shí)文件的目錄 --> <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超時(shí)時(shí)長(zhǎng) --> <name>ha.zookeeper.session-timeout.ms</name> <value>10000</value> </property> </configuration>
3. hdfs-site.xml
<configuration> <property> <!-- 指定HDFS副本的數(shù)量 --> <name>dfs.replication</name> <value>3</value> </property> <property> <!-- namenode節(jié)點(diǎn)數(shù)據(jù)(即元數(shù)據(jù))的存放位置,可以指定多個(gè)目錄實(shí)現(xiàn)容錯(cuò),多個(gè)目錄用逗號(hào)分隔 --> <name>dfs.namenode.name.dir</name> <value>/home/hadoop/namenode/data</value> </property> <property> <!-- datanode節(jié)點(diǎn)數(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上的共享存儲(chǔ)目錄 --> <name>dfs.namenode.shared.edits.dir</name> <value>qjournal://hadoop001:8485;hadoop002:8485;hadoop003:8485/mycluster</value> </property> <property> <!-- Journal Edit Files的存儲(chǔ)目錄 --> <name>dfs.journalnode.edits.dir</name> <value>/home/hadoop/journalnode/data</value> </property> <property> <!-- 配置隔離機(jī)制,確保在任何給定時(shí)間只有一個(gè)NameNode處于活動(dòng)狀態(tài) --> <name>dfs.ha.fencing.methods</name> <value>sshfence</value> </property> <property> <!-- 使用sshfence機(jī)制時(shí)需要ssh免密登錄 --> <name>dfs.ha.fencing.ssh.private-key-files</name> <value>/root/.ssh/id_rsa</value> </property> <property> <!-- SSH超時(shí)時(shí)間 --> <name>dfs.ha.fencing.ssh.connect-timeout</name> <value>30000</value> </property> <property> <!-- 訪問(wèn)代理類,用于確定當(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> <!-- 開(kāi)啟故障自動(dòng)轉(zhuǎn)移 --> <name>dfs.ha.automatic-failover.enabled</name> <value>true</value> </property> </configuration>
4. yarn-site.xml
<configuration> <property> <!--配置NodeManager上運(yùn)行的附屬服務(wù)。需要配置成mapreduce_shuffle后才可以在Yarn上運(yùn)行MapReduce程序。--> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> <property> <!-- 是否啟用日志聚合(可選) --> <name>yarn.log-aggregation-enable</name> <value>true</value> </property> <property> <!-- 聚合日志的保存時(shí)間(可選) --> <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)識(shí) --> <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> <!-- 啟用自動(dòng)恢復(fù) --> <name>yarn.resourcemanager.recovery.enabled</name> <value>true</value> </property> <property> <!-- 用于進(jìn)行持久化存儲(chǔ)的類 --> <name>yarn.resourcemanager.store.class</name> <value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value> </property> </configuration>
5. mapred-site.xml
<configuration> <property> <!--指定mapreduce作業(yè)運(yùn)行在yarn上--> <name>mapreduce.framework.name</name> <value>yarn</value> </property> </configuration>
5. slaves
配置所有從屬節(jié)點(diǎn)的主機(jī)名或IP地址,每行一個(gè)。所有從屬節(jié)點(diǎn)上的DataNode服務(wù)和NodeManager服務(wù)都會(huì)被啟動(dòng)。
hadoop001
hadoop002
hadoop003
4.4 分發(fā)程序
將Hadoop安裝包分發(fā)到其他兩臺(tái)服務(wù)器,分發(fā)后建議在這兩臺(tái)服務(wù)器上也配置一下Hadoop的環(huán)境變量。
# 將安裝包分發(fā)到hadoop002 scp -r /usr/app/hadoop-2.6.0-cdh5.15.2/ hadoop002:/usr/app/ # 將安裝包分發(fā)到hadoop003 scp -r /usr/app/hadoop-2.6.0-cdh5.15.2/ hadoop003:/usr/app/
5.1 啟動(dòng)ZooKeeper
分別到三臺(tái)服務(wù)器上啟動(dòng)ZooKeeper服務(wù):
zkServer.sh start
5.2 啟動(dòng)Journalnode
分別到三臺(tái)服務(wù)器的的${HADOOP_HOME}/sbin目錄下,啟動(dòng)journalnode進(jìn)程:
hadoop-daemon.sh start journalnode
5.3 初始化NameNode
在hadop001上執(zhí)行NameNode初始化命令:
hdfs namenode -format
執(zhí)行初始化命令后,需要將NameNode元數(shù)據(jù)目錄的內(nèi)容,復(fù)制到其他未格式化的NameNode上。元數(shù)據(jù)存儲(chǔ)目錄就是我們?cè)?code>hdfs-site.xml中使用dfs.namenode.name.dir屬性指定的目錄。這里我們需要將其復(fù)制到hadoop002上:
scp -r /home/hadoop/namenode/data hadoop002:/home/hadoop/namenode/
5.4 初始化HA狀態(tài)
在任意一臺(tái)NameNode上使用以下命令來(lái)初始化ZooKeeper中的HA狀態(tài):
hdfs zkfc -formatZK
5.5 啟動(dòng)HDFS
進(jìn)入到hadoop001的${HADOOP_HOME}/sbin目錄下,啟動(dòng)HDFS。此時(shí)hadoop001和hadoop002上的NameNode服務(wù),和三臺(tái)服務(wù)器上的DataNode服務(wù)都會(huì)被啟動(dòng):
start-dfs.sh
5.6 啟動(dòng)YARN
進(jìn)入到hadoop002的${HADOOP_HOME}/sbin目錄下,啟動(dòng)YARN。此時(shí)hadoop002上的ResourceManager服務(wù),和三臺(tái)服務(wù)器上的NodeManager服務(wù)都會(huì)被啟動(dòng):
start-yarn.sh
需要注意的是,這個(gè)時(shí)候hadoop003上的ResourceManager服務(wù)通常是沒(méi)有啟動(dòng)的,需要手動(dòng)啟動(dòng):
yarn-daemon.sh start resourcemanager
六、查看集群
6.1 查看進(jìn)程
成功啟動(dòng)后,每臺(tái)服務(wù)器上的進(jìn)程應(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
6.2 查看Web UI
HDFS和YARN的端口號(hào)分別為50070和8080,界面應(yīng)該如下:
此時(shí)hadoop001上的NameNode處于可用狀態(tài):

而hadoop002上的NameNode則處于備用狀態(tài):

hadoop002上的ResourceManager處于可用狀態(tài):

hadoop003上的ResourceManager則處于備用狀態(tài):

同時(shí)界面上也有Journal Manager的相關(guān)信息:

七、集群的二次啟動(dòng)
上面的集群初次啟動(dòng)涉及到一些必要初始化操作,所以過(guò)程略顯繁瑣。但是集群一旦搭建好后,想要再次啟用它是比較方便的,步驟如下(首選需要確保ZooKeeper集群已經(jīng)啟動(dòng)):
在hadoop001啟動(dòng) HDFS,此時(shí)會(huì)啟動(dòng)所有與 HDFS 高可用相關(guān)的服務(wù),包括 NameNode,DataNode 和 JournalNode:
start-dfs.sh
在hadoop002啟動(dòng)YARN:
start-yarn.sh
這個(gè)時(shí)候hadoop003上的ResourceManager服務(wù)通常還是沒(méi)有啟動(dòng)的,需要手動(dòng)啟動(dòng):
yarn-daemon.sh start resourcemanager
參考資料
以上搭建步驟主要參考自官方文檔:
HDFS High Availability Using the Quorum Journal ManagerResourceManager High Availability
總結(jié)
以上所述是小編給大家介紹的基于 ZooKeeper 搭建 Hadoop 高可用集群 的教程圖解,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
如果你覺(jué)得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!
相關(guān)文章
微服務(wù)架構(gòu)之服務(wù)注冊(cè)與發(fā)現(xiàn)實(shí)踐示例詳解
這篇文章主要為大家介紹了微服務(wù)架構(gòu)之服務(wù)注冊(cè)與發(fā)現(xiàn)實(shí)踐的示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-01-01
UDP DUP超時(shí)UPD端口狀態(tài)檢測(cè)代碼示例
這篇文章主要介紹了UDP DUP超時(shí)UPD端口狀態(tài)檢測(cè),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-10-10
外貿(mào)網(wǎng)站屏蔽中國(guó)IP訪問(wèn)的多種方法
這篇文章主要介紹了外貿(mào)網(wǎng)站屏蔽中國(guó)IP訪問(wèn)的多種方法,本文通過(guò)nginx、iptables、javascript三種方法實(shí)現(xiàn),需要的朋友可以參考下2014-12-12
通過(guò)StatefulSet部署有狀態(tài)服務(wù)應(yīng)用實(shí)現(xiàn)方式
這篇文章主要為大家介紹了通過(guò)StatefulSet部署有狀態(tài)服務(wù)應(yīng)用的實(shí)現(xiàn)方式,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-03-03
Mac下開(kāi)啟與關(guān)閉端口轉(zhuǎn)發(fā)的腳本配置方法
這篇文章主要介紹了Mac下開(kāi)啟與關(guān)閉端口轉(zhuǎn)發(fā)的腳本配置方法,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2018-04-04
DELL R720服務(wù)器安裝Windows Server 2008 R2系統(tǒng)的圖文詳解
這篇文章主要介紹了DELL R720服務(wù)器安裝Windows Server 2008 R2系統(tǒng)的圖文詳解,需要的朋友可以參考下2021-03-03
在Mac OS X中配置Apache+PHP+MySQL運(yùn)行環(huán)境的詳細(xì)步驟
這篇文章主要介紹了在Mac OS X中配置Apache+PHP+MySQL運(yùn)行環(huán)境的詳細(xì)步驟,需要的朋友可以參考下2017-09-09
阿里云k8s服務(wù)springboot項(xiàng)目應(yīng)用升級(jí)時(shí)出現(xiàn)502錯(cuò)誤
這篇文章主要介紹了阿里云k8s服務(wù)springboot項(xiàng)目應(yīng)用升級(jí)時(shí)出現(xiàn)502錯(cuò)誤,需要的朋友可以參考下2022-04-04

