天天看點

03_Hadoop高可用叢集環境搭建

作者:妮唯伊

Hadoop高可用叢集環境搭建

li_zliang

2021-09-25

1 高可用簡介

1.1 高可用架構

1.2 基于 QJM 的共享存儲系統的資料同步機制分析

1.3 NameNode 主備切換

2 叢集規劃

2.1 虛機環境

2.2 JDK1.8

2.3 hadoop叢集

2.4 zookeeper叢集

3. 前置配置

3.1 zookeeper叢集

3.2 安裝jdk

3.3 修改計算機名

3.4 配置免密登陸

3.3.1 ssh服務

3.3.2 生成秘鑰

3.3.3 免密登陸

3.3.4 登陸驗證

4. 叢集搭建

4.1 安裝hadoop(master主機)

4.2 配置環境變量(master主機,slave從機分發後)

4.3 建立檔案目錄(master主機)

4.4 配置配置檔案(master主機)

4.4.2 配置hadoop-env.sh

4.4.3 配置yarn-env.sh

4.4.4 配置core-site.xml

4.4.5 配置hdfs-site.xml

4.4.6 配置yarn-site.xml

4.4.7 配置mapred-site.xml

4.4.8 配置slaves

4.5 分發程式(master主機)

4.6 設定環境變量(slave從機)

5 關閉防火牆

6 啟動運作

6.1 啟動Zookeeper

6.2 啟動Journalnode

6.3 初始化NameNode

6.4 初始化HA狀态

6.5 啟動HDFS

6.6 啟動YARN

6.7 檢視叢集

7 二次啟動運作

8 參考資料

9 問題

9.1 問題1-啟動連結journalnode(端口8485)異常

1 高可用簡介

Hadoop 高可用 (High Availability) 分為 HDFS 高可用和 YARN 高可用,兩者的實作基本類似,但HDFS NameNode 對資料存儲及其一緻性的要求比 YARN ResourceManger 高得多,是以它的實作也更加複雜;

1.1 高可用架構

03_Hadoop高可用叢集環境搭建

Hadoop 高可用 (High Availability) 分為 HDFS 高可用和 YARN 高可用,兩者的實作基本類似,但HDFS NameNode 對資料存儲及其一緻性的要求比 YARN ResourceManger 高得多,是以它的實作也更加複雜;

HDFS 高可用架構主要由以下元件所構成:

Active NameNode 和 Standby NameNode:兩台 NameNode 形成互備,一台處于 Active 狀态,為主 NameNode,另外一台處于 Standby 狀态,為備 NameNode,隻有主 NameNode 才能對外提供讀寫服務。

主備切換控制器 ZKFailoverController:ZKFailoverController 作為獨立的程序運作,對NameNode 的主備切換進行總體控制。ZKFailoverController 能及時檢測到 NameNode 的健康狀況,在主 NameNode 故障時借助 Zookeeper 實作自動的主備選舉和切換,當然 NameNode目前也支援不依賴于 Zookeeper 的手動主備切換。

Zookeeper 叢集:為主備切換控制器提供主備選舉支援。

共享存儲系統:共享存儲系統是實作 NameNode 的高可用最為關鍵的部分,共享存儲系統儲存了NameNode 在運作過程中所産生的 HDFS 的中繼資料。主 NameNode 和 NameNode 通過共享存儲系統實作中繼資料同步。在進行主備切換的時候,新的主 NameNode 在确認中繼資料完全同步之後才能繼續對外提供服務。

DataNode 節點:除了通過共享存儲系統共享 HDFS 的中繼資料資訊之外,主 NameNode 和備NameNode 還需要共享 HDFS 的資料塊和 DataNode 之間的映射關系。DataNode 會同時向主NameNode 和備 NameNode 上報資料塊的位置資訊。

1.2 基于 QJM 的共享存儲系統的資料同步機制分析

目前 Hadoop 支援使用 Quorum Journal Manager (QJM) 或 Network File System (NFS) 作為共享的存儲系統,這裡以 QJM 叢集為例進行說明:Active NameNode 首先把 EditLog 送出到 JournalNode 叢集,然後 Standby NameNode 再從 JournalNode 叢集定時同步 EditLog,當 Active NameNode 當機後, Standby NameNode 在确認中繼資料完全同步之後就可以對外提供服務。

需要說明的是向 JournalNode 叢集寫入 EditLog 是遵循 “過半寫入則成功” 的政策,是以你至少要有 3個 JournalNode 節點,當然你也可以繼續增加節點數量,但是應該保證節點總數是奇數。同時如果有2N+1 台 JournalNode,那麼根據過半寫的原則,最多可以容忍有 N 台 JournalNode 節點挂掉。

03_Hadoop高可用叢集環境搭建

1.3 NameNode 主備切換

NameNode 實作主備切換的流程下圖所示:

03_Hadoop高可用叢集環境搭建

1. HealthMonitor 初始化完成之後會啟動内部的線程來定時調用對應 NameNode 的HAServiceProtocol RPC 接口的方法,對 NameNode 的健康狀态進行檢測。

2. HealthMonitor 如果檢測到 NameNode 的健康狀态發生變化,會回調 ZKFailoverController 注冊的相應方法進行處理。

3. 如果 ZKFailoverController 判斷需要進行主備切換,會首先使用 ActiveStandbyElector 來進行自動的主備選舉。

4. ActiveStandbyElector 與 Zookeeper 進行互動完成自動的主備選舉。

5. ActiveStandbyElector 在主備選舉完成後,會回調 ZKFailoverController 的相應方法來通知目前的 NameNode 成為主 NameNode 或備 NameNode。

6. ZKFailoverController 調用對應 NameNode 的 HAServiceProtocol RPC 接口的方法将NameNode 轉換為 Active 狀态或 Standby 狀态。

1.4 YARN高可用

YARN ResourceManager 的高可用與 HDFS NameNode 的高可用類似,但是 ResourceManager 不像NameNode ,沒有那麼多的中繼資料資訊需要維護,是以它的狀态資訊可以直接寫到 Zookeeper 上,并依賴 Zookeeper 來進行主備選舉;

03_Hadoop高可用叢集環境搭建

2 叢集規劃

按照高可用的設計目标:需要保證至少有兩個 NameNode (一主一備) 和 兩個 ResourceManager (一主一備) ,同時為滿足“過半寫入則成功”的原則,需要至少要有 3 個 JournalNode 節點。這裡使用三台主機進行搭建,叢集規劃如下:

03_Hadoop高可用叢集環境搭建

三台主機名:hadoop-master、hadoop-slave1、hadoop-slave2

1. 主NameNode:hadoop-master

2. 備NameNode:hadoop-slave1

3. 主ResourceManager:hadoop-master

4. 備ResourceManager:hadoop-slave2

5. DataNode:三台主機都有

6. JournalNode:三台主機都有

7. NodeManager:三台主機都有

8. Zookeeper:三台主機都有

2 前提準備

2.1 虛機環境

裡搭建一個 3 節點的 Hadoop 叢集;我這裡準備了三台CentOS 7;用VMware搭建;

計算機名分别 為hadoop-master、hadoop-slave1、hadoop-slave2;

2.2 JDK1.8

hadoop依賴JDK,提前安裝好JDK; 三台主機都要安裝;

2.3 hadoop叢集

搭建好hadoop叢集,詳見《01_Hadoop叢集環境搭建(CentOS)》;

2.4 zookeeper叢集

搭建好zookeeper叢集,詳見《02_Zookeeper叢集環境搭建(CentOS)》;

3. 前置配置

3.1 zookeeper叢集

搭建好zookeeper叢集,詳見《02_Zookeeper叢集環境搭建(CentOS)》;

3.2 安裝jdk

詳見《01_Hadoop叢集環境搭建(CentOS)》;

3.3 修改計算機名

詳見《01_Hadoop叢集環境搭建(CentOS)》;

3.4 配置免密登陸

這裡需要注意的是:三台主機互相免密登陸;《01_Hadoop叢集環境搭建(CentOS)》中隻是配置的master免密通路slave1和slave2;

3.3.1 ssh服務

一般伺服器上都已安裝ssh;

隻要ps -e | grep ssh,有sshd輸出即可;

03_Hadoop高可用叢集環境搭建

3.3.2 生成秘鑰

每台主機上使用ssh-keygen指令生成公鑰私鑰對;

//生成秘鑰

> ssh-keygen -t rsa -P ""

//.ssh隐藏,ls是看不到的;

> cd /root/.ssh

注:回車後會在/root/.ssh/下生成兩個檔案:id_rsa和id_rsa.pub這兩個檔案是成對出現的;

3.3.3 免密登陸

第一步:将公鑰id_rsa.pub寫到 ~/.ssh/authorized_keys授權檔案中

# hadoop-master上執行

> ssh-copy-id -i ~/.ssh/id_rsa.pub hadoop-master

# hadoop-slave1上執行

> ssh-copy-id -i ~/.ssh/id_rsa.pub hadoop-slave1

# hadoop-slave2上執行

> ssh-copy-id -i ~/.ssh/id_rsa.pub hadoop-slave2

第二步:将公鑰複制為id_rsa_master.pub并放到/home下

# hadoop-master上執行

> cp ~/.ssh/id_rsa.pub /home/id_rsa_master.pub

# hadoop-slave1上執行

> cp ~/.ssh/id_rsa.pub /home/id_rsa_slave1.pub

# hadoop-slave2上執行

> cp ~/.ssh/id_rsa.pub /home/id_rsa_slave2.pub

第三步:将id_rsa_master.pub、id_rsa_slave1.pub、id_rsa_slave2.pub檔案取下來,并放到hadoop-master、hadoop-slave1、hadoop-slave2的/root/~ssh目錄下;

先放到/home下,再複制到/root/~ssh下,因為~ssh目錄是看不到的

# hadoop-master上執行

> cp /home/id_rsa_slave1.pub /root/.ssh/

> cp /home/id_rsa_slave2.pub /root/.ssh/

# hadoop-slave1上執行

> cp /home/id_rsa_master.pub /root/.ssh/

> cp /home/id_rsa_slave2.pub /root/.ssh/

# hadoop-slave2上執行

> cp /home/id_rsa_master.pub /root/.ssh/

> cp /home/id_rsa_slave1.pub /root/.ssh/

第四步:将公鑰id_rsa_xxxxx.pub寫到 ~/.ssh/authorized_keys授權檔案中

# hadoop-master上執行

> cat ~/.ssh/id_rsa_slave1.pub >> ~/.ssh/authorized_keys

> cat ~/.ssh/id_rsa_slave2.pub >> ~/.ssh/authorized_keys

# hadoop-slave1上執行

> cat ~/.ssh/id_rsa_master.pub >> ~/.ssh/authorized_keys

> cat ~/.ssh/id_rsa_slave2.pub >> ~/.ssh/authorized_keys

# hadoop-slave2上執行

> cat ~/.ssh/id_rsa_master.pub >> ~/.ssh/authorized_keys

> cat ~/.ssh/id_rsa_slave1.pub >> ~/.ssh/authorized_keys

3.3.4 登陸驗證

在hadoop-master上操作,分别免密登陸hadoop-slave1和hadoop-slave2;

> ssh hadoop-slave1

> exit

> ssh hadoop-slave2

> exit

03_Hadoop高可用叢集環境搭建

在hadoop-slave1上操作,分别免密登陸hadoop-master和hadoop-slave2;

> ssh hadoop-master

> exit

> ssh hadoop-slave2

> exit

在hadoop-slave2上操作,分别免密登陸hadoop-master和hadoop-slave1;

> ssh hadoop-master

> exit

> ssh hadoop-slave1

> exit

4. 叢集搭建

4.1 安裝hadoop(master主機)

詳見《01_Hadoop叢集環境搭建(CentOS)》;

4.2 配置環境變量(master主機,slave從機分發後)

詳見《01_Hadoop叢集環境搭建(CentOS)》;

4.3 建立檔案目錄(master主機)

詳見《01_Hadoop叢集環境搭建(CentOS)》;

4.4 配置配置檔案(master主機)

4.4.1 檢視配置

詳見《01_Hadoop叢集環境搭建(CentOS)》;

4.4.2 配置hadoop-env.sh

修改JAVA_HOME

# 指定JDK的安裝位置

# export JAVA_HOME=$JAVA_HOME

export JAVA_HOME=/usr/local/java/jdk1.8.0_301

4.4.3 配置yarn-env.sh

修改JAVA_HOME

# 指定JDK的安裝位置

# export JAVA_HOME=/home/y/libexec/jdk1.6.0/

export JAVA_HOME=/usr/local/java/jdk1.8.0_301

4.4.4 配置core-site.xml

注意,實際配置時,将中文注釋都去掉,否則在後續初始化時出現編碼異常(java.lang.RuntimeException: com.ctc.wstx.exc.WstxIOException: Invalid UTF-8 start byte 0xb5);

<configuration>

<property>

<!--指定 namenode 的 hdfs 協定檔案系統的通信位址-->

<name>fs.defaultFS</name>

<value>hdfs://hadoop-master:8020</value>

</property>

<property>

<!--指定 hadoop 叢集存儲臨時檔案的目錄-->

<name>hadoop.tmp.dir</name>

<!--$hadoop_home/hdfs/tmp-->

<value>/usr/local/hadoop/hadoop-2.10.1/hdfs/tmp</value>

</property>

<property>

<!-- ZooKeeper 叢集的位址 -->

<name>ha.zookeeper.quorum</name>

<value>hadoop-master:2181,hadoop-slave1:2181,hadoop-slave2:2181</value>

</property>

<property>

<!-- ZKFC 連接配接到 ZooKeeper 逾時時長 -->

<name>ha.zookeeper.session-timeout.ms</name>

<value>10000</value>

</property>

</configuration>

4.4.5 配置hdfs-site.xml

注意,實際配置時,将中文注釋都去掉,否則在後續初始化時出現編碼異常(java.lang.RuntimeException: com.ctc.wstx.exc.WstxIOException: Invalid UTF-8 start byte 0xb5);

<configuration>

<property>

<!-- 指定 HDFS 副本的數量 -->

<name>dfs.replication</name>

<value>3</value>

</property>

<property>

<name>dfs.namenode.name.dir</name>

<!--namenode 節點資料(即中繼資料)的存放位置,可以指定多個目錄實作容錯,多個目錄用逗号分隔-->

<!--$hadoop_home/hdfs/name-->

<value>/usr/local/hadoop/hadoop-2.10.1/hdfs/name</value>

<final>true</final>

</property>

<property>

<name>dfs.datanode.data.dir</name>

<!--datanode 節點資料(即資料塊)的存放位置-->

<!--$hadoop_home/hdfs/data-->

<value>/usr/local/hadoop/hadoop-2.10.1/hdfs/data</value>

<final>true</final>

</property>

<property>

<name>dfs.datanode.edits.dir</name>

<value>/usr/local/hadoop/hadoop-2.10.1/hdfs/edits</value>

<final>true</final>

</property>

<property>

<!-- 叢集服務的邏輯名稱 -->

<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>hadoop-master:8020</value>

</property>

<property>

<!-- nn2 的 RPC 通信位址 -->

<name>dfs.namenode.rpc-address.mycluster.nn2</name>

<value>hadoop-slave1:8020</value>

</property>

<property>

<!-- nn1 的 http 通信位址 -->

<name>dfs.namenode.http-address.mycluster.nn1</name>

<value>hadoop-master:50070</value>

</property>

<property>

<!-- nn2 的 http 通信位址 -->

<name>dfs.namenode.http-address.mycluster.nn2</name>

<value>hadoop-slave1:50070</value>

</property>

<property>

<!-- NameNode 中繼資料在 JournalNode 上的共享存儲目錄 -->

<name>dfs.namenode.shared.edits.dir</name>

<value>qjournal://hadoop-master:8485;hadoop-slave1:8485;hadoop-slave2:8485/mycluster</value>

</property>

<property>

<!-- Journal Edit Files 的存儲目錄 -->

<name>dfs.journalnode.edits.dir</name>

<value>/usr/local/hadoop/hadoop-2.10.1/journalnode/data</value>

</property>

<property>

<!-- 配置隔離機制,確定在任何給定時間隻有一個 NameNode 處于活動狀态 -->

<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>

<!-- 通路代理類,用于确定目前處于 Active 狀态的 NameNode -->

<name>dfs.client.failover.proxy.provider.mycluster</name>

<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>

</property>

<property>

<!-- 開啟故障自動轉移 -->

<name>dfs.ha.automatic-failover.enabled</name>

<value>true</value>

</property>

</configuration>

4.4.6 配置yarn-site.xml

注意,實際配置時,将中文注釋都去掉,否則在後續初始化時出現編碼異常(java.lang.RuntimeException: com.ctc.wstx.exc.WstxIOException: Invalid UTF-8 start byte 0xb5);

<configuration>

<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 叢集辨別 -->

<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 的服務位址 -->

<name>yarn.resourcemanager.hostname.rm1</name>

<value>hadoop-slave1</value>

</property>

<property>

<!-- RM2 的服務位址 -->

<name>yarn.resourcemanager.hostname.rm2</name>

<value>hadoop-slave2</value>

</property>

<property>

<!-- RM1 Web 應用程式的位址 -->

<name>yarn.resourcemanager.webapp.address.rm1</name>

<value>hadoop-slave1:8088</value>

</property>

<property>

<!-- RM2 Web 應用程式的位址 -->

<name>yarn.resourcemanager.webapp.address.rm2</name>

<value>hadoop-slave2:8088</value>

</property>

<property>

<!-- ZooKeeper 叢集的位址 -->

<name>yarn.resourcemanager.zk-address</name>

<value>hadoop-master:2181,hadoop-slave1:2181,hadoop-slave2:2181</value>

</property>

<property>

<!-- 啟用自動恢複 -->

<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>

<property>

<!--配置 NodeManager 上運作的附屬服務;需要配置成 mapreduce_shuffle 後才可以在Yarn 上運作 MapReduce 程式;-->

<name>yarn.nodemanager.aux-services</name>

<value>mapreduce_shuffle</value>

</property>

<property>

<name>yarn.nodemanager.auxservices.mapreduce.shuffle.class</name>

<value>org.apache.hadoop.mapred.ShuffleHandler</value>

</property>

</configuration>

4.4.7 配置mapred-site.xml

複制mapred-site.xml.template檔案,并命名為mapred-site.xml;

cp mapred-site.xml.template mapred-site.xml

配置mapred-site.xml:

注意,實際配置時,将中文注釋都去掉,否則在後續初始化時出現編碼異常(java.lang.RuntimeException: com.ctc.wstx.exc.WstxIOException: Invalid UTF-8 start byte 0xb5);

<configuration>

<property>

<!--指定 mapreduce 作業運作在 yarn 上-->

<name>mapreduce.framework.name</name>

<value>yarn</value>

</property>

</configuration>

4.4.8 配置slaves

配置所有從屬節點的主機名或 IP 位址,每行一個。所有從屬節點上的 DataNode 服務和NodeManager 服務都會被啟動;

把原本的localhost删掉,改為:

hadoop-master

hadoop-slave1

hadoop-slave2

4.5 分發程式(master主機)

将 Hadoop 安裝包分發到其他兩台伺服器;

# hadoop-slave1 和 hadoop-slave2分别建立目錄

> mkdir /usr/local/hadoop/

# 将安裝包分發到hadoop-slave1

> scp -r /usr/local/hadoop/hadoop-2.10.1 hadoop-slave1:/usr/local/hadoop/

# 将安裝包分發到hadoop-slave2

> scp -r /usr/local/hadoop/hadoop-2.10.1 hadoop-slave2:/usr/local/hadoop/

# 總之從機的hadoop_home路徑與主機保持一緻;

# 修改配置後重新分發,比如修改主機配置檔案後

scp -r /usr/local/hadoop/hadoop-2.10.1/etc/hadoop/* hadoop-slave1:/usr/local/hadoop/hadoop-2.10.1/etc/hadoop/

scp -r /usr/local/hadoop/hadoop-2.10.1/etc/hadoop/* hadoop-slave2:/usr/local/hadoop/hadoop-2.10.1/etc/hadoop/

4.6 設定環境變量(slave從機)

在hadoop-slave1和hadoop-slave2設定 Hadoop 的環境變量;同4.2;

5 關閉防火牆

關閉三個主機的防火牆:

> systemctl stop firewalld.service

> systemctl disable firewalld.service

> systemctl status firewalld.service

6 啟動運作

6.1 啟動Zookeeper

分别到三台伺服器上啟動 ZooKeeper 服務:

> cd $ZOOKEEPER_HOME/bin

> ./zkServer.sh start

6.2 啟動Journalnode

分别到三台伺服器的的 ${HADOOP_HOME}/sbin 目錄下,啟動 journalnode 程序:

> cd ${HADOOP_HOME}/sbin

> ./hadoop-daemon.sh start journalnode

6.3 初始化NameNode

首次啟動需要進行初始化,初始化成功不再初始化;

在hadoop-master 上執行 namenode 初始化指令:

> hdfs namenode -format

注意如果出現編碼異常,則說明配置檔案中有中文字元;主機、從機的配置檔案都去掉中文注釋;

重新初始化:删除$HADOOP_HOME/hdfs/name、data、tmp的内容,以及$HADOOP_HOME/logs,然後再次format;

執行初始化指令後,需要将 NameNode 中繼資料目錄的内容,複制到其他未格式化的 NameNode 上。中繼資料存儲目錄就是我們在 hdfs-site.xml 中使用 dfs.namenode.name.dir 屬性指定的目錄。這裡我們需要将其複制到 hadoop-slave1 上:

> scp -r /usr/local/hadoop/hadoop-2.10.1/hdfs/name hadoop-slave1:/usr/local/hadoop/hadoop-2.10.1/hdfs/

6.4 初始化HA狀态

在任意一台 NameNode 上使用以下指令來初始化 ZooKeeper 中的 HA 狀态:

> hdfs zkfc -formatZK

6.5 啟動HDFS

進入到 hadoop-master 的 ${HADOOP_HOME}/sbin 目錄下,啟動 HDFS;

此時 hadoop-slave1 和 hadoop-slave2 上的 NameNode 服務,和三台伺服器上的 DataNode 服務都會被啟動:

> cd ${HADOOP_HOME}/sbin

> ./start-dfs.sh

6.6 啟動YARN

進入到 hadoop-slave1 的 ${HADOOP_HOME}/sbin 目錄下,啟動 YARN;

此時 hadoop-slave2 上的ResourceManager 服務,和三台伺服器上的 NodeManager 服務都會被啟動:

> cd ${HADOOP_HOME}/sbin

> ./start-yarn.sh

需要注意的是,這個時候 hadoop-slave2 上的 ResourceManager 服務通常是沒有啟動的,需要到hadoop-slave2 上手動啟動:

> cd ${HADOOP_HOME}/sbin

> ./yarn-daemon.sh start resourcemanager

6.7 檢視叢集

在每台伺服器上使用 jps 指令檢視服務程序:

03_Hadoop高可用叢集環境搭建
03_Hadoop高可用叢集環境搭建
03_Hadoop高可用叢集環境搭建

在本機(windows)配置hosts:

192.168.25.100 hadoop-master

192.168.25.102 hadoop-slave1

192.168.25.103 hadoop-slave2

檢視HDFS Web-UI 界面(節點管理GUI),端口為 50070

http://hadoop-master:50070

http://hadoop-slave1:50070

hadoop-master 上的 NameNode 處于可用狀态:

03_Hadoop高可用叢集環境搭建

hadoop-slave1 上的 NameNode 則處于備用狀态:

03_Hadoop高可用叢集環境搭建

同時界面上也有 Journal Manager 的相關資訊:

03_Hadoop高可用叢集環境搭建

檢視 Yarn Web-UI界面(資源管理GUI),端口為 8088 :

http://hadoop-slave1:8088

http://hadoop-slave2:8088

hadoop-slave1 上的 ResourceManager 處于可用狀态:

03_Hadoop高可用叢集環境搭建

hadoop-slave2 上的 ResourceManager 則處于備用狀态:

03_Hadoop高可用叢集環境搭建

7 二次啟動運作

上面的叢集初次啟動涉及到一些必要初始化操作,是以過程略顯繁瑣。但是叢集一旦搭建好後,想要再次啟用它是比較友善的,步驟如下

1. 分别到三台伺服器上啟動 ZooKeeper 服務:

> cd $ZOOKEEPER_HOME/bin

> ./zkServer.sh start

2. 在 hadoop-master 啟動 HDFS,此時會啟動所有與 HDFS 高可用相關的服務,包括 NameNode,DataNode 和 JournalNode:

> cd ${HADOOP_HOME}/sbin

> ./stop-dfs.sh

> ./start-dfs.sh

3. 在 hadoop-slave1 啟動 YARN:

> cd ${HADOOP_HOME}/sbin

> ./stop-yarn.sh

> ./start-yarn.sh

4. hadoop-slave2 上的 ResourceManager 服務通常還是沒有啟動的,需要手動啟動:

> cd ${HADOOP_HOME}/sbin

> ./yarn-daemon.sh stop resourcemanager

> ./yarn-daemon.sh start resourcemanager

8 參考資料

以上搭建步驟主要參考自官方文檔:

HDFS High Availability Using the Quorum Journal Manager

ResourceManager High Availability

9 問題

9.1 問題1-啟動連結journalnode(端口8485)異常

啟動hadoop時,出現Call From hadoop-master/192.168.25.100 to hadoop-master:8485 failed on connection exception: java.net.ConnectException: 拒絕連接配接;

答:

預設情況下namenode啟動10s(maxRetries=10, sleepTime=1000)後journalnode還沒有啟動,就會報上述錯誤。

由于部署好ha後,首次啟動我是分步啟動的,沒有遇到該問題;之後啟動,大約70%情況下會有該問題,30%左右的啟動是正常的,究其原因,我想70%的時候journalnode啟動比較慢,另有個别時候是啟動比較快;

修改core-site.xml中的ipc參數:僅對于這種由于服務沒有啟動完成造成連接配接逾時的問題,都可以調整core-site.xml中的ipc參數來解決;

<!--修改core-site.xml中的ipc參數,防止出現連接配接journalnode服務ConnectException-->

<property>

<name>ipc.client.connect.max.retries</name>

<value>100</value>

<description>Indicates the number of retries a client will make to establish a server connection.</description>

</property>

<property>

<name>ipc.client.connect.retry.interval</name>

<value>10000</value>

<description>Indicates the number of milliseconds a client will wait for before retrying to establish a server connection.</description>

</property>

9.2 問題2: Namenode寫Journalnode逾時

解決問題1後,啟動服務再次出現下述錯誤:

FATAL org.apache.hadoop.hdfs.server.namenode.FSEditLog: Error: flush failed for required journal (JournalAndStream(mgr=QJM to [192.168.5.100:8486, 192.168.5.102:8486, 192.168.5.103:8486], stream=QuorumOutputStream starting at txid 2947))java.io.IOException: Timed out waiting 20000ms for a quorum of nodes to respond.

答:

修改hdfs-site.xml中的ipc參數:在namenode對應的配置檔案中調大寫journanode逾時參數(預設是20000ms)

<property>

<name>dfs.qjournal.start-segment.timeout.ms</name>

<value>90000</value>

</property>

<property>

<name>dfs.qjournal.select-input-streams.timeout.ms</name>

<value>90000</value>

</property>

<property>

<name>dfs.qjournal.write-txns.timeout.ms</name>

<value>90000</value>

</property>

修改core-site.xml

<property>

<name>ipc.client.connect.timeout</name>

<value>90000</value>

</property>

繼續閱讀