Hadoop高可用架构

再添加一台主机node5,作为主备节点之一

[root@node5 ~]# vim /etc/hosts
192.168.117.131 node1
192.168.117.132 node2
192.168.117.133 node3
192.168.117.134 node4
192.168.117.135 node5
[root@node5 ~]# yum install -y nfs-utils
[root@node5 ~]# useradd hadoop
[root@node5 ~]# echo westos |passwd --stdin hadoop
[root@node5 ~]# mount 192.168.117.131:/home/hadoop /home/hadoop
[root@node5 ~]# su - hadoop

zookeeper集群部署

开始前各节点清空数据目录

$ rm -fr /tmp/*

安装zookeeper

[hadoop@node1 ~]$ logout
[root@node1 ~]# ls
apache-zookeeper-3.8.6-bin.tar.gz
[root@node1 ~]# mv apache-zookeeper-3.8.6-bin.tar.gz /home/hadoop/
[root@node1 ~]# su - hadoop
[hadoop@node1 ~]$ tar zxf apache-zookeeper-3.8.6-bin.tar.gz
[hadoop@node1 ~]$ cd apache-zookeeper-3.8.6-bin/
[hadoop@node1 apache-zookeeper-3.8.6-bin]$ cd conf/
[hadoop@node1 conf]$ cp zoo_sample.cfg zoo.cfg
[hadoop@node1 conf]$ vim zoo.cfg
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/tmp/zookeeper
clientPort=2181
server.1=192.168.117.132:2888:3888
server.2=192.168.117.133:2888:3888
server.3=192.168.117.134:2888:3888

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

[hadoop@node2 conf]$ mkdir /tmp/zookeeper
[hadoop@node2 conf]$ echo 1 > /tmp/zookeeper/myid

[hadoop@node3 ~]$ mkdir /tmp/zookeeper
[hadoop@node3 ~]$ echo 2 > /tmp/zookeeper/myid

[hadoop@node4 ~]$ mkdir /tmp/zookeeper
[hadoop@node4 ~]$ echo 3 > /tmp/zookeeper/myid

在各节点启动服务:(server2、server3、server4)

启动服务
$ bin/zkServer.sh start
查看节点状态
$ bin/zkServer.sh status

Hadoop配置

编辑 core-site.xml

[hadoop@node1 ~]$ cd hadoop/etc/hadoop/
[hadoop@node1 hadoop]$ vim core-site.xml
<configuration>
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://masters</value>
    </property>

<property>
<name>ha.zookeeper.quorum</name>
<value>192.168.117.132:2181,192.168.117.133:2181,192.168.117.134:2181</value>
</property>

</configuration>

编辑 hdfs-site.xml

[hadoop@node1 hadoop]$ vim hdfs-site.xml
<configuration>
    <property>
        <name>dfs.replication</name>
        <value>3</value>
    </property>

<property>
<name>dfs.nameservices</name>
<value>masters</value>
</property>

<property>
<name>dfs.ha.namenodes.masters</name>
<value>h1,h2</value>
</property>

<property>
<name>dfs.namenode.rpc-address.masters.h1</name>
<value>192.168.117.131:9000</value>
</property>

<property>
<name>dfs.namenode.http-address.masters.h1</name>
<value>192.168.117.131:9870</value>
</property>

<property>
<name>dfs.namenode.rpc-address.masters.h2</name>
<value>192.168.117.135:9000</value>
</property>

<property>
<name>dfs.namenode.http-address.masters.h2</name>
<value>192.168.117.135:9870</value>
</property>

<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://192.168.117.132:8485;192.168.117.133:8485;192.168.117.134:8485/masters</value>
</property>

<property>
<name>dfs.journalnode.edits.dir</name>
<value>/tmp/journaldata</value>
</property>

<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>

<property>
<name>dfs.client.failover.proxy.provider.masters</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>

<property>
<name>dfs.ha.fencing.methods</name>
<value>
sshfence
shell(/bin/true)
</value>
</property>

<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/home/hadoop/.ssh/id_rsa</value>
</property>

<property>
<name>dfs.ha.fencing.ssh.connect-timeout</name>
<value>30000</value>
</property>

</configuration>

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

1)确认启动zookeeper集群(server2、server3、server4)

[hadoop@node2 apache-zookeeper-3.8.6-bin]$ jps
2515 QuorumPeerMain
2668 Jps

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

[hadoop@node2 apache-zookeeper-3.8.6-bin]$ cd
[hadoop@node2 ~]$ cd hadoop
[hadoop@node2 hadoop]$ bin/hdfs --daemon start journalnode
[hadoop@node2 hadoop]$ jps
2721 JournalNode
2515 QuorumPeerMain
2763 Jps

3)格式化HDFS集群(server1上执行)

[hadoop@node1 hadoop]$ pwd
/home/hadoop/hadoop
[hadoop@node1 hadoop]$ bin/hdfs namenode -format
Namenode数据默认存放在/tmp,需要把数据拷贝到h2
[hadoop@node1 hadoop]$ scp -r /tmp/hadoop-hadoop node5:/tmp

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

[hadoop@node1 hadoop]$ bin/hdfs zkfc -formatZK  (注意大小写)

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

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

image-20260824111831759

6)查看各节点状态

[hadoop@node1 hadoop]$ jps
4405 Jps
3990 NameNode
4350 DFSZKFailoverController

[hadoop@node5 ~]$ jps
1685 NameNode
1768 DFSZKFailoverController
4511 Jps

[hadoop@node2 hadoop]$ jps
2721 JournalNode
2961 Jps
2515 QuorumPeerMain
2836 DataNode
...

主节点

image-20260824112041510

备节点

image-20260824112119266

7)测试故障自动切换

[hadoop@node1 hadoop]$ jps
3990 NameNode
4454 Jps
4350 DFSZKFailoverController
[hadoop@node1 hadoop]$ kill -9 3990

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

image-20260824112314137

[hadoop@node1 hadoop]$ bin/hdfs --daemon start namenode

启动h1上的namenode,此时为standby状态

image-20260824112448947

yarn高可用配置

编辑 mapred-site.xml

[hadoop@node1 hadoop]$ pwd
/home/hadoop/hadoop/etc/hadoop
[hadoop@node1 hadoop]$ vim mapred-site.xml
<configuration>
    <property>
        <name>mapreduce.framework.name</name>
        <value>yarn</value>
    </property>
    <property>
        <name>mapreduce.application.classpath</name>
        <value>$HADOOP_MAPRED_HOME/share/hadoop/mapreduce/*:$HADOOP_MAPRED_HOME/share/hadoop/mapreduce/lib/*</value>
    </property>
</configuration>

编辑 yarn-site.xml

[hadoop@node1 hadoop]$ vim yarn-site.xml
<configuration>
    <property>
        <name>yarn.nodemanager.aux-services</name>
        <value>mapreduce_shuffle</value>
    </property>
    <property>
        <name>yarn.nodemanager.env-whitelist</name>
        <value>JAVA_HOME,HADOOP_COMMON_HOME,HADOOP_HDFS_HOME,HADOOP_CONF_DIR,CLASSPATH_PREPEND_DISTCACHE,HADOOP_YARN_HOME,HADOOP_HOME,PATH,LANG,TZ,HADOOP_MAPRED_HOME</value>
    </property>

<property>
<name>yarn.resourcemanager.ha.enabled</name>
<value>true</value>
</property>

<property>
<name>yarn.resourcemanager.cluster-id</name>
<value>RM_CLUSTER</value>
</property>

<property>
<name>yarn.resourcemanager.ha.rm-ids</name>
<value>rm1,rm2</value>
</property>

<property>
<name>yarn.resourcemanager.hostname.rm1</name>
<value>node1</value>
</property>

<property>
<name>yarn.resourcemanager.hostname.rm2</name>
<value>node5</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>
<name>yarn.resourcemanager.zk-address</name>
<value>192.168.117.132:2181,192.168.117.133:2181,192.168.117.134:2181</value>
</property>
</configuration>

</configuration>

启动yarn服务

[hadoop@node1 hadoop]$ sbin/start-yarn.sh
Starting resourcemanagers on [ node1 node5]
Starting nodemanagers
[hadoop@node1 hadoop]$ jps
4528 NameNode
8615 ResourceManager
8936 Jps
4350 DFSZKFailoverController

主节点

image-20260824144300726

备节点

image-20260824144348280

测试yarn故障切换

b[hadoop@node1 hadoop]$ jps
4528 NameNode
8615 ResourceManager
8936 Jps
4350 DFSZKFailoverController
[hadoop@node1 hadoop]$ kill -9 8615

node5切换为主节点

image-20260824144527991

稍后手动恢复rm

[hadoop@node1 hadoop]$ bin/yarn --daemon start resourcemanager

node1恢复为备节点

image-20260824144719922

主备切换原理:

下面我们就来看看YARN是如何实现多个ResourceManager之间的主备切换的。

​ 创建锁节点 在ZooKeeper上会有一个/yarn-leader-election/RM_CLUSTER的锁节点,所有的 ResourceManager 在启动的时候,都会去竞争写一个 Lock 子节点:/yarn-leader-election/RM_CLUSTER/ActiveBreadCrumb,该节点是临时节点。ZooKeepr能够为我们保证最终只有一个 ResourceManager 能够创建成功。创建成功的那个ResourceManager就切换为Active状态,没有成功的那些ResourceManager则切换为Standby状态。

[hadoop@node2 hadoop]$ cd
[hadoop@node2 ~]$ cd apache-zookeeper-3.8.6-bin/
[hadoop@server2 apache-zookeeper-3.8.6-bin]$ bin/zkCli.sh
[zk: localhost:2181(CONNECTED) 0] ls /yarn-leader-election
[RM_CLUSTER]
[zk: localhost:2181(CONNECTED) 1] get /yarn-leader-election/RM_CLUSTER/ActiveBreadCrumb
RM_CLUSTERrm2

可以看到此时集群中ResourceManager2为Active

image-20260824144924546

​ 注 册 Watcher 监 听 所 有 Standby 状 态 的 ResourceManager 都 会 向/yarn-leader-election/RM_CLUSTER/ActiveBreadCrumb节点注册一个节点变更的Watcher监听,利用临时节点的特性,能够快速感知到Active状态的ResourceManager的运行情况。

​ 主备切换当Active状态的ResourceManager出现诸如宕机或重启的异常情况时,其在ZooKeeper 上 连 接 的 客 户 端 会 话 就 会 失 效 , 因 此/yarn-leader-election/RM_CLUSTER/ActiveBreadCrumb节点就会被删除。此时其余各个Standby状态的ResourceManager就都会接收到来自ZooKeeper服务端的Watcher事件通知,然后会重复进行步骤1的操作。

​ 以上就是利用ZooKeeper来实现ResourceManager的主备切换的过程,实现了ResourceManager的HA。

HDFS中NameNode的HA的实现原理跟YARN中ResourceManager的HA的实现原理相同。其锁节点为/hadoop-ha/masters/ActiveBreadCrumb

资源回收

node1

[hadoop@node1 hadoop]$ sbin/stop-yarn.sh
[hadoop@node1 hadoop]$ sbin/stop-dfs.sh
[hadoop@node1 hadoop]$ logout
[root@node1 ~]# rm -fr /tmp/*
[root@node1 ~]# systemctl disable --now nfs

node2、node3、node4

[hadoop@node2 apache-zookeeper-3.8.6-bin]$ bin/zkServer.sh stop
[hadoop@node2 apache-zookeeper-3.8.6-bin]$ logout
[root@node2 ~]# rm -fr /tmp/*
[root@node2 ~]# umount /home/hadoop

node5

[hadoop@node5 ~]$ logout
[root@node5 ~]# rm -fr /tmp/*
[root@node5 ~]# umount /home/hadoop

这样下次重启时就不会出现问题了

更多推荐