HA 概述
1.所谓HA(High Availablity),即高可用(7*24小时不中断服务)。
2.实现高可用最关键的策略是消除单点故障。HA严格来说应该分成各个组件的HA机制:HDFS的HA和YARN的HA。
3.NameNode主要在以下两个方面影响HDFS集群:
- NameNode机器发生意外,如宕机,集群无法使用,指导管理员重启。
- NameNode机器需要升级,包括软件,硬件升级,此时集群也将无法使用。
HDFS HA功能通过配置多个NameNodes(Active/Standby)实现在集群中对NameNode的热备(备用系统模式)来解决上述问题。如果出现故障,如机器崩溃或机器需要升级维护,这时可通过此种方式将NameNode很快的切换到另外一台机器。
准备工作
jdk安装及ssh免密登录设置,hadoop安装及环境变量设置同上,配置好zookeeper并启动。
HDFS-HA集群搭建
之前的hdfs集群搭建的规划:
master | slave1 | slave2 |
NameNode | Secondarynamenode | |
DataNode | DataNode | DataNode |
HA的主要目的是消除namenode的单点故障,需要将hdfs集群规划成以下模样,其中自动故障转移为HDFS部署增加了两个新组件ZooKeeper和ZKFailoverController(ZKFC)进程,如图所示。ZooKeeper是维护少量协调数据,通知客户端这些数据的改变和监视客户端故障的高可用服务。
master | slave1 | slave2 |
NameNode | NameNode | NameNode |
JournalNode | JournalNode | JournalNode |
DataNode | DataNode | DataNode |
Zookeeper | Zookeeper | Zookeeper |
ZKFC | ZKFC | ZKFC |
配置文件修改
1.修改core-site.xml,hdfs-site.xml配置文件
核心配置文件core-site.xml
<configuration>
<!-- 把多个 NameNode 的地址组装成一个集群 mycluster -->
<property>
<name>fs.defaultFS</name>
<value>hdfs://mycluster</value>
</property>
<!-- 指定 hadoop 运行时产生文件的存储目录 -->
<property>
<name>hadoop.tmp.dir</name>
<value>/opt/module/hadoop3/data</value>
</property>
<!-- 存放journalnode数据的地址 -->
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/opt/module/hadoop3/data/jn</value>
</property>
<!-- 列出运行zookeeper服务的主机端口对 -->
<property>
<name>ha.zookeeper.quorum</name>
<value>master:2181,slave1:2181,slave2:2181</value>
</property>
</configuration>
HDFS配置文件hdfs-site.xml
<configuration>
<!-- 服务的逻辑名称,使用mycluster代替master -->
<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>master:8020</value>
</property>
<property>
<name>dfs.namenode.rpc-address.mycluster.nn2</name>
<value>slave1:8020</value>
</property>
<property>
<name>dfs.namenode.rpc-address.mycluster.nn3</name>
<value>slave2:8020</value>
</property>
<!-- 指定NameNode的web端访问地址 -->
<property>
<name>dfs.namenode.http-address.mycluster.nn1</name>
<value>master:9870</value>
</property>
<property>
<name>dfs.namenode.http-address.mycluster.nn2</name>
<value>slave1:9870</value>
</property>
<property>
<name>dfs.namenode.http-address.mycluster.nn3</name>
<value>slave2:9870</value>
</property>
<!-- 指定 NameNode 元数据在 JournalNode 上的存放位置 -->
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://master:8485;slave1:8485;slave2:8485/mycluster</value>
</property>
<!-- 切换namenode代理, 用于确定哪个 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
shell(/bin/true)
</value>
</property>
<!-- 使用隔离机制时需要 ssh 秘钥登录 下面的路径改成自己的 -->
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/root/.ssh/id_rsa</value>
</property>
<!-- 启动自动故障转移机制 -->
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
</configuration>
2.修改hadoop-env.sh文件
vim hadoop-env.sh
添加内容
export JAVA_HOME=/opt/module/jdk1.8
export HDFS_NAMENODE_USER=root
export HDFS_DATANODE_USER=root
export YARN_RESOURCEMANAGER_USER=root
export YARN_NODEMANAGER_USER=root
export HDFS_JOURNALNODE_USER=root
export HDFS_ZKFC_USER=root
4.修改workers文件
vim workers
删除原来的localhost修改为
master
slave1
slave2
5.用scp分发第一、二步的文件到所以节点
cd /opt/module
scp –r hadoop3 slave1:/opt/module
scp –r hadoop3 slave2:/opt/module
6.启动journalnode服务(三个节点都要操作)
hdfs --daemon start journalnode
检查是否成功启动
jps
7.格式化namenode(格式化之前确保zookeeper服务与journalnode服务都已启动)
hdfs namenode -format
8.单独启动namenode(在master上执行)
hdfs --daemon start namenode
9.namenode主从信息同步(在slave1、slave2上执行)
hdfs namenode -bootstrapStandby
10.格式化zookeeper(只需要在master节点执行)
执行之前执行stop-dfs.sh先关掉journalnode进程
hdfs zkfc -formatZK
11.启动hadoop
start-dfs.sh
12.验证hadoop正常启动
jps
13.测试功能是否可用
三个节点web页面如下,其中master为active,slave1与slave2为standby
查看master节点的namenode进程号,并杀死进程
kill -9 20254
此时,发现master节点web页面打不开了,slave1节点变为active状态,slave2依旧是standby
配置YARN-HA集群
集群规划如下:
master | slave1 | slave2 |
ResourceManager | ResourceManager | ResourceManager |
NodeManager | NodeManager | NodeManager |
Zookeeper | Zookeeper | Zookeeper |
配置文件修改
1.修改yarn-site.xml,mapred.xml配置文件
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>
<!-- 指定RM的cluster id -->
<property>
<name>yarn.resourcemanager.cluster-id</name>
<value>cluster-yarn</value>
</property>
<!--指定 resourcemanager 的逻辑列表-->
<property>
<name>yarn.resourcemanager.ha.rm-ids</name>
<value>rm1,rm2,rm3</value>
</property>
<!-- ========== rm1 的配置 ========== -->
<!-- 指定 rm1 的主机名 -->
<property>
<name>yarn.resourcemanager.hostname.rm1</name>
<value>master</value>
</property>
<!-- 指定 rm1 的 web 端地址 -->
<property>
<name>yarn.resourcemanager.webapp.address.rm1</name>
<value>master:8088</value>
</property>
<!-- 指定 rm1 的内部通信地址 -->
<property>
<name>yarn.resourcemanager.address.rm1</name>
<value>master:8032</value>
</property>
<!-- 指定 AM 向 rm1 申请资源的地址 -->
<property>
<name>yarn.resourcemanager.scheduler.address.rm1</name>
<value>master:8030</value>
</property>
<!-- 指定供 NM 连接的地址 -->
<property>
<name>yarn.resourcemanager.resource-tracker.address.rm1</name>
<value>master:8031</value>
</property>
<!-- ========== rm2 的配置 ========== -->
<property>
<name>yarn.resourcemanager.hostname.rm2</name>
<value>slave1</value>
</property>
<property>
<name>yarn.resourcemanager.webapp.address.rm2</name>
<value>slave1:8088</value>
</property>
<property>
<name>yarn.resourcemanager.address.rm2</name>
<value>slave1:8032</value>
</property>
<property>
<name>yarn.resourcemanager.scheduler.address.rm2</name>
<value>slave1:8030</value>
</property>
<property>
<name>yarn.resourcemanager.resource-tracker.address.rm2</name>
<value>slave1:8031</value>
</property>
<!-- ========== rm3 的配置 ========== -->
<property>
<name>yarn.resourcemanager.hostname.rm3</name>
<value>slave2</value>
</property>
<property>
<name>yarn.resourcemanager.webapp.address.rm3</name>
<value>slave2:8088</value>
</property>
<property>
<name>yarn.resourcemanager.address.rm3</name>
<value>slave2:8032</value>
</property>
<property>
<name>yarn.resourcemanager.scheduler.address.rm3</name>
<value>slave2:8030</value>
</property>
<property>
<name>yarn.resourcemanager.resource-tracker.address.rm3</name>
<value>slave2:8031</value>
</property>
<!-- 指定 zookeeper 集群的地址 -->
<property>
<name>yarn.resourcemanager.zk-address</name>
<value>master:2181,slave1:2181,slave2: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,CLAS
SPATH_PREPEND_DISTCACHE,HADOOP_YARN_HOME,HADOOP_MAPRED_HOME</value>
</property>
</configuration>
mapred-site.xml
<configuration>
<!-- 指定 MapReduce 程序运行在 Yarn 上 -->
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
</configuration>
2.启动
start-yarn.sh
3.测试
打开三个节点yarn的web页面,发现三个网址都会跳转到slave1的页面,说明只有slave1是active.
查看slave1的rm的进程号,并杀死
此时,再打开网页,发现跳转的是master的网页。
Hadoop HA最终规划
master | slave1 | slave2 |
NameNode | NameNode | NameNode |
JournalNode | JournalNode | JournalNode |
DataNode | DataNode | DataNode |
Zookeeper | Zookeeper | Zookeeper |
ZKFC | ZKFC | ZKFC |
ResourceManager | ResourceManager | ResourceManager |
NodeManager | NodeManager | NodeManager |