1.简介

若HDFS集群中只配置了一个NameNode,那么当该NameNode所在的节点宕机,则整个HDFS就不能进行文件的上传和下载。

若YARN集群中只配置了一个ResourceManager,那么当该ResourceManager所在的节点宕机,则整个YARN就不能进行任务的计算。

*Hadoop依赖Zookeeper进行各个模块的HA配置,其中状态为Active的节点对外提供服务,而状态为StandBy的节点则只负责数据的同步,在必要时提供快速故障转移。

2.HDFS HA集群

2.1 模型

当有两个NameNode时,提供哪个NameNode地址给客户端?




hadoop jar找不到类 hadoop找不到namenode_hadoop


1.Hadoop提供了NameService进程,其是NameNode的代理,维护NameNode列表并存储NameNode的状态,客户端直接访问的是NameService,NameService会将请求转发给当前状态为Active的NameNode。

2.当启动HDFS时,DataNode将同时向两个NameNode进行注册。

怎样发现NameNode无法提供服务以及如何进行NameNode间状态的切换?


hadoop jar找不到类 hadoop找不到namenode_hadoop_02


1.Hadoop提供了FailoverControllerActive和FailoverControllerStandBy两个进程用于NameNode的生命监控。

2.FailoverControllerActive和FailoverControllerStandBy会分别监控对应状态的NameNode,若NameNode无异常则定期向Zookeeper集群发送心跳,若在一定时间内Zookeeper集群没收到FailoverControllerActive发送的心跳,则认为此时状态为Active的NameNode已经无法对外提供服务,因此将状态为StandBy的NameNode切换为Active状态。

NameNode之间的数据如何进行同步和共享?

1.Hadoop提供了JournalNode用于存放NameNode中的编辑日志。

2.当激活的NameNode执行任何名称空间上的修改时,它将修改的记录保存到JournalNode集群中,备用的NameNode能够实时监控JournalNode集群中日志的变化,当监控到日志发生改变时会将其同步到本地。

*当状态为Active的NameNode无法对外提供服务时,Zookeeper将会自动的将处于StandBy状态的NameNode切换成Active。

2.2 HDFS HA高可用集群搭建

1.安装并配置Zookeeper集群

2.配置HDFS(hdfs-site.xml)

dfs.nameservicesmyclusterdfs.ha.namenodes.myclusternn1,nn2dfs.namenode.rpc-address.mycluster.nn1192.168.1.80:8020dfs.namenode.rpc-address.mycluster.nn2192.168.1.81:8020dfs.namenode.http-address.mycluster.nn1192.168.1.80:50070dfs.namenode.http-address.mycluster.nn2192.168.1.81:50070dfs.namenode.shared.edits.dirqjournal://192.168.1.80:8485;192.168.1.81:8485;192.168.1.82:8485/myclusterdfs.journalnode.edits.dir/usr/hadoop/hadoop-2.9.0/journalnodedfs.client.failover.proxy.provider.myclusterorg.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProviderdfs.ha.fencing.methodssshfencedfs.ha.fencing.ssh.private-key-files/root/.ssh/id_rsadfs.ha.automatic-failover.enabledtrueha.zookeeper.quorum192.168.1.80:2181,192.168.1.81:2181,192.168.1.82:2181dfs.replication3dfs.permissions.enabledfalsedfs.hosts.exclude/usr/hadoop/hadoop-2.9.0/etc/hadoop/hdfs.exclude

*指定NameNode的RPC通讯地址是为了接收FailoverControllerActive和FailoverControllerStandBy以及DataNode发送的心跳。

3.配置Hadoop公共属性(core-site.xml)

hadoop.tmp.dir/usr/hadoop/hadoop-2.9.0/datafs.defaultFShdfs://myclusterfs.trash.interval1440

*在HDFS HA集群中,StandBy的NameNode会对namespace进行checkpoint操作,因此就不需要在HA集群中运行SecondaryNameNode、CheckpintNode、BackupNode。

4.启动HDFS HA高可用集群

1.分别启动JournalNode


hadoop jar找不到类 hadoop找不到namenode_hadoop jar找不到类_03


hadoop jar找不到类 hadoop找不到namenode_hadoop_04


hadoop jar找不到类 hadoop找不到namenode_hadoop_05


2.格式化第一个NameNode并启动


hadoop jar找不到类 hadoop找不到namenode_hadoop启动后没有namenode_06


hadoop jar找不到类 hadoop找不到namenode_hadoop jar找不到类_07


3.第二个NameNode同步第一个NameNode的信息


hadoop jar找不到类 hadoop找不到namenode_hadoop_08


4.启动第二个NameNode


hadoop jar找不到类 hadoop找不到namenode_hadoop jar找不到类_09


5.启动Zookeeper集群


hadoop jar找不到类 hadoop找不到namenode_hadoop jar找不到类_10


hadoop jar找不到类 hadoop找不到namenode_hadoop jar找不到类_11


hadoop jar找不到类 hadoop找不到namenode_hadoop jar找不到类_12


6.格式化Zookeeper


hadoop jar找不到类 hadoop找不到namenode_hadoop启动后没有namenode_13


*当格式化ZK后,ZK中将会多了hadoop-ha节点。

7.重启HDFS集群


hadoop jar找不到类 hadoop找不到namenode_hadoop启动后没有namenode_14


hadoop jar找不到类 hadoop找不到namenode_hadoop启动后没有namenode_15


当HDFS HA集群启动完毕后,可以分别访问NameNode管理页面查看当前NameNode的状态,http://192.168.1.80:50070、http://192.168.1.81:50070。


hadoop jar找不到类 hadoop找不到namenode_hadoop启动后没有namenode_16


hadoop jar找不到类 hadoop找不到namenode_hadoop jar找不到类_17


*可以查看到主机名为hadoop1的NamNode其状态为StandBy,而主机名为hadoop2的NameNode其状态为Active。

8.模拟NameNode宕机,手动杀死进程。


hadoop jar找不到类 hadoop找不到namenode_hadoop集群_18


此时访问NameNode管理页面,可见主机名为hadoop1的NameNode其状态从原本的StandBy切换成Active。


hadoop jar找不到类 hadoop找不到namenode_hadoop启动后没有namenode_19


2.3 JAVA操作HDFS HA集群

*由于在HDFS HA集群中存在两个NameNode,且服务端暴露的是NameService,因此在通过JAVA连接HDFS HA集群时需要使用Configuration实例进行相关的配置。

/** * @Auther: ZHUANGHAOTANG * @Date: 2018/11/6 11:49 * @Description: */public class HDFSUtils { private static Logger logger = LoggerFactory.getLogger(HDFSUtils.class); /** * NameNode Service */ private static final String NAMESERVER_URL = "hdfs://mycluster:8020"; /** * NameNode服务列表 */ private static final String[] NAMENODE_URLS = {"192.168.1.80:8020