天天看點

Hadoop(五) (Hadoop+zookeeper實作hdfs及yarn的高可用)實驗簡介

文章目錄

  • 實驗簡介
    • 部署zookeeper
      • ZooKeeper簡介
    • Hadoop 配置
    • 啟動 hdfs 叢集
    • 進行 測試
    • yarn的高可用

實驗簡介

在典型的 HA 叢集中,通常有兩台不同的機器充當 NN。在任何時間,隻有一台機器處于Active 狀态;另一台機器是處于 Standby 狀态。Active NN 負責叢集中所有用戶端的操作;

而 Standby NN 主要用于備用,它主要維持足夠的狀态,如果必要,可以提供快速的故障恢複。

為了讓 Standby NN 的狀态和 Active NN 保持同步,即中繼資料保持一緻,它們都将會和JournalNodes 守護程序通信。當 Active NN 執行任何有關命名空間的修改,它需要持久化到一半以上的 JournalNodes 上(通過 edits log 持久化存儲),而 Standby NN 負責觀察edits log的變化,它能夠讀取從 JNs 中讀取 edits 資訊,并更新其内部的命名空間。

一旦 Active NN出現故障,Standby NN 将會保證從 JNs 中讀出了全部的 Edits,然後切換成 Active 狀态。Standby NN 讀取全部的 edits 可確定發生故障轉移之前,是和 Active NN 擁有完全同步的命名空間狀态。

為了提供快速的故障恢複,Standby NN 也需要儲存叢集中各個檔案塊的存儲位置。為了實作這個,叢集中所有的 Database 将配置好 Active NN 和 Standby NN 的位置,并向它們發送塊檔案所在的位置及心跳,如下圖所示:

Hadoop(五) (Hadoop+zookeeper實作hdfs及yarn的高可用)實驗簡介

在任何時候,叢集中隻有一個 NN 處于 Active 狀态是極其重要的。否則,在兩個 Active NN的狀态下 NameSpace 狀态将會出現分歧,這将會導緻資料的丢失及其它不正确的結果。為了保證這種情況不會發生,在任何時間,JNs 隻允許一個 NN 充當 writer。在故障恢複期間,将要變成 Active 狀态的 NN 将取得 writer 的角色,并阻止另外一個 NN 繼續處于 Active狀态。

為了部署 HA 叢集,你需要準備以下事項:

(1)、NameNode machines:運作 Active NN 和 Standby NN 的機器需要相同的硬體配置;

(2)、JournalNode machines:也就是運作 JN 的機器。JN 守護程序相對來說比較輕量,是以這些守護程序可以可其他守護線程(比如 NN,YARN ResourceManager)運作在同一台機器上。在一個叢集中,最少要運作 3 個 JN 守護程序,這将使得系統有一定的容錯能力。當然,你也可以運作 3 個以上的 JN,但是為了增加系統的容錯能力,你應該運作奇數個 JN(3、5、7 等),當運作 N 個 JN,系統将最多容忍(N-1)/2 個 JN 崩潰。

在 HA 叢集中,Standby NN 也執行 namespace 狀态的 checkpoints,是以不必要運作Secondary NN、CheckpointNode 和 BackupNode;事實上,運作這些守護程序是錯誤的。

Zookeeper 叢集至少三台,總節點數為奇數個。

實驗環境:

172.25.2.3 ser3   NameNode  DFSZKFailoverController   ResourceManager

172.25.2.4  ser4  nn(新開的節點) NameNode DFSZKFailoverController   ResourceManager

172.25.2.5 ser5   JournalNode QuorumPeerMain  DataNode  NodeManager

172.25.2.6 ser6   JournalNode QuorumPeerMain DataNode  NodeManager
172.25.2.7  ser7   JournalNode QuorumPeerMain  DataNode  NodeManager
           

在ser3上

[[email protected] ~]$ rm -fr /tmp/*
[[email protected] ~]$ logout 
[[email protected] ~]# systemctl start nfs
[[email protected] ~]# showmount -e
Export list for ser3:
/home/yxx *
           

在新開的ser7上

[[email protected] ~]# yum install nfs-utils -y
[[email protected] ~]# useradd yxx
[[email protected] ~]# id yxx
uid=1001(yxx) gid=1001(yxx) groups=1001(yxx)
[[email protected] ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
172.25.2.1 ser1
172.25.2.3 ser3
172.25.2.4 ser4
172.25.2.5 ser5
172.25.2.6 ser6
172.25.2.7 ser7

[[email protected] ~]# systemctl start rpcbind
[[email protected] ~]# showmount -e 172.25.2.3
Export list for 172.25.2.3:
/home/yxx *
[[email protected] ~]# mount 172.25.2.3:/home/yxx/ /home/yxx

在其他資料節點也進行mount
           

部署zookeeper

ZooKeeper簡介

它是一個分布式的,開放源碼的分布式應用程式協調服務,是Google的Chubby一個開源的實作,是Hadoop和Hbase的重要元件。

它是一個為分布式應用提供一緻性服務的軟體,提供的功能包括:配置維護、域名服務、分布式同步、組服務等。

ZooKeeper的目标就是封裝好複雜易出錯的關鍵服務,将簡單易用的接口和性能高效、功能穩定的系統提供給使用者。

ZooKeeper包含一個簡單的原語集,提供Java和C的接口。

用途:

https://www.cnblogs.com/SimonHu1993/p/7798665.html
           

下載下傳位址

https://archive.apache.org/dist/zookeeper/zookeeper-3.4.9/
           

在ser3

[[email protected] ~]$ tar zxf zookeeper-3.4.9.tar.gz 
[[email protected] ~]$ du -sh zookeeper-3.4.9
45M	zookeeper-3.4.9


# 此時zookeeper也通過nfs在幾個節點間進行共享
           

在ser4上,對zookeeper進行設定

各節點配置檔案相同,并且需要在

/tmp/zookeeper

目錄中建立 myid 檔案,寫入

一個唯一的數字,取值範圍在 1-255。比如:172.25.0.2 節點的 myid 檔案寫入數

字“1”,此數字與配置檔案中的定義保持一緻,

(server.1=172.25.0.2:2888:3888 )

其它節點依次類推,配置檔案不用再每個節點更改,隻需要改myid,因為nfs已經進行共享了/home/yxx/*

[[email protected] ~]$ cd zookeeper-3.4.9/
[[email protected] zookeeper-3.4.9]$ cd conf/
[[email protected] conf]$ ls
configuration.xsl  log4j.properties  zoo_sample.cfg
[[email protected] conf]$ cp zoo_sample.cfg zoo.cfg
[[email protected] conf]$ vim zoo.cfg 配置檔案,用戶端連接配接端口是2181

在最後添加
server.1=172.25.2.4:2888:3888 # 3個都屬後端資料節點
server.2=172.25.2.5:2888:3888
server.3=172.25.2.6:2888:3888
           

2888是資料同步端口,3888是選舉端口。

server.x=[hostname]:nnnnn[:nnnnn]
           

這裡的 x 是一個數字,與 myid 檔案中的 id 是一緻的。右邊可以配置兩個端口,第一個端口

用于 F 和 L 之間的資料同步和其它通信,第二個端口用于 Leader 選舉過程中投票通信。

建立myid檔案

[[email protected] conf]$ mkdir /tmp/zookeeper 
[[email protected] conf]$ echo 1  > /tmp/zookeeper/myid

[[email protected] conf]$ mkdir /tmp/zookeeper
[[email protected] conf]$ echo 2 > /tmp/zookeeper/myid

[[email protected] ~]$ mkdir /tmp/zookeeper
[[email protected] ~]$ echo 3 > /tmp/zookeeper/myid
           

在各個節點(ser4 ,ser5 ser6)啟動程序

[[email protected] zookeeper-3.4.9]$ bin/zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /home/yxx/zookeeper-3.4.9/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
           

當所有 的都啟動,再檢視狀态

叢集通過選舉讓ser4和ser6是跟随者,ser5是上司

[[email protected] zookeeper-3.4.9]$  bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /home/yxx/zookeeper-3.4.9/bin/../conf/zoo.cfg
Mode: leader

[[email protected] zookeeper-3.4.9]$ bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /home/yxx/zookeeper-3.4.9/bin/../conf/zoo.cfg
Mode: follower
           

連接配接

[[email protected] zookeeper-3.4.9]$ bin/zkCli.sh  連接配接本機
[zk: localhost:2181(CONNECTED) 1] ls /
[zookeeper]


bin/zkCli.sh -server 127.0.0.1:2181 連接配接 其他主機的zookeeper
           

Hadoop 配置

ser3和set7做的是hadoop的高可用master

[[email protected] ~]$ ssh 172.25.2.7
The authenticity of host '172.25.2.7 (172.25.2.7)' can't be established.
ECDSA key fingerprint is SHA256:Tsxe8LyfOAjPlH9iB0gv5RIN1GBLFjhC7nw3UrVZng4.
ECDSA key fingerprint is MD5:2e:97:50:30:c7:83:8b:93:c4:e4:e2:38:ec:d9:97:a2.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '172.25.2.7' (ECDSA) to the list of known hosts.
Last login: Fri Jun  5 09:32:00 2020
[[email protected] ~]$ 
           
[[email protected] ~]$ cd hadoop
[[email protected] hadoop]$ cd etc/hadoop/
[[email protected] hadoop]$ vim core-site.xml 

指定 hdfs 的 namenode 為 masters (名稱可自定義)

<configuration>
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://masters<</value>
    </property>
</configuration>

指定 zookeeper 叢集主機位址 
<property>
<name>ha.zookeeper.quorum</name>
<value>172.25.2.4:2181,172.25.2.5:2181,172.25.2.6:2181</value>
</property>
</configuration>
           

編輯控制 hdfs的檔案

1.指定 hdfs 的 nameservices 為 masters,和 core-site.xml 檔案中的設定保持一
緻 
<property>
<name>dfs.nameservices</name>
<value>masters</value>
</property>

2. masters 下面有兩個 namenode 節點,分别是 h1 和 h2 (名稱可自定義)
<property>
<name>dfs.ha.namenodes.masters</name>
<value>h1,h2</value>
</property>

3.<!-- 指定 h1 節點的 rpc 通信位址 -->
<property>
<name>dfs.namenode.rpc-address.masters.h1</name>
<value>172.25.2.3:9000</value>
</property>

4.<!-- 指定 h1 節點的 http 通信位址 --> web界面的通信位址
<property>
<name>dfs.namenode.http-address.masters.h
<value>172.25.2.3:9870</value>
</property>


5.<!-- 指定 h2 節點的 rpc 通信位址 -->
<property>
<name>dfs.namenode.rpc-address.masters.h2</name>
<value>172.25.2.7:9000</value>
</property>

6.<!-- 指定 h2 節點的 http 通信位址 -->
<property>
<name>dfs.namenode.http-address.masters.h2</name>
<value>172.25.2.7:9870</value>
</property>

7.<!-- 指定 NameNode 中繼資料在 JournalNode 上的存放位置 --> 在ser4 5 6 上

<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://172.25.0.2:8485;172.25.0.3:8485;172.25.0.4:8485/masters</value>
</property>

8.<!-- 指定 JournalNode 在本地磁盤存放資料的位置 -->
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/tmp/journaldata</value>
</property>

9.<!-- 開啟 NameNode 失敗自動切換 -->
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>

10.<!-- 配置失敗自動切換實作方式 -->
<property>
<name>dfs.client.failover.proxy.provider.masters</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>

</property>

11.<!-- 配置隔離機制方法,每個機制占用一行-->
<property>
<name>dfs.ha.fencing.methods</name>
<value>
sshfence
shell(/bin/true)
</value>
</property>


12.<!-- 使用 sshfence 隔離機制時需要 ssh 免密碼 -->
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/home/yxx/.ssh/id_rsa</value>
</property>

13.<!-- 配置 sshfence 隔離機制逾時時間 -->
<property>
<name>dfs.ha.fencing.ssh.connect-timeout</name>
<value>30000</value>
</property>
</configuration>
           

啟動 hdfs 叢集

啟動 hdfs 叢集(按順序啟動)

1)在三個 DN 上依次啟動 zookeeper 叢集

$ bin/zkServer.sh start
[[email protected] ~]$ jps
1222 QuorumPeerMain
1594 Jps
           

2)在三個 DN 上依次啟動 journalnode(第一次啟動 hdfs 必須先啟動 journalnode)

在ser5 ser4ser6 上

[[email protected] ~]$ hdfs --daemon start  journalnode
[[email protected] ~]$ jps 
14594 JournalNode
14610 Jps
13983 QuorumPeerMain
           

3)格式化 HDFS 叢集

[[email protected] hadoop]$ hdfs namenode  -format
Namenode 資料預設存放在/tmp,需要把資料拷貝到 h2

$ scp -r /tmp/hadoop-yxx 172.25.2.7:/tmp
           

格式化之後發現報錯

2020-06-05 10:35:12,461 INFO util.ExitUtil: Exiting with status 1: org.apache.hadoop.hdfs.qjournal.client.QuorumException: Unable to check if JNs are ready for formatting. 2 exceptions thrown:
172.25.2.5:8485: Call From ser3/172.25.2.3 to ser5:8485 failed on connection exception: java.net.ConnectException: Connection refused; For more details see:  http://wiki.apache.org/hadoop/ConnectionRefused
172.25.2.6:8485: Call From ser3/172.25.2.3 to ser6:8485 failed on connection exception: java.net.ConnectException: Connection refused; For more details see:  http://wiki.apache.org/hadoop/ConnectionRefused
2020-06-05 10:35:12,470 INFO namenode.NameNode: SHUTDOWN_MSG: 
/************************************************************
SHUTDOWN_MSG: Shutting down NameNode at ser3/172.25.2.3
************************************************************/
           

原因是journalnode 也就是nn沒有啟動成功,重新開機之後正常

2020-06-05 10:48:40,593 INFO common.Storage: Storage directory /tmp/hadoop-yxx/dfs/name has been successfully formatted
           
[[email protected] ~]$ netstat -antlp |grep 8485
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
tcp        0      0 0.0.0.0:8485            0.0.0.0:*               LISTEN      14978/java      
           
[[email protected] ~]$ ll -d /tmp/journaldata/
drwxrwxr-x 3 yxx yxx 21 Jun  5 10:48 /tmp/journaldata/
           

格式化是在ser3上進行的,但是此時ser7上還沒有

[[email protected] hadoop]$ scp -r /tmp/hadoop-yxx 172.25.2.7:/tmp
VERSION                              100%  213    73.8KB/s   00:00    
seen_txid                            100%    2     1.0KB/s   00:00    
fsimage_0000000000000000000.md5      100%   62    28.5KB/s   00:00    
fsimage_0000000000000000000          100%  398    89.0KB/s   00:00   
           
  1. 格式化 zookeeper (隻需在 h1 上執行即可)
[[email protected] ~]$ hdfs  zkfc -formatZK
           

(注意大小寫)

4)啟動 hdfs 叢集(隻需在 h1 上執行即可)

[[email protected] ~]$ cd  hadoop
[[email protected] hadoop]$  sbin/start-dfs.sh
Starting namenodes on [ser3 ser7]
ser7: Warning: Permanently added 'ser7' (ECDSA) to the list of known hosts.
Starting datanodes
Starting journal nodes [ser5 ser4 ser6]
ser5: Warning: Permanently added 'ser5' (ECDSA) to the list of known hosts.
ser6: Warning: Permanently added 'ser6' (ECDSA) to the list of known hosts.
ser4: Warning: Permanently added 'ser4' (ECDSA) to the list of known hosts.
ser4: journalnode is running as process 15030.  Stop it first.
ser6: journalnode is running as process 15044.  Stop it first.
ser5: journalnode is running as process 14978.  Stop it first.
Starting ZK Failover Controllers on NN hosts [ser3 ser7]


[[email protected] hadoop]$ cd etc/hadoop/
[[email protected] hadoop]$ cat workers 
172.25.2.4
172.25.2.5
172.25.2.6


ser3和ser7啟動的是nn和故障控制器
[[email protected] hadoop]$ jps 
15937 Jps
15833 DFSZKFailoverController
15470 NameNode

[[email protected] tmp]$ jps 
30304 Jps
30164 DFSZKFailoverController #故障控制器
30090 NameNode

Datanode 在ser4 ser5 ser6 上
[[email protected] ~]$ jps 
16912 Jps
16872 JournalNode
16763 DataNode
13983 QuorumPeerMain
[[email protected] hadoop]$ hdfs dfs -ls

發現每個blocak存儲三份

           

進行 測試

在日志節點的master上

[zk: localhost:2181(CONNECTED) 0] ls /
[zookeeper, hadoop-ha]
[zk: localhost:2181(CONNECTED) 1] cd  /hadoop-ha/masters/Active

ActiveBreadCrumb           ActiveStandbyElectorLock


[zk: localhost:2181(CONNECTED) 3] get /hadoop-ha/masters/ActiveBreadCrumb

masters h1 ser3   #可以看到master裡的h1是活躍的
cZxid = 0x100000008
ctime = Fri Jun 05 10:55:40 CST 2020
mZxid = 0x100000017
mtime = Fri Jun 05 11:03:24 CST 2020
pZxid = 0x100000008
cversion = 0
dataVersion = 2
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 25
numChildren = 0
           

測試

[[email protected] hadoop]$ hdfs dfs -mkdir /user
[[email protected] hadoop]$ hdfs dfs -mkdir /user/yxx
[[email protected] hadoop]$ hdfs dfs -ls
[[email protected] hadoop]$ hdfs dfs -put bigfile 
           

測試nn的高可用

Hadoop(五) (Hadoop+zookeeper實作hdfs及yarn的高可用)實驗簡介
Hadoop(五) (Hadoop+zookeeper實作hdfs及yarn的高可用)實驗簡介

把ser3的nn程序關閉

[[email protected] hadoop]$ jps 
20248 Jps
20107 DFSZKFailoverController
19759 NameNode
[[email protected] hadoop]$ kill 19759
[[email protected] hadoop]$ jps 
20107 DFSZKFailoverController
20267 Jps
[[email protected] hadoop]$ 
           

此時ser7由standby變成了 activebackup

Hadoop(五) (Hadoop+zookeeper實作hdfs及yarn的高可用)實驗簡介
在ser5上再進行檢視
[zk: localhost:2181(CONNECTED) 4] get /hadoop-ha/masters/ActiveBreadCrumb

mastersh2 ser7   # ser7成為activebackup
cZxid = 0x100000008
ctime = Fri Jun 05 10:55:40 CST 2020
mZxid = 0x10000002f
mtime = Fri Jun 05 11:44:06 CST 2020
pZxid = 0x100000008
cversion = 0
dataVersion = 6
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 25
numChildren = 0
[zk: localhost:2181(CONNECTED) 5]
           

注意:

這是hadoop自帶的高可用機制

如何恢複ser3

[[email protected] hadoop]$ hdfs --daemon start namenode
[[email protected] hadoop]$ jps
20472 Jps
20107 DFSZKFailoverController
20397 NameNode
           

再次上線,ser3隻能成為standby

Hadoop(五) (Hadoop+zookeeper實作hdfs及yarn的高可用)實驗簡介

到此 hdfs 的高可用完成。接下來看看 yarn 的高可用。

yarn的高可用

1) 編輯 mapred-site.xml 檔案
<configuration>
<!-- 指定 yarn 為 MapReduce 的架構 -->
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
</configuration>
2)編輯 yarn-site.xml 檔案
<configuration>
<!-- 配置可以在 nodemanager 上運作 mapreduce 程式 -->
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<!-- 激活 RM 高可用 -->
<property>
<name>yarn.resourcemanager.ha.enabled</name>
<value>true</value>
</property><!-- 指定 RM 的叢集 id -->
<property>
<name>yarn.resourcemanager.cluster-id</name>
<value>RM_CLUSTER</value>
</property>
<!-- 定義 RM 的節點-->
<property>
<name>yarn.resourcemanager.ha.rm-ids</name>
<value>rm1,rm2</value>
</property>
<!-- 指定 RM1 的位址 -->
<property>
<name>yarn.resourcemanager.hostname.rm1</name>
<value>172.25.2.3</value>
</property>
<!-- 指定 RM2 的位址 -->
<property>
<name>yarn.resourcemanager.hostname.rm2</name>
<value>172.25.2.7</value>
</property>
<!-- 激活 RM 自動恢複 -->
<property>
<name>yarn.resourcemanager.recovery.enabled</name>
<value>true</value>
</property>
<!-- 配置 RM 狀态資訊存儲方式,有 MemStore 和 ZKStore-->
<property>
<name>yarn.resourcemanager.store.class</name>
<value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</
value>
</property>
<!-- 配置為 zookeeper 存儲時,指定 zookeeper 叢集的位址 -->
<property>
<name>yarn.resourcemanager.zk-address</name>
<value>172.25.0.2:2181,172.25.0.3:2181,172.25.0.4:2181</value>
</property>
</configuration>

3)啟動 yarn 服務
$ sbin/start-yarn.sh
[[email protected] hadoop]$ jps
6559 Jps
2163 NameNode
1739 DFSZKFailoverController5127 ResourceManager
RM2 上需要手動啟動
$ sbin/yarn-daemon.sh start resourcemanager
[[email protected] hadoop]$ jps
1191 NameNode
3298 Jps
1293 DFSZKFailoverController
2757 ResourceManager
最好是把 RM 與 NN 分離運作,這樣可以更好的保證程式的運作性能。
4) 測試 yarn 故障切換
[[email protected] hadoop]$ jps
5918 Jps
2163 NameNode
1739 DFSZKFailoverController
5127 ResourceManager
[[email protected] hadoop]$ kill -9 5127
           

真實

[[email protected] hadoop]$ sbin/start-yarn.sh
Starting resourcemanagers on [ 172.25.2.3 172.25.2.7]
Starting nodemanagers
           
Hadoop(五) (Hadoop+zookeeper實作hdfs及yarn的高可用)實驗簡介
Hadoop(五) (Hadoop+zookeeper實作hdfs及yarn的高可用)實驗簡介

ser7是standby的

Hadoop(五) (Hadoop+zookeeper實作hdfs及yarn的高可用)實驗簡介
在ser5上
[zk: localhost:2181(CONNECTED) 5] get /yarn-leader-election/RM_CLUSTER/ActiveBreadCrumb


RM_CLUSTERrm1
cZxid = 0x10000003b
ctime = Fri Jun 05 12:11:57 CST 2020
mZxid = 0x10000003b
mtime = Fri Jun 05 12:11:57 CST 2020
pZxid = 0x10000003b
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 17
numChildren = 0
[zk: localhost:2181(CONNECTED) 6]
           

測試故障轉移

[[email protected] hadoop]$ jps 
21690 Jps
20107 DFSZKFailoverController
20397 NameNode
21261 ResourceManager
[[email protected] hadoop]$ kill 21261
[[email protected] hadoop]$ jps 
20107 DFSZKFailoverController
20397 NameNode
21709 Jps
           

此時ser7成功activebackup

Hadoop(五) (Hadoop+zookeeper實作hdfs及yarn的高可用)實驗簡介

如何恢複ser3的rm?

[[email protected] hadoop]$ yarn --daemon start resourcemanager
           

再次上線成為standby

Hadoop(五) (Hadoop+zookeeper實作hdfs及yarn的高可用)實驗簡介