HDFS HA 高可用
概述:
1)所谓HA(high available),即高可用(7*24小时不中断服务)。
2)实现高可用最关键的策略是消除单点故障。HA严格来说应该分成各个组件的HA机制:HDFS的HA和YARN的HA。
3)Hadoop2.0之前,在HDFS集群中NameNode存在单点故障(SPOF)。
4)NameNode主要在以下两个方面影响HDFS集群
NameNode机器发生意外,如宕机,集群将无法使用,直到管理员重启
NameNode机器需要升级,包括软件、硬件升级,此时集群也将无法使用
HDFS HA功能通过配置Active/Standby两个nameNodes实现在集群中对NameNode的热备来解决上述问题。如果出现故障,如机器崩溃或机器需要升级维护,这时可通过此种方式将NameNode很快的切换到另外一台机器。
HDFS-HA 工作机制:
通过双 namenode 消除单点故障
HDFS-HA 工作要点:
1)元数据管理方式需要改变:
内存中各自保存一份元数据;
Edits 日志只有 Active 状态的 namenode 节点可以写操作;
两个 namenode 都可以读取 edits;
共享的 edits 放在一个共享存储中管理 (qjournal 和 NFS 两个主流实现);
2)需要一个状态管理功能模块:
实现了一个 zkfailover,常驻在每一个 namenode 所在的节点,每一个 zkfailover 负责监控自己所在 namenode 节点,利用 zk 进行状态标识,当需要进行状态转换时,由 zkfailover 来负责切换,切换时需要防止 brain split(脑裂)现象的发生。
3)必须保证两个 NameNode 之间能够 ssh 无密码登录。
4)隔离(Fence),即同一时刻仅仅有一个 NameNode 对外提供服务。
HDFS-HA 自动故障转移工作机制:
自动故障转移为 HDFS 部署增加了两个新组件:ZooKeeper 和 ZKFailoverController(ZKFC) 进程。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 对短暂节点的支持,如果会话终止,锁节点将自动删除。
4)基于 ZooKeeper 的选择:如果本地 NameNode 是健康的,且 ZKFC 发现没有其它的节点当前持有 znode 锁,它将为自己获取该锁。如果成功,则它已经赢得了选择,并负责运行故障转移进程以使用它的本地 NameNode 为 active。
HDFS-HA 集群配置:
1、环境准备
1)修改 ip
2)修改主机名及主机名的 ip 地址映射
3)关闭防火墙
4)ssh 免密登录
5)安装 JDK,配置环境变量等
2、规划集群
bigdata111 bigdata112 bigdata113
NameNode NameNode
JournalNode JournalNode JournalNode
DataNode DataNode DataNode
ZK ZK ZK
ResourceManager
NodeManager NodeManager NodeManager
3、 配置Zookeeper集群
0)集群规划
在bigdata111、bigdata112和bigdata113三个节点上部署Zookeeper。
1)解压安装
(1)解压zookeeper安装包到/opt/module/目录下
[itstar@bigdata111 software]$ tar -zxvf zookeeper-3.4.10.tar.gz -C /opt/module/
(2)在/opt/module/zookeeper-3.4.10/这个目录下创建zkData
mkdir -p zkData
(3)重命名/opt/module/zookeeper-3.4.10/conf这个目录下的zoo_sample.cfg为zoo.cfg
mv zoo_sample.cfg zoo.cfg
2)配置zoo.cfg文件
(1)具体配置
dataDir=/opt/module/zookeeper-3.4.10/zkData
增加如下配置
#######################cluster##########################
server.1=bigdata111:2888:3888
server.2=bigdata112:2888:3888
server.3=bigdata113:2888:3888
(2)配置参数解读
Server.A=B:C:D。
A是一个数字,表示这个是第几号服务器;
B是这个服务器的ip地址;
C是这个服务器与集群中的Leader服务器交换信息的端口;
D是万一集群中的Leader服务器挂了,需要一个端口来重新进行选举,选出一个新的Leader,而这个端口就是用来执行选举时服务器相互通信的端口。
集群模式下配置一个文件myid,这个文件在dataDir目录下,这个文件里面有一个数据就是A的值,Zookeeper启动时读取此文件,拿到里面的数据与zoo.cfg里面的配置信息比较从而判断到底是哪个server。
3)集群操作
(1)在/opt/module/zookeeper-3.4.10/zkData目录下创建一个myid的文件
touch myid
添加myid文件,注意一定要在linux里面创建,在notepad++里面很可能乱码
(2)编辑myid文件
vi myid
在文件中添加与server对应的编号:如2
(3)拷贝配置好的zookeeper到其他机器上
scp -r zookeeper-3.4.10/ [root@bigdata112.itstar.com:/opt/app/](mailto:root@hadoop103.atguigu.com:/opt/app/)
scp -r zookeeper-3.4.10/ [root@bigdata113.itstar.com:/opt/app/](mailto:root@hadoop104.atguigu.com:/opt/app/)
并分别修改myid文件中内容为3、4
(4)分别启动zookeeper
[root@bigdata111 zookeeper-3.4.10]# bin/zkServer.sh start
[root@bigdata112 zookeeper-3.4.10]# bin/zkServer.sh start
[root@bigdata113 zookeeper-3.4.10]# bin/zkServer.sh start
(5)查看状态
[root@bigdata111 zookeeper-3.4.10]# bin/zkServer.sh status
JMX enabled by default
Using config: /opt/module/zookeeper-3.4.10/bin/…/conf/zoo.cfg
Mode: follower
[root@bigdata112 zookeeper-3.4.10]# bin/zkServer.sh status
JMX enabled by default
Using config: /opt/module/zookeeper-3.4.10/bin/…/conf/zoo.cfg
Mode: leader
[root@bigdata113 zookeeper-3.4.5]# bin/zkServer.sh status
JMX enabled by default
Using config: /opt/module/zookeeper-3.4.10/bin/…/conf/zoo.cfg
Mode: follower
4、配置HDFS-HA集群
1)官方地址:http://hadoop.apache.org/
2)在opt目录下创建一个ha文件夹
mkdir HA
3)将/opt/app/下的 hadoop-2.8.4拷贝到/opt/ha目录下
cp -r hadoop-2.8.4/ /opt/HA/
4)配置 hadoop-env.sh
export JAVA_HOME=/opt/module/jdk1.8.0_144
5)配置 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/HA/hadoop-2.8.4/data</value>
</property>
</configuration>
6)配置 hdfs-site.xml
<configuration>
<!-- 完全分布式集群名称 -->
<property>
<name>dfs.nameservices</name>
<value>mycluster</value>
</property>
<!-- 集群中NameNode节点都有哪些 -->
<property>
<name>dfs.ha.namenodes.mycluster</name>
<value>nn1,nn2</value>
</property>
<!-- nn1的RPC通信地址 -->
<property>
<name>dfs.namenode.rpc-address.mycluster.nn1</name>
<value>bigdata111:9000</value>
</property>
<!-- nn2的RPC通信地址 -->
<property>
<name>dfs.namenode.rpc-address.mycluster.nn2</name>
<value>bigdata112:9000</value>
</property>
<!-- nn1的http通信地址 -->
<property>
<name>dfs.namenode.http-address.mycluster.nn1</name>
<value>bigdata111:50070</value>
</property>
<!-- nn2的http通信地址 -->
<property>
<name>dfs.namenode.http-address.mycluster.nn2</name>
<value>bigdata112:50070</value>
</property>
<!-- 指定NameNode元数据在JournalNode上的存放位置 -->
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://bigdata111:8485;bigdata112:8485;bigdata113:8485/mycluster</value>
</property>
<!-- 配置隔离机制,即同一时刻只能有一台服务器对外响应 -->
<property>
<name>dfs.ha.fencing.methods</name>
<value>sshfence</value>
</property>
<!-- 使用隔离机制时需要ssh无秘钥登录-->
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/root/.ssh/id_rsa</value>
</property>
<!-- 声明journalnode服务器存储目录-->
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/opt/HA/hadoop-2.8.4/data/jn</value>
</property>
<!-- 关闭权限检查-->
<property>
<name>dfs.permissions.enable</name>
<value>false</value>
</property>
<!-- 访问代理类:client,mycluster,active配置失败自动切换实现方式-->
<property>
<name>dfs.client.failover.proxy.provider.mycluster</name>
<value>
org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider
</value>
</property>
</configuration>
<!--secondary NameNode的地址,端口号是50090-->
<property>
<name>dfs.namenode.secondary.http-address</name>
<value>bigdata112:50090</value>
</property>
7)拷贝配置好的hadoop环境到其他节点
使用 scp 命令将 HA 拷贝到其他节点上。
5、启动HDFS-HA集群:
1)在各个JournalNode节点上,输入以下命令启动journalnode服务:
Journalnode主要是用来做数据之间共享的。
sbin/hadoop-daemon.sh start journalnode
2)在[nn1]上,对其进行格式化,并启动:
bin/hdfs namenode -format
sbin/hadoop-daemon.sh start namenode
3)在[nn2]上,同步nn1的元数据信息:
bin/hdfs namenode -bootstrapStandby
4)启动[nn2]:
sbin/hadoop-daemon.sh start namenode
5)查看web页面显示
6)在[nn1]上,启动所有datanode
sbin/hadoop-daemons.sh start datanode
7)查看是否Active
bin/hdfs haadmin -getServiceState nn1
8)将[nn1]切换为Active
切换为Active:bin/hdfs haadmin -transitionToActive nn1
切换为Standby:bin/hdfs haadmin -transitionToStandby nn1
6、配置HDFS-HA自动故障转移:
1)具体配置
(1)在 hdfs-site.xml 中增加
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
(2)在core-site.xml文件中增加
<property>
<name>ha.zookeeper.quorum</name>
<value>bigdata111:2181,bigdata112:2181,bigdata113:2181</value>
</property>
2)启动
(1)关闭所有HDFS服务:
sbin/stop-dfs.sh
(2)启动Zookeeper集群:
bin/zkServer.sh start
(3)初始化HA在Zookeeper中状态:
bin/hdfs zkfc -formatZK
(4)启动HDFS服务:
sbin/start-dfs.sh
(5)在各个NameNode节点上启动DFSZK Failover Controller,先在哪台机器启动,哪个机器的NameNode就是Active NameNode
sbin/hadoop-daemon.sh start zkfc
3)验证
(1)将Active NameNode进程kill
kill -9 namenode的进程id
(2)将Active NameNode机器断开网络
service network stop
配置YARN-HA集群:
0)环境准备
(1)修改IP
(2)修改主机名及主机名和IP地址的映射
(3)关闭防火墙
(4)ssh免密登录
(5)安装JDK,配置环境变量等
(6)配置Zookeeper集群
1)规划集群
bigdata111 bigdata112 bigdata113
NameNode NameNode
JournalNode JournalNode JournalNode
DataNode DataNode DataNode
ZK ZK ZK
ResourceManager ResourceManager
NodeManager NodeManager NodeManager
2)具体配置
(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>
<property>
<name>yarn.resourcemanager.ha.rm-ids</name>
<value>rm1,rm2</value>
</property>
<property>
<name>yarn.resourcemanager.hostname.rm1</name>
<value>bigdata111</value>
</property>
<property>
<name>yarn.resourcemanager.hostname.rm2</name>
<value>bigdata112</value>
</property>
<!--指定zookeeper集群的地址-->
<property>
<name>yarn.resourcemanager.zk-address</name>
<value>bigdata111:2181,bigdata112:2181,bigdata113: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>
</configuration>
2)同步更新其他节点的配置信息
删除其他节点的 yarn-site.xml 再将本节点的 yarn-site.xml scp 过去
3)启动hdfs
(1)在各个JournalNode节点上,输入以下命令启动journalnode服务:
sbin/hadoop-daemon.sh start journalnode
(2)在[nn1]上,对其进行格式化,并启动:
bin/hdfs namenode -format
sbin/hadoop-daemon.sh start namenode
(3)在[nn2]上,同步nn1的元数据信息:
bin/hdfs namenode -bootstrapStandby
(4)启动[nn2]:
sbin/hadoop-daemon.sh start namenode
(5)启动所有datanode
sbin/hadoop-daemons.sh start datanode
(6)将[nn1]切换为Active
bin/hdfs haadmin -transitionToActive nn1
4)启动yarn
(1)在bigdata111中执行:
sbin/start-yarn.sh
(2)在bigdata112中执行:
sbin/yarn-daemon.sh start resourcemanager
(3)查看服务状态
bin/yarn rmadmin -getServiceState rm1