目录
- 0.HDFS-HA的工作机制
- 1. HDFS-HA集群配置
- 2. 配置HDFS-HA集群
- 3. 启动HDFS-HA集群
- 4.配置HDFS-HA自动故障转移
- 5. YARN-HA配置
- 4.4.2 配置YARN-HA集群
0.HDFS-HA的工作机制
问题:因为hdfs的中心就是namenode,而我们的集群只有一台服务器安装了nn,如果这台服务器挂掉,整个集群瘫痪,这个就是典型的单点故障,搭建HA其实就是为了解决单点故障问题
解决办法:安装多台nn
此方案有如下问题需要解决?
a)多个nn内部元数据的数据一致性的问题?
引入三台journalnode,来存储nn产生的edits文件,保证多个nn的内部数据一致性问题
b)对外提供服务问题?
多个nn不能同时对外服务,同一时刻仅仅有一个NameNode对外提供服务,当这台工作的nn挂掉以后,剩下的 备胎nn直接顶上给nn定义两个状态,active和standby
c)多个Standby的nn上位问题?
自动故障转移
d)节点状态管理功能?
实现了一个zkfailover,常驻在每一个namenode所在的节点,每一个zkfailover负责监控自己所在NameNode节点,利用zk进行状态标识,当需要进行状态切换时,由zkfailover来负责切换,切换时需要防止brainsplit现象的发
生。
工作机制原理图
自动故障转移为HDFS部署增加了两个新组件:ZooKeeper和ZKFailoverController(ZKFC)进程,如图3-20所示。ZooKeeper是维护少量协调数据,通知客户端这些数据的改变和监视客户端故障的高可用服务。HA的自动故障转移依赖于ZooKeeper的以下功能:
1.故障检测
集群中的每个NameNode在ZooKeeper中维护了一个会话,如果机器崩溃,ZooKeeper中的会话将终止,ZooKeeper通知另一个NameNode需要触发故障转移。
2.现役NameNode选择
ZooKeeper提供了一个简单的机制用于唯一的选择一个节点为active状态。如果目前现役NameNode崩溃,另一个节点可能从ZooKeeper获得特殊的排外锁以表明它应该成为现役NameNode。
ZKFC是自动故障转移中的另一个新组件,是ZooKeeper的客户端,也监视和管理NameNode的状态。每个运行NameNode的主机也运行了一个ZKFC进程,ZKFC负责:
1)健康监测
ZKFC使用一个健康检查命令定期地ping与之在相同主机的NameNode,只要该NameNode及时地回复健康状态,ZKFC认为该节点是健康的。如果该节点崩溃,冻结或进入不健康状态,健康监测器标识该节点为非健康的。
2)ZooKeeper会话管理
当本地NameNode是健康的,ZKFC保持一个在ZooKeeper中打开的会话。如果本地NameNode处于active状态,ZKFC也保持一个特殊的znode锁,该锁使用了ZooKeeper对短暂节点的支持,如果会话终止,锁节点将自动删除。
3)基于ZooKeeper的选择
如果本地NameNode是健康的,且ZKFC发现没有其它的节点当前持有znode锁,它将为自己获取该锁。如果成功,则它已经赢得了选择,并负责运行故障转移进程以使它的本地NameNode为Active。
1. HDFS-HA集群配置
1.1 环境准备
集群搭建
(1)修改IP
(2)修改主机名及主机名和IP地址的映射
(3)关闭防火墙
(4)ssh免密登录
(5)安装JDK,配置环境变量等
1.2 规划集群
-
Zookeeper分布式本身就是高可用
-
-HDFS HA:namenode高可用
-
Yarn HA:rcemanager高可用
hadoop102 | hadoop103 | hadoop104 |
---|---|---|
NameNode | NameNode | NameNode |
ZKFC | ZKFC | ZKFC |
JournalNode | JournalNode | JournalNode |
DataNode | DataNode | DataNode |
ZK | ZK | ZK |
ResourceManager | ResourceManager | ResourceManager |
NodeManager | NodeManager | NodeManager |
1.3 配置Zookeeper集群
在hadoop102、hadoop103和hadoop104三个节点上部署Zookeeper
2. 配置HDFS-HA集群
2.1官方地址:http://hadoop.apache.org/
2.2在opt目录下创建一个ha文件夹
sudo mkdir ha
sudo chown atguigu:atguigu /opt/ha
2.3 将/opt/module/下的 hadoop-3.1.3拷贝到/opt/ha目录下(记得删除/data 和 /logs目录)
cp -r /opt/module/hadoop-3.1.3 /opt/ha/
2.4 配置hadoop-env.sh
export JAVA_HOME=/opt/module/jdk1.8.0_212
2.5 配置core-site.xml
<configuration>
<!-- 把多个NameNode的地址组装成一个集群mycluster;mycluster:完全分布式集群名称 -->
<property>
<name>fs.defaultFS</name>
<value>hdfs://mycluster</value>
</property>
<!-- 指定hadoop运行时产生文件的存储目录 -->
<property>
<name>hadoop.tmp.dir</name>
<value>/opt/ha/hadoop-3.1.3/data</value>
</property>
</configuration>
2.6 配置hdfs-site.xml
<configuration>
<!-- NameNode数据存储目录 -->
<property>
<name>dfs.namenode.name.dir</name>
<value>file://${hadoop.tmp.dir}/name</value>
</property>
<!-- DataNode数据存储目录 -->
<property>
<name>dfs.datanode.data.dir</name>
<value>file://${hadoop.tmp.dir}/data</value>
</property>
<!-- JournalNode数据存储目录 -->
<property>
<name>dfs.journalnode.edits.dir</name>
<value>${hadoop.tmp.dir}/jn</value>
</property>
<!-- 完全分布式集群名称 -->
<property>
<name>dfs.nameservices</name>
<value>mycluster</value>
</property>
<!-- 集群中NameNode节点都有哪些 -->
<property>
<name>dfs.ha.namenodes.mycluster</name>
<!-- 节点名称可以自定义 -->
<value>nn1,nn2,nn3</value>
</property>
<!-- NameNode的RPC通信地址 -->
<property>
<name>dfs.namenode.rpc-address.mycluster.nn1</name>
<value>hadoop102:8020</value>
</property>
<property>
<name>dfs.namenode.rpc-address.mycluster.nn2</name>
<value>hadoop103:8020</value>
</property>
<property>
<name>dfs.namenode.rpc-address.mycluster.nn3</name>
<value>hadoop104:8020</value>
</property>
<!-- NameNode的http通信地址 -->
<property>
<name>dfs.namenode.http-address.mycluster.nn1</name>
<value>hadoop102:9870</value>
</property>
<property>
<name>dfs.namenode.http-address.mycluster.nn2</name>
<value>hadoop103:9870</value>
</property>
<property>
<name>dfs.namenode.http-address.mycluster.nn3</name>
<value>hadoop104:9870</value>
</property>
<!-- 指定NameNode共享edits文件元数据在JournalNode上的存放位置 -->
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://hadoop102:8485;hadoop103:8485;hadoop104:8485/mycluster</value>
</property>
<!-- 访问代理类:client用于确定哪个NameNode为Active -->
<property>
<name>dfs.client.failover.proxy.provider.mycluster</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>
<!-- 配置隔离机制,即同一时刻只能有一台服务器对外响应 -->
<property>
<name>dfs.ha.fencing.methods</name>
<value>sshfence</value>
</property>
<!-- 使用隔离机制时需要ssh秘钥登录,需要集群之间节点任意两台ssh免密登录-->
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/home/atguigu/.ssh/id_rsa</value>
</property>
</configuration>
2.7 分发配置好的hadoop环境到其他节点
[atguigu@hadoop102 hadoop-3.1.3]$ sudo xsync /opt/ha/hadoop-3.1.3
3. 启动HDFS-HA集群
1.将HADOOP_HOME环境变量更改到HA目录
sudo vim /etc/profile.d/my_env.sh
将HADOOP_HOME部分改为如下
##HADOOP_HOME
export HADOOP_HOME=/opt/ha/hadoop-3.1.3
export PATH=$PATH:$HADOOP_HOME/bin
export PATH=$PATH:$HADOOP_HOME/sbin
将该文件分发至各个节点
sudo xsync /etc/profile.d/my_env.sh
各个节点=source一下
source /etc/profile.d/my_env.sh
2.在各个JournalNode节点上,输入以下命令启动journalnode服务
hdfs --daemon start journalnode
查看下JournalNode进程
3.在【nn1】上,对其进行格式化,并启动
hdfs namenode -format
hdfs --daemon start namenode
查看【nn1】节点上的namenode进程
查看各个节点数据
[atguigu@hadoop103 hadoop-3.1.3]$ tree /opt/ha/hadoop-3.1.3/data/
【nn1】 【nn2】 【nn3】
4.在【nn2】和【nn3】上,分别同步【nn1】的元数据信息
[atguigu@hadoop104 hadoop-3.1.3]$ hdfs namenode -bootstrapStandby
查看各个节点数据变化,各个节点元数据信息一致
【nn1】 【nn2】 【nn3】
5.启动【nn2】和【nn3】的namenode
[atguigu@hadoop102 hadoop-3.1.3]$ hdfs --daemon start namenode
6.查看web页面显示
hadoop102(standby)
hadoop103(standby)
hadoop104(standby)
7.在所有节点上,启动datanode
[atguigu@hadoop102 hadoop-3.1.3]$ hdfs --daemon start datanode
8.手动将【nn1】切换为Active,查看是否Active
[atguigu@hadoop102 hadoop-3.1.3]$ hdfs haadmin -transitionToActive nn1
[atguigu@hadoop102 hadoop-3.1.3]$ hdfs haadmin -getServiceState nn1
查看【nn1】web界面
目前还不能实现故障自动转移
4.配置HDFS-HA自动故障转移
1.具体配置
(1)在hdfs-site.xml中增加
<!-- 启用nn故障自动转移 -->
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
(2)在core-site.xml文件中增加
<!-- 指定zkfc要连接的zkServer地址 -->
<property>
<name>ha.zookeeper.quorum</name>
<value>hadoop102:2181,hadoop103:2181,hadoop104:2181</value>
</property>
(3)将hdfs-site.xml和core-site.xml分发到其他节点
[atguigu@hadoop102 hadoop-3.1.3]$ xsync etc/hadoop/
2.启动
(1)关闭所有HDFS服务:
[atguigu@hadoop102 hadoop-3.1.3]$ stop-dfs.sh
(2)启动Zookeeper集群,各个节点启动zkServer,可以用群起脚本
zkServer.sh start
(3)在【nn1】初始化HA在Zookeeper中状态:
[atguigu@hadoop102 hadoop-3.1.3]$ hdfs zkfc -formatZK
另外开个shell窗口,启动zookeeper客户端
[atguigu@hadoop102 ~]$ zkCli.sh
zookeeper多了一个hadoop-ha/mycluster节点
(4)启动HDFS服务:
[atguigu@hadoop102 hadoop-3.1.3]$ start-dfs.sh
如果各个节点进程如上图所示,则证明HDFS的HA自动故障转移搭建成功
)
3.验证
(1)查看web页面
hadoop102(standby)
hadoop103(active)
hadoop104(standby)
(2)在Active的节点将NameNode进程kill
[atguigu@hadoop103 hadoop-3.1.3]$ kill -9 8988
(3)查看web页面
此时hadoop102从standby状态变为active,hadoop104状态依然是standby
5. YARN-HA配置
5.1YARN-HA工作机制
1)官方文档:
http://hadoop.apache.org/docs/r3.1.3/hadoop-yarn/hadoop-yarn-site/ResourceManagerHA.html
2)YARN-HA工作机制
4.4.2 配置YARN-HA集群
1)环境准备
(1)修改IP
(2)修改主机名及主机名和IP地址的映射
(3)关闭防火墙
(4)ssh免密登录
(5)安装JDK,配置环境变量等
(6)配置Zookeeper集群
2)规划集群
hadoop102 | hadoop103 | hadoop104 |
---|---|---|
NameNode | NameNode | NameNode |
JournalNode | JournalNode | JournalNode |
DataNode | DataNode | DataNode |
ZK | ZK | ZK |
ResourceManager | ResourceManager | |
NodeManager | NodeManager | NodeManager |
3)具体配置
(1)yarn-site.xml
<configuration>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<!--启用resourcemanager ha-->
<property>
<name>yarn.resourcemanager.ha.enabled</name>
<value>true</value>
</property>
<!--声明两台resourcemanager的地址-->
<property>
<name>yarn.resourcemanager.cluster-id</name>
<value>cluster-yarn1</value>
</property>
<!--指定resourcemanager的逻辑列表-->
<property>
<name>yarn.resourcemanager.ha.rm-ids</name>
<value>rm1,rm2</value>
</property>
<!-- ========== rm1的配置 ========== -->
<!--指定rm1的主机名-->
<property>
<name>yarn.resourcemanager.hostname.rm1</name>
<value>hadoop102</value>
</property>
<!-- 指定rm1的web端地址 -->
<property>
<name>yarn.resourcemanager.webapp.address.rm1</name>
<value>hadoop102:8088</value>
</property>
<!-- 指定rm1的内部通信地址 -->
<property>
<name>yarn.resourcemanager.address.rm1</name>
<value>hadoop102:8032</value>
</property>
<!-- 指定AM向rm1申请资源的地址 -->
<property>
<name>yarn.resourcemanager.scheduler.address.rm1</name>
<value>hadoop102:8030</value>
</property>
<!-- 指定供NM连接的地址 -->
<property>
<name>yarn.resourcemanager.resource-tracker.address.rm1</name>
<value>hadoop102:8031</value>
</property>
<!-- ========== rm2的配置 ========== -->
<!--指定rm2的主机名-->
<property>
<name>yarn.resourcemanager.hostname.rm2</name>
<value>hadoop103</value>
</property>
<property>
<name>yarn.resourcemanager.webapp.address.rm2</name>
<value>hadoop103:8088</value>
</property>
<property>
<name>yarn.resourcemanager.address.rm2</name>
<value>hadoop103:8032</value>
</property>
<property>
<name>yarn.resourcemanager.scheduler.address.rm2</name>
<value>hadoop103:8030</value>
</property>
<property>
<name>yarn.resourcemanager.resource-tracker.address.rm2</name>
<value>hadoop103:8031</value>
</property>
<!--指定zookeeper集群的地址-->
<property>
<name>yarn.resourcemanager.zk-address</name>
<value>hadoop102:2181,hadoop103:2181,hadoop104:2181</value>
</property>
<!--启用自动恢复-->
<property>
<name>yarn.resourcemanager.recovery.enabled</name>
<value>true</value>
</property>
<!--指定resourcemanager的状态信息存储在zookeeper集群-->
<property>
<name>yarn.resourcemanager.store.class</name> <value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</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_MAPRED_HOME</value>
</property>
</configuration>
(2)同步更新其他节点的配置信息
xsync /opt/ha/hadoop-3.1.3/yarn-site.xml
4)启动hdfs
start-dfs.sh
5)启动YARN
(1)在hadoop102或者hadoop103中执行:
start-yarn.sh
(2)查看服务状态
yarn rmadmin -getServiceState rm1
(3)web端查看hadoop102:8088和hadoop103:8088的YARN的状态
注意:
yarn的web页面访问无论访问那个节点会重定向到active这个节点,不是错误
hdfs的web页面avtive,standby都可以访问;