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.xmlhdfs-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。