hadoop+zookeeper高可用

    xiaoxiao2022-07-13  151

    前言:环境基于nfs文件共享,server1上安装了hadoop,部署的相关服务参考我的上一篇博客

    环境RHEL 7.3h1172.25.1.1(server1)h2172.25.1.5(server5)DN1172.25.1.2(server2)DN2172.25.1.3(server3)DN3172.25.1.4(server4)

    在典型的 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 的位置,并向它们发送块文件所在的位置及心跳,如下图所示: 在任何时候,集群中只有一个 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 集群至少三台,总节点数为奇数个。

    一、hdfs实现hadoop+zookeeper的高可用

    1.新开一个服务器server5并安装nfs-util,

    [root@server5 ~]# yum install nfs-utils -y

    2.新建hadoop用户:

    [root@server5 ~]# useradd hadoop

    3.然后在五个服务端开启nfs服务,在server2、server3、server4、server5端将172.25.1.1:/home/hadoop目录挂载到本机/home/hadoop目录下

    [root@server5 ~]# systemctl start rpcbind [root@server5 ~]# systemctl start nfs [root@server5 ~]# mount 172.25.1.1:/home/hadoop/ /home/hadoop/

    4.为了实验环境的干净,在五个服务端将之前的环境清理(不是必须):

    [hadoop@server1 hadoop]$ sbin/stop-yarn.sh [hadoop@server1 hadoop]$ sbin/stop-dfs.sh ##1-5server都执行 [hadoop@server1 hadoop]$ rm -fr /tmp/*

    5.在server1端,切换到hadoop用户,解压zookeeper安装包并将zoo_sample.cfg复制为zoo.cfg文件:

    由于其他主机都使用了server1端的nfs文件系统,所以在server1端根目录下的hadoop目录里的所有操作,都会同步到其他4台主机里,也就是说5台机器的/home/hadoop目录内容完全一致。

    [hadoop@server1 ~]$ tar zxf zookeeper-3.4.9.tar.gz [hadoop@server1 ~]$ cd zookeeper-3.4.9 [hadoop@server1 zookeeper-3.4.9]$ cp conf/zoo_sample.cfg conf/zoo.cfg [hadoop@server1 zookeeper-3.4.9]$ ls conf/ configuration.xsl log4j.properties zoo.cfg zoo_sample.cfg [hadoop@server1 zookeeper-3.4.9]$

    编辑zoo.cfg文件,写入集群的三台设备:

    [hadoop@server1 zookeeper-3.4.9]$ cd conf/ [hadoop@server1 conf]$ vim zoo.cfg server.1=172.25.1.2:2888:3888 server.2=172.25.1.3:2888:3888 server.3=172.25.1.4:2888:3888

    6.在三个集群节点:

    各节点配置文件相同,并且需要在/tmp/zookeeper 目录中创建 myid 文件,写入一个唯一的数字,取值范围在 1-255。比如:172.25.45.2 节点的 myid 文件写入数字“1”,此数字与配置文件中的定义保持一致,(server.1=172.25.0.2:2888:3888)其它节点依次类推。

    [hadoop@server2 conf]$ mkdir /tmp/zookeeper [hadoop@server3 conf]$ mkdir /tmp/zookeeper [hadoop@server4 conf]$ mkdir /tmp/zookeeper [hadoop@server2 conf]$ echo 1 > /tmp/zookeeper/myid [hadoop@server3 conf]$ echo 2 > /tmp/zookeeper/myid [hadoop@server4 conf]$ echo 3 > /tmp/zookeeper/myid [hadoop@server2 zookeeper-3.4.9]$ bin/zkServer.sh start [hadoop@server3 zookeeper-3.4.9]$ bin/zkServer.sh start [hadoop@server4 zookeeper-3.4.9]$ bin/zkServer.sh start [hadoop@server2 zookeeper-3.4.9]$ bin/zkServer.sh status ZooKeeper JMX enabled by default Using config: /home/hadoop/zookeeper-3.4.9/bin/../conf/zoo.cfg Mode: follower [hadoop@server3 zookeeper-3.4.9]$ bin/zkServer.sh status ZooKeeper JMX enabled by default Using config: /home/hadoop/zookeeper-3.4.9/bin/../conf/zoo.cfg Mode: follower [hadoop@server4 zookeeper-3.4.9]$ bin/zkServer.sh status ZooKeeper JMX enabled by default Using config: /home/hadoop/zookeeper-3.4.9/bin/../conf/zoo.cfg Mode: leader

    发现server4为liader!

    7.进入命令行

    [hadoop@server2 ~]$ cd zookeeper-3.4.9/bin/ [hadoop@server2 bin]$ ls README.txt zkCli.cmd zkEnv.cmd zkServer.cmd zkCleanup.sh zkCli.sh zkEnv.sh zkServer.sh [hadoop@server2 bin]$ ./zkCli.sh WATCHER:: WatchedEvent state:SyncConnected type:None path:null [zk: localhost:2181(CONNECTED) 0] ls / [zookeeper] [zk: localhost:2181(CONNECTED) 1] ls / [zookeeper] [zk: localhost:2181(CONNECTED) 2] ls /zookeeper [quota] [zk: localhost:2181(CONNECTED) 3] ls /zookeeper/quota [] [zk: localhost:2181(CONNECTED) 4] get /zookeeper/quota cZxid = 0x0 ctime = Thu Jan 01 08:00:00 CST 1970 mZxid = 0x0 mtime = Thu Jan 01 08:00:00 CST 1970 pZxid = 0x0 cversion = 0 dataVersion = 0 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 0 numChildren = 0

    二、配置hadoop

    在server1端:

    1.编辑cpre-site.xml文件

    [hadoop@server1 ~]$ cd hadoop/etc/hadoop/ [hadoop@server1 hadoop]$ vim core-site.xml #指定hdfs的namenode为masters 指定zookeeper集群主机地址 <configuration> <property> <name>fs.defaultFS</name> <value>hdfs://masters</value> </property> <property> <name>ha.zookeeper.quorum</name> <value>172.25.1.2:2181,172.25.1.3:2181,172.25.1.4:2181</value> </property> </configuration>

    2.编辑hdfs-site.xml文件:

    [hadoop@server1 hadoop]$ vim hdfs-site.xml 18 19 <configuration> 20 <property> 21 <name>dfs.replication</name> 22 <value>3</value> 23 </property> 24 指定 hdfs 的 nameservices 为 masters,和 core-site.xml 文件中的设置保持一致 25 <property> 26 <name>dfs.nameservices</name> 27 <value>masters</value> 28 </property> 29 masters 下面有两个 namenode 节点,分别是 h1 和 h2 (名称可自定义) 30 <property> 31 <name>dfs.ha.namenodes.masters</name> 32 <value>h1,h2</value> 33 </property> 34 指定 h1 节点的 rpc 通信地址 35 <property> 36 <name>dfs.namenode.rpc-address.masters.h1</name> 37 <value>172.25.1.1:9000</value> 38 </property> 39 指定 h1 节点的 http 通信地址 40 <property> 41 <name>dfs.namenode.http-address.masters.h1</name> 42 <value>172.25.1.1:50070</value> 43 </property> 44 指定 h2 节点的 rpc 通信地址 45 <property> 46 <name>dfs.namenode.rpc-address.masters.h2</name> 47 <value>172.25.1.5:9000</value> 48 </property> 49 指定 h2 节点的 http 通信地址 50 <property> 51 <name>dfs.namenode.http-address.masters.h2</name> 52 <value>172.25.1.5:50070</value> 53 </property> 54 指定 NameNode 元数据在 JournalNode 上的存放位置 55 <property> 56 <name>dfs.namenode.shared.edits.dir</name> 57 <value>qjournal://172.25.1.2:8485;172.25.1.3:8485;172.25.1.4:8485/masters</value> 58 </property> 59 指定 JournalNode 在本地磁盘存放数据的位置 60 <property> 61 <name>dfs.journalnode.edits.dir</name> 62 <value>/tmp/journaldata</value> 63 </property> 64 开启 NameNode 失败自动切换 65 <property> 66 <name>dfs.ha.automatic-failover.enabled</name> 67 <value>true</value> 68 </property> 69 配置失败自动切换实现方式 70 <property> 71 <name>dfs.client.failover.proxy.provider.masters</name> 72 <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxy Provider</value> 73 </property> 74 配置隔离机制方法,每个机制占用一行 75 <property> 76 <name>dfs.ha.fencing.methods</name> 77 <value> 78 sshfence 79 shell(/bin/true) 80 </value> 81 </property> 82 使用 sshfence 隔离机制时需要 ssh 免密码 83 <property> 84 <name>dfs.ha.fencing.ssh.private-key-files</name> 85 <value>/home/hadoop/.ssh/id_rsa</value> 86 </property> 87 配置 sshfence 隔离机制超时时间 88 <property> 89 <name>dfs.ha.fencing.ssh.connect-timeout</name> 90 <value>30000</value> 91 </property> 92 </configuration>

    3.编辑文件workers:

    [hadoop@server1 hadoop]$ vim workers 172.25.1.2 172.25.1.3 172.25.1.4

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

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

    [hadoop@server2 zookeeper-3.4.9]$ bin/zkServer.sh start

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

    cd /home/hadoop/hadoop

    在server2上

    [hadoop@server2 hadoop]$ sbin/hadoop-daemon.sh start journalnode [hadoop@server2 hadoop]$ jps 13161 Jps 13131 JournalNode 12927 QuorumPeerMain

    在server3上

    [hadoop@server3 ~]$ cd hadoop [hadoop@server3 hadoop]$ sbin/hadoop-daemon.sh start journalnode [hadoop@server3 hadoop]$ jps 12372 Jps 12183 QuorumPeerMain 12332 JournalNode

    在server4上

    [hadoop@server4 hadoop]$ pwd /home/hadoop/hadoop [hadoop@server4 hadoop]$ sbin/hadoop-daemon.sh start journalnode [hadoop@server4 hadoop]$ jps 10930 QuorumPeerMain 11125 Jps 11084 JournalNode [hadoop@server4 hadoop]$

    3)在server1格式化 HDFS 集群 Namenode 数据默认存放在/tmp,需要把数据拷到 h2

    [hadoop@server1 hadoop]$ bin/hdfs namenode -format [hadoop@server1 hadoop]$ scp -r /tmp/hadoop-hadoop 172.25.1.5:/tmp

    4) 格式化 zookeeper (只需在 h1 上执行即可)

    [hadoop@server1 hadoop]$ bin/hdfs zkfc -formatZK

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

    [hadoop@server1 hadoop]$ sbin/start-dfs.sh

    6) 查看各节点状态

    [hadoop@server1 hadoop]$ jps 22536 DFSZKFailoverController 22587 Jps 22174 NameNode [hadoop@server2 hadoop]$ jps 13131 JournalNode 13246 DataNode 12927 QuorumPeerMain 13375 Jps [hadoop@server3 hadoop]$ jps 12576 Jps 12183 QuorumPeerMain 12332 JournalNode 12447 DataNode [hadoop@server4 hadoop]$ jps 10930 QuorumPeerMain 11192 DataNode 11323 Jps 11084 JournalNode [hadoop@server5 ~]$ jps 10784 NameNode 10859 DFSZKFailoverController 10988 Jps

    测试:

    测试故障自动切换

    server1端杀掉namennode进程:

    [hadoop@server1 hadoop]$ jps 22612 Jps 22536 DFSZKFailoverController 22174 NameNode [hadoop@server1 hadoop]$ kill -9 22174

    杀掉 h1主机的 namenode 进程后依然可以访问,此时 h2转为 active 状态接管 namenode

    刷新发现active跳到serverr5上:实现高可用 重新开启server1的namenode:

    [hadoop@server1 hadoop]$ pwd /home/hadoop/hadoop [hadoop@server1 hadoop]$ sbin/hadoop-daemon.sh start namenode WARNING: Use of this script to start HDFS daemons is deprecated. WARNING: Attempting to execute replacement "hdfs --daemon start" instead. [hadoop@server1 hadoop]$ jps 22774 Jps 22536 DFSZKFailoverController 22702 NameNode

    刷新发现server1变成stanby

    二、yarn实现hadoop+zookeeper的高可用

    1、 编辑 mapred-site.xml 文件 指定 yarn 为 MapReduce 的框架

    [hadoop@server1 hadoop]$ cd /home/hadoop/hadoop/etc/hadoop/ [hadoop@server1 hadoop]$ vim mapred-site.xml <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property>

    2、编辑 yarn-site.xml 文件

    [hadoop@server1 hadoop]$ vim yarn-site.xml 15<configuration> 配置可以在 nodemanager 上运行 mapreduce 程序 16 <property> 17 <name>yarn.nodemanager.aux-services</name> 18 <value>mapreduce_shuffle</value> 19 </property> 激活 RM 高可用 20 <property> 21 <name>yarn.resourcemanager.ha.enabled</name> 22 <value>true</value> 23 </property> 指定 RM 的集群 id 24 <property> 25 <name>yarn.resourcemanager.cluster-id</name> 26 <value>RM_CLUSTER</value> 27 </property> 定义 RM 的节点 28 <property> 29 <name>yarn.resourcemanager.ha.rm-ids</name> 30 <value>rm1,rm2</value> 31 </property> 指定 RM1 的地址 32 <property> 33 <name>yarn.resourcemanager.hostname.rm1</name> 34 <value>172.25.1.1</value> 35 </property> 指定 RM2 的地址 36 <property> 37 <name>yarn.resourcemanager.hostname.rm2</name> 38 <value>172.25.1.5</value> 39 </property> 激活 RM 自动恢复 40 <property> 41 <name>yarn.resourcemanager.recovery.enabled</name> 42 <value>true</value> 43 </property> 配置 RM 状态信息存储方式,有 MemStore 和 ZKStore 44 <property> 45 <name>yarn.resourcemanager.store.class</name> 46 <value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value> 48 </property> 配置为 zookeeper 存储时,指定 zookeeper 集群的地址 49 <property> 50 <name>yarn.resourcemanager.zk-address</name> 51 <value>172.25.1.2:2181,172.25.1.3:2181,172.25.1.4:2181</value> 52 </property> 53 <!-- Site specific YARN configuration properties --> 54 55 </configuration>

    3、启动 yarn 服务

    [hadoop@server1 hadoop]$ pwd /home/hadoop/hadoop [hadoop@server1 hadoop]$ sbin/start-yarn.sh Starting resourcemanagers on [ 172.25.1.1 172.25.1.5] Starting nodemanagers [hadoop@server1 hadoop]$ jps 3417 DFSZKFailoverController 3803 ResourceManager 3068 NameNode 3934 Jps

    4、RM2 上需要手动启动

    [hadoop@server5 hadoop]$ pwd /home/hadoop/hadoop [hadoop@server5 hadoop]$ sbin/yarn-daemon.sh start resourcemanager [hadoop@server5 hadoop]$ jps 11329 ResourceManager 10996 DFSZKFailoverController 10933 NameNode 11643 Jps

    最好是把 RM 与 NN 分离运行,这样可以更好的保证程序的运行性能。

    5、查看各个节点的状态

    [hadoop@server1 hadoop]$ jps 13512 Jps 3417 DFSZKFailoverController 3803 ResourceManager 3068 NameNode [hadoop@server5 hadoop]$ jps 11329 ResourceManager 10996 DFSZKFailoverController 10933 NameNode 11643 Jps [hadoop@server2 hadoop]$ jps 1556 QuorumPeerMain 11524 NodeManager 11637 Jps 11225 JournalNode 11327 DataNode [hadoop@server3 hadoop]$ jps 11520 NodeManager 11330 DataNode 11098 QuorumPeerMain 11228 JournalNode 11631 Jps [hadoop@server4 hadoop]$ jps 2066 Jps 1955 NodeManager 1656 JournalNode 1532 QuorumPeerMain 1758 DataNode

    6、测试 yarn 故障切换

    [hadoop@server2 hadoop]$ cd [hadoop@server2 ~]$ cd zookeeper-3.4.9 [hadoop@server2 zookeeper-3.4.9]$ bin/zkCli.sh [zk: localhost:2181(CONNECTED) 11] get /yarn-leader-election/RM_CLUSTER/ActiveBreadCrumb RM_CLUSTERrm2 cZxid = 0x100000042 ctime = Wed May 29 10:14:47 CST 2019 mZxid = 0x100000042 mtime = Wed May 29 10:14:47 CST 2019 pZxid = 0x100000042 cversion = 0 dataVersion = 0 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 17 numChildren = 0

    可以看到我们现在是rm2及172.25.1.5的节点为主节点。

    作测试:

    [hadoop@server5 hadoop]$ jps 12625 NameNode 13747 Jps 12741 DFSZKFailoverController 13371 ResourceManager [hadoop@server5 hadoop]$ kill -9 13371 [hadoop@server5 hadoop]$ jps 12625 NameNode 12741 DFSZKFailoverController 13759 Jps [hadoop@server5 hadoop]$

    我们在rm2的这一端。杀掉ResourceManager进程。

    [hadoop@server2 bin]$ ./zkCli.sh [zk: localhost:2181(CONNECTED) 2] get /yarn-leader-election/RM_CLUSTER/ActiveBreadCrumb RM_CLUSTERrm1 cZxid = 0x100000042 ctime = Wed May 29 10:14:47 CST 2019 mZxid = 0x10000004d mtime = Wed May 29 10:37:26 CST 2019 pZxid = 0x100000042 cversion = 0 dataVersion = 1 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 17 numChildren = 0 [zk: localhost:2181(CONNECTED) 3]

    可以看到现在rm1成为master,高可用配置成功。

    最新回复(0)