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的高可用)_第1张图片在任何时候,集群中只有一个 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上

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

在新开的ser7上

[root@ser7 ~]# yum install nfs-utils -y
[root@ser7 ~]# useradd yxx
[root@ser7 ~]# id yxx
uid=1001(yxx) gid=1001(yxx) groups=1001(yxx)
[root@ser7 ~]# 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

[root@ser7 ~]# systemctl start rpcbind
[root@ser7 ~]# showmount -e 172.25.2.3
Export list for 172.25.2.3:
/home/yxx *
[root@ser7 ~]# 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

[yxx@ser3 ~]$ tar zxf zookeeper-3.4.9.tar.gz 
[yxx@ser3 ~]$ 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/*

[yxx@ser4 ~]$ cd zookeeper-3.4.9/
[yxx@ser4 zookeeper-3.4.9]$ cd conf/
[yxx@ser4 conf]$ ls
configuration.xsl  log4j.properties  zoo_sample.cfg
[yxx@ser4 conf]$ cp zoo_sample.cfg zoo.cfg
[yxx@ser4 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文件

[yxx@ser4 conf]$ mkdir /tmp/zookeeper 
[yxx@ser4 conf]$ echo 1  > /tmp/zookeeper/myid

[yxx@ser5 conf]$ mkdir /tmp/zookeeper
[yxx@ser5 conf]$ echo 2 > /tmp/zookeeper/myid

[yxx@ser6 ~]$ mkdir /tmp/zookeeper
[yxx@ser6 ~]$ echo 3 > /tmp/zookeeper/myid

在各个节点(ser4 ,ser5 ser6)启动进程

[yxx@ser4 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是领导

[yxx@ser5 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

[yxx@ser4 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

连接

[yxx@ser6 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

[yxx@ser3 ~]$ 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
[yxx@ser7 ~]$ 

[yxx@ser3 ~]$ cd hadoop
[yxx@ser3 hadoop]$ cd etc/hadoop/
[yxx@ser3 hadoop]$ vim core-site.xml 

指定 hdfs 的 namenode 为 masters (名称可自定义)


    
        fs.defaultFS
        hdfs://masters<
    


指定 zookeeper 集群主机地址 

ha.zookeeper.quorum
172.25.2.4:2181,172.25.2.5:2181,172.25.2.6:2181


编辑控制 hdfs的文件

1.指定 hdfs 的 nameservices 为 masters,和 core-site.xml 文件中的设置保持一
致 

dfs.nameservices
masters


2. masters 下面有两个 namenode 节点,分别是 h1 和 h2 (名称可自定义)

dfs.ha.namenodes.masters
h1,h2


3.

dfs.namenode.rpc-address.masters.h1
172.25.2.3:9000


4. web界面的通信地址

dfs.namenode.http-address.masters.h
172.25.2.3:9870



5.

dfs.namenode.rpc-address.masters.h2
172.25.2.7:9000


6.

dfs.namenode.http-address.masters.h2
172.25.2.7:9870


7. 在ser4 5 6 上


dfs.namenode.shared.edits.dir
qjournal://172.25.0.2:8485;172.25.0.3:8485;172.25.0.4:8485/masters


8.

dfs.journalnode.edits.dir
/tmp/journaldata


9.

dfs.ha.automatic-failover.enabled
true


10.

dfs.client.failover.proxy.provider.masters
org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider



11.

dfs.ha.fencing.methods

sshfence
shell(/bin/true)




12.

dfs.ha.fencing.ssh.private-key-files
/home/yxx/.ssh/id_rsa


13.

dfs.ha.fencing.ssh.connect-timeout
30000


启动 hdfs 集群

启动 hdfs 集群(按顺序启动)

1)在三个 DN 上依次启动 zookeeper 集群

$ bin/zkServer.sh start
[hadoop@server2 ~]$ jps
1222 QuorumPeerMain
1594 Jps

2)在三个 DN 上依次启动 journalnode(第一次启动 hdfs 必须先启动 journalnode)
在ser5 ser4ser6 上

[yxx@ser4 ~]$ hdfs --daemon start  journalnode
[yxx@ser4 ~]$ jps 
14594 JournalNode
14610 Jps
13983 QuorumPeerMain

3)格式化 HDFS 集群

[yxx@ser3 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
[yxx@ser5 ~]$ 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      
[yxx@ser5 ~]$ ll -d /tmp/journaldata/
drwxrwxr-x 3 yxx yxx 21 Jun  5 10:48 /tmp/journaldata/

格式化是在ser3上进行的,但是此时ser7上还没有

[yxx@ser3 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 上执行即可)
[yxx@ser3 ~]$ hdfs  zkfc -formatZK

(注意大小写)

4)启动 hdfs 集群(只需在 h1 上执行即可)

[yxx@ser3 ~]$ cd  hadoop
[yxx@ser3 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]


[yxx@ser3 hadoop]$ cd etc/hadoop/
[yxx@ser3 hadoop]$ cat workers 
172.25.2.4
172.25.2.5
172.25.2.6


ser3和ser7启动的是nn和故障控制器
[yxx@ser3 hadoop]$ jps 
15937 Jps
15833 DFSZKFailoverController
15470 NameNode

[yxx@ser7 tmp]$ jps 
30304 Jps
30164 DFSZKFailoverController #故障控制器
30090 NameNode

Datanode 在ser4 ser5 ser6 上
[yxx@ser4 ~]$ jps 
16912 Jps
16872 JournalNode
16763 DataNode
13983 QuorumPeerMain
[yxx@ser3 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

测试

[yxx@ser3 hadoop]$ hdfs dfs -mkdir /user
[yxx@ser3 hadoop]$ hdfs dfs -mkdir /user/yxx
[yxx@ser3 hadoop]$ hdfs dfs -ls
[yxx@ser3 hadoop]$ hdfs dfs -put bigfile 

测试nn的高可用
Hadoop(五) (Hadoop+zookeeper实现hdfs及yarn的高可用)_第2张图片Hadoop(五) (Hadoop+zookeeper实现hdfs及yarn的高可用)_第3张图片把ser3的nn进程关闭

[yxx@ser3 hadoop]$ jps 
20248 Jps
20107 DFSZKFailoverController
19759 NameNode
[yxx@ser3 hadoop]$ kill 19759
[yxx@ser3 hadoop]$ jps 
20107 DFSZKFailoverController
20267 Jps
[yxx@ser3 hadoop]$ 

此时ser7由standby变成了 activebackup
Hadoop(五) (Hadoop+zookeeper实现hdfs及yarn的高可用)_第4张图片

在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

[yxx@ser3 hadoop]$ hdfs --daemon start namenode
[yxx@ser3 hadoop]$ jps
20472 Jps
20107 DFSZKFailoverController
20397 NameNode

再次上线,ser3只能成为standby
Hadoop(五) (Hadoop+zookeeper实现hdfs及yarn的高可用)_第5张图片到此 hdfs 的高可用完成。接下来看看 yarn 的高可用。

yarn的高可用

1) 编辑 mapred-site.xml 文件



mapreduce.framework.name
yarn


2)编辑 yarn-site.xml 文件



yarn.nodemanager.aux-services
mapreduce_shuffle



yarn.resourcemanager.ha.enabled
true


yarn.resourcemanager.cluster-id
RM_CLUSTER



yarn.resourcemanager.ha.rm-ids
rm1,rm2



yarn.resourcemanager.hostname.rm1
172.25.2.3



yarn.resourcemanager.hostname.rm2
172.25.2.7



yarn.resourcemanager.recovery.enabled
true



yarn.resourcemanager.store.class
org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore



yarn.resourcemanager.zk-address
172.25.0.2:2181,172.25.0.3:2181,172.25.0.4:2181



3)启动 yarn 服务
$ sbin/start-yarn.sh
[hadoop@server1 hadoop]$ jps
6559 Jps
2163 NameNode
1739 DFSZKFailoverController5127 ResourceManager
RM2 上需要手动启动
$ sbin/yarn-daemon.sh start resourcemanager
[hadoop@server5 hadoop]$ jps
1191 NameNode
3298 Jps
1293 DFSZKFailoverController
2757 ResourceManager
最好是把 RM 与 NN 分离运行,这样可以更好的保证程序的运行性能。
4) 测试 yarn 故障切换
[hadoop@server1 hadoop]$ jps
5918 Jps
2163 NameNode
1739 DFSZKFailoverController
5127 ResourceManager
[hadoop@server1 hadoop]$ kill -9 5127

真实

[yxx@ser3 hadoop]$ sbin/start-yarn.sh
Starting resourcemanagers on [ 172.25.2.3 172.25.2.7]
Starting nodemanagers

Hadoop(五) (Hadoop+zookeeper实现hdfs及yarn的高可用)_第6张图片Hadoop(五) (Hadoop+zookeeper实现hdfs及yarn的高可用)_第7张图片
ser7是standby的
Hadoop(五) (Hadoop+zookeeper实现hdfs及yarn的高可用)_第8张图片


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

测试故障转移

[yxx@ser3 hadoop]$ jps 
21690 Jps
20107 DFSZKFailoverController
20397 NameNode
21261 ResourceManager
[yxx@ser3 hadoop]$ kill 21261
[yxx@ser3 hadoop]$ jps 
20107 DFSZKFailoverController
20397 NameNode
21709 Jps

此时ser7成功activebackup
Hadoop(五) (Hadoop+zookeeper实现hdfs及yarn的高可用)_第9张图片
如何恢复ser3的rm?

[yxx@ser3 hadoop]$ yarn --daemon start resourcemanager

再次上线成为standby
Hadoop(五) (Hadoop+zookeeper实现hdfs及yarn的高可用)_第10张图片

你可能感兴趣的:(企业实战学习笔记)