Hadoop HA
- Hadoop HDFS-HA
- HA(High Availablity)
- HDFS-HA 集群搭建
- HDFS-HA 核心问题
- HDFS-HA手动配置
- 1 环境准备
- 2 规划集群
- 3 配置HDFS-HA集群
- 4 启动HDFS-HA集群
- HDFS-HA自动模式
- HDFS-HA 自动故障转移工作机制
- HDFS-HA 自动故障转移的集群规划
- 配置HDFS-HA 自动故障转移
- YARN-HA配置
- YARN-HA 工作机制
- 配置YARN-HA集群
Hadoop HDFS-HA
HA(High Availablity)
1.高可用:7*24小时不中断服务。
2.实现高可用最关键的策略是消除单点故障(一个节点故障,整个集群不可以使用),HA严格来说应该分成各个组件的HA机制:HDFS的HA和YARN的HA。
3.NameNode主要在以下两个方法影响HDFS集群
NameNode集群发生意外,如宕机,集群将无法使用,直到管理员重启。
NameNode机器需要升级,包括软件、硬件升级,此时集群也将无法使用
HDFS HA 功能通过配置多个NameNodes(1个Active/多个Standby)实现在集群中对NameNode的热备份来解决问题。如果出现故障可以将Standby替换Active。
HDFS-HA 集群搭建
当前HDFS集群的规划
HA的主要目的是消除NameNode的单点故障,需要将HDFS集群重新规划,这里规划3个。
HDFS-HA 核心问题
1.如何保证三台NameNode的数据一致
Fsimage:需要一台NameNode作为Active生成数据,其他NameNode作为Standby进行同步
Edits:需要引进新的模块JournaNode来保证edtis的文件数据一致性
2.怎么让只有一台nn是active,其他所有是standly
1.手动分配,指定某一台为active,其余为standly
2.自动分配
3.2nn在ha架构中不允许不存在,那么谁负责定期合并Fsimage和Edits?
由standly的nn
4.如果active的nn发生了问题,怎么让其他的nn变成新的active?
a.手动故障转移
b.自动故障转移:依赖框架
HDFS-HA手动配置
1 环境准备
1.修改IP
2.修改主机名和主机名与IP地址的映射
3.关闭防火墙
4.ssh免密登录
5.安装JDK,配置环境变量等
我之前已经配过了,具体流程可以看下面的博客
2 规划集群
3 配置HDFS-HA集群
1.在opt目录下创建一个ha文件,103、104同样需要
[ranan@hadoop102 opt]$ sudo mkdir ha
[ranan@hadoop102 opt]$ ll
总用量 0
drwxr-xr-x. 2 root root 6 1月 5 10:28 ha # 权限属于root用户
drwxr-xr-x. 4 ranan ranan 46 6月 17 2021 module
drwxr-xr-x. 2 ranan ranan 67 7月 8 21:34 software
[ranan@hadoop102 opt]$ sudo chown ranan:ranan ha # 修改权限
[ranan@hadoop102 opt]$ ll
总用量 0
drwxr-xr-x. 2 ranan ranan 6 1月 5 10:28 ha
drwxr-xr-x. 4 ranan ranan 46 6月 17 2021 module
drwxr-xr-x. 2 ranan ranan 67 7月 8 21:34 software
2.将/opt/module/下的hadoop-3.1.3拷贝到/opt/ha目录下
[ranan@hadoop102 opt]$ cp -r /opt/module/hadoop-3.1.3 /opt/ha/
3.删除/opt/ha/hadoop-3.1.3 下的data和logs文件,删除数据
[ranan@hadoop102 hadoop-3.1.3]$ rm -rf data/ logs/
4.配置/opt/ha/hadoop-3.1.3/etc/hadoop/目录下的core-site.xml 和hdfs-site.xml
fs.defaultFS
hdfs://mycluster
hadoop.tmp.dir
/opt/ha/hadoop-3.1.3/data
dfs.namenode.name.dir
file://${hadoop.tmp.dir}/name
dfs.datanode.data.dir
file://${hadoop.tmp.dir}/data
dfs.journalnode.edits.dir
file://${hadoop.tmp.dir}/jn
dfs.nameservices
mycluster
dfs.ha.namenodes.mycluster
nn1,nn2,nn3
dfs.namenode.rpc-address.mycluster.nn1
hadoop102:8020
dfs.namenode.rpc-address.mycluster.nn2
hadoop103:8020
dfs.namenode.rpc-address.mycluster.nn3
hadoop104:8020
dfs.namenode.http-address.mycluster.nn1
hadoop102:9870
dfs.namenode.http-address.mycluster.nn2
hadoop103:9870
dfs.namenode.http-address.mycluster.nn3
hadoop104:9870
dfs.namenode.shared.edits.dir
qjournal://hadoop102:8485;hadoop103:8485;hadoop104:8485/mycluster
dfs.client.failover.proxy.provider.mycluster
org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider
dfs.ha.fencing.methods
sshfence
dfs.ha.fencing.ssh.private-key-files
/home/ranan/.ssh/id_rsa
5.分发配置信息
[ranan@hadoop102 opt]$ xsync ha/hadoop-3.1.3
4 启动HDFS-HA集群
1 修改3台节点的环境配置信息,关于hadoop的配置信息,我的在/etc/profile.d/my_env.sh
[ranan@hadoop103 hadoop-3.1.3]$ cd /etc/profile.d
[ranan@hadoop103 profile.d]$ sudo vim my_env.sh
[ranan@hadoop102 profile.d]$ source /etc/profile # 会重新加载profile脚本,该脚本里会加载profile.d
2 在各个JournalNode节点上,启动JournalNode服务
[ranan@hadoop102 hadoop-3.1.3]$ hdfs --daemon start journalnode
[ranan@hadoop103 hadoop-3.1.3]$ hdfs --daemon start journalnode
[ranan@hadoop104 hadoop-3.1.3]$ hdfs --daemon start journalnode
[ranan@hadoop102 hadoop]$ jpsall
=============== hadoop102 ===============
4005 Jps
3933 JournalNode
=============== hadoop103 ===============
3738 Jps
3679 JournalNode
=============== hadoop104 ===============
3699 JournalNode
3757 Jps
3 在启动集群之前,需要格式化namenode,但是现在三台节点都是namenode,我们可以随便选择一个节点格式化,其他节点同步该信息,namenode需要一致
在nn1,对其格式化,并启动
[ranan@hadoop102 hadoop]$ hadfs namenode -farmat
[ranan@hadoop102 hadoop]$ hdfs --daemon start namenode
查看是否启动成功:http://hadoop102:9870/
在nn2和nn3上,同步nn1的元数据信息
[ranan@hadoop103 hadoop-3.1.3]$ hdfs namenode -bootstrapStandby
[ranan@hadoop104 hadoop-3.1.3]$ hdfs namenode -bootstrapStandby
[ranan@hadoop103 hadoop-3.1.3]$ hdfs --daemon start namenode
[ranan@hadoop104 hadoop-3.1.3]$ hdfs --daemon start namenode
查看是否启动成功:http://hadoop103:9870/,http://hadoop104:9870/
4 修改其中一个节点为Active节点
因为这是我们手动配置的,所以所有节点都是standby,我们需要手动的修改其中一个为Active节点
先在所有节点上,启动datanode,将HDFS启动起来
[ranan@hadoop102 hadoop-3.1.3]$ hdfs --daemon start datanode
[ranan@hadoop103 hadoop-3.1.3]$ hdfs --daemon start datanode
[ranan@hadoop104 hadoop-3.1.3]$ hdfs --daemon start datanode
[ranan@hadoop102 hadoop]$ jpsall
=============== hadoop102 ===============
4200 NameNode
4570 DataNode
4747 Jps
3933 JournalNode
=============== hadoop103 ===============
3976 NameNode
4408 Jps
4238 DataNode
3679 JournalNode
=============== hadoop104 ===============
3699 JournalNode
4259 DataNode
3990 NameNode
4427 Jps
将nn1切换为Active
[ranan@hadoop102 hadoop]$ hdfs haadmin -transitionToActive nn1
5 假设nn1挂掉了
kill nn1
[ranan@hadoop102 hadoop]$ jpsall
=============== hadoop102 ===============
4200 NameNode
4570 DataNode
19355 Jps
3933 JournalNode
=============== hadoop103 ===============
3976 NameNode
18923 Jps
4238 DataNode
3679 JournalNode
=============== hadoop104 ===============
3699 JournalNode
4259 DataNode
3990 NameNode
19033 Jps
[ranan@hadoop102 hadoop]$ kill -kill 4200
[ranan@hadoop102 hadoop]$ jpsall
=============== hadoop102 ===============
4570 DataNode
3933 JournalNode
19422 Jps
=============== hadoop103 ===============
18992 Jps
3976 NameNode
4238 DataNode
3679 JournalNode
=============== hadoop104 ===============
3699 JournalNode
4259 DataNode
3990 NameNode
19103 Jps
假设此时我们把nn2设置为active,报错102拒绝连接
[ranan@hadoop103 hadoop-3.1.3]$ hdfs haadmin -transitionToActive nn2
2022-01-11 10:10:18,292 INFO ipc.Client: Retrying connect to server: hadoop102/192.168.10.102:8020. Already tried 0 time(s); retry policy is RetryUpToMaximumCountWithFixedSleep(maxRetries=1, sleepTime=1000 MILLISECONDS)
Unexpected error occurred Call From hadoop103/192.168.10.103 to hadoop102:8020 failed on connection exception: java.net.ConnectException: 拒绝连接; For more details see: http://wiki.apache.org/hadoop/ConnectionRefused
Usage: haadmin [-ns ] [-transitionToActive [--forceactive] ]
重启nn1,发现nn1变成了standby,现在没有active了,可以重新选取节点成为新的active
[ranan@hadoop102 hadoop]$ hdfs --daemon start namenode
手动模式下,需要所有namenode启动才可以将某个节点转成Active
Active需要知道其他namenode是存活状态,因为一个集群中只能由一个Active,如果联系不上,不知道该节点是否是active。
HDFS-HA自动模式
HDFS-HA 自动故障转移工作机制
主要需要解决的问题:当要提升某个节点为Active的时候,如果确定其他节点不是Active
ZooKeeper 是维护少量协调数据,通知客户端这些数据的改变和监视客户端故障的高可用服务
自动故障增加了两个新组件:Zookeeper和ZKFailoverController(ZKFC)进程,该进程监控节点是否挂掉,如果监控到挂点了,再次发送kill命令真正杀死节点,防止出现脑裂。
HDFS-HA 自动故障转移的集群规划
配置HDFS-HA 自动故障转移
1 在hdfs-site.xml里面打开自动转移
dfs.ha.automatic-failover.enabled
true
2 在core-site.xml里面添加zookeeper信息
ha.zookeeper.quorum
hadoop102:2181,hadoop103:2181,hadoop104:2181
3 分发节点
[ranan@hadoop102 hadoop]$ xsync core-site.xml hdfs-site.xml
4 保持集群关闭状态下,启动Zookeeper集群,再初始化HA在Zookeeper中状态
# 启动zookeep
[ranan@hadoop102 zookeeper-3.4.10]# zkServer.sh start
[ranan@hadoop103 zookeeper-3.4.10]# zkServer.sh start
[ranan@hadoop104 zookeeper-3.4.10]# zkServer.sh start
# 初始化HA在Zookeeper中的状态
[ranan@hadoop102 zookeeper-3.4.10]# hdfs zkfc -formatZK
5 启动集群
[ranan@hadoop102 hadoop]# start-dfs.sh
6 可以去zkCli.sh客户端查看NameNode节点内容
哪台机器先启动DFSZK Failover Controller,哪个机器的NameNode就是Active NameNode
[ranan@hadoop102 zookeeper]# bin/zkcli.sh
get -s /hadoop-ha/mycluster/ActiveStandbyElectorLock
mycluster nn2 hadoop103 # 这里是hadoop103节点
7 杀死Hadoop103,观察Active是否转移
Active切换到hadoop102后,如果hadoop103重新启动,hadoop103不再是Active而是Standby
[ranan@hadoop103 zookeeper]# kill -9 4897
# zkcli.sh客户端查看
get -s /hadoop-ha/mycluster/ActiveStandbyElectorLock
mycluster nn1 hadoop102 # 这里切换到了hadoop102了
注意如果写代码上传到比如根目录使用hdfs://mycluster/
在上传过程中会去找active,所以可能在尝试中会连接到standby,有报错但是没关系。
YARN-HA配置
YARN-HA 工作机制
配置YARN-HA集群
1 集群规划
2 核心问题
a.如果当前active rm挂了,其他rm怎么上位
核心原理和hdfs一样,利用了zk的临时节点
b.当前rm上有很多的计算程序在等待运行,其他rm怎么将这些程序接手过来继续跑
rm会将当前的所有计算程序的状态存储在zk中,其他rm上位后会去读取,然后接着跑
3 修改yarn-site.xml,修改之后分发yarn-site.xml
yarn.nodemanager.aux-services
mapreduce_shuffle
yarn.resourcemanager.ha.enabled
true
yarn.resourcemanager.cluster-id
cluster-yarn1
yarn.resourcemanager.ha.rm-ids
rm1,rm2,rm3
yarn.resourcemanager.hostname.rm1
hadoop102
yarn.resourcemanager.webapp.address.rm1
hadoop102:8088
yarn.resourcemanager.address.rm1
hadoop102:8032
yarn.resourcemanager.scheduler.address.rm1
hadoop102:8030
yarn.resourcemanager.resource-tracker.address.rm1
hadoop102:8031
yarn.resourcemanager.hostname.rm1
hadoop103
yarn.resourcemanager.webapp.address.rm1
hadoop103:8088
yarn.resourcemanager.address.rm1
hadoop103:8032
yarn.resourcemanager.scheduler.address.rm1
hadoop103:8030
yarn.resourcemanager.resource-tracker.address.rm1
hadoop103:8031
yarn.resourcemanager.hostname.rm1
hadoop104
yarn.resourcemanager.webapp.address.rm1
hadoop104:8088
yarn.resourcemanager.address.rm1
hadoop104:8032
yarn.resourcemanager.scheduler.address.rm1
hadoop104:8030
yarn.resourcemanager.resource-tracker.address.rm1
hadoop104:8031
yarn.resourcemanager.zk-address
hadoop102:2181,hadoop103:2181,hadoop104:2181
yarn.resourcemanager.recovery.enabled
true
yarn.resourcemanager.store.class
org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore
yarn.nodemanager.env-whitelist
JAVA_HOME,HADDOP_COMMON_HOME,HADOOP_HDFS_HOME,HADDOP_CONF_DIR,CLASSPATH_PREPEND_DISTCACHE,HADOOP_YARN_HOME,HADOOP_MAORED_HOME
4 启动yarn
[ranan@hadoop102 hadoop]$ start-yarn.sh
# 查看服务状态
[ranan@hadoop102 hadoop]$ yarn rmadmin -getServiceState rm1
standby
访问hadoop102:8088发现直接跳到了hadoop103:8088,因为这里hadoop103:8088是Active。