HDFS HA 高可用
HA 简述
(1)所谓HA(High Available),即高可用(7*24小时不中断服务)。
(2)实现高可用最关键的策略是消除单点故障。HA严格来说应该分成各个组件的HA机制:HDFS的HA和YARN的HA。
(3)Hadoop2.0之前,在HDFS集群中 NN 存在单点故障(SPOF)。
(4)NameNode 主要在以下两个方面影响HDFS集群
NameNode机器发生意外,如宕机,集群将无法使用,直到管理员重启
NameNode机器需要升级,包括软件、硬件升级,此时集群也将无法使用
HDFS HA功能通过配置Active/Standby两个NameNodes实现在集群中对NameNode的热备来解决上述问题。如果出现故障,如机器崩溃或机器需要升级维护,这时可通过此种方式将NameNode很快的切换到另外一台机器。
HDFS-HA工作机制
通过双 NameNode 消除单点故障
HDFS-HA 工作点
1、元数据管理方式需要改变
- 内存中各自保存一份元数据
- Edits 日志只有 Active 状态的 NN 节点可以做写操作
- 两个 NN 都可以读取 Edits
- 共享的 Edits 放在一个共享存储中管理(qjournal 和 NFS 两个主流实现)
2、需要一个状态管理功能模块
- 实现了一个 zkfailover,常驻在每个 NN 的节点,每个 zkfailover 负责监控自己所在的 NN 节点,利用 zk 进行状态标识,需要进行状态切换时,由 zkfailover 负责切换,切换时需要防止 brain split 现象发生。
3、必须保证两个 NN 之间能够 ssh 无密码登录
4、隔离(Fence),即同一时刻仅仅有一个 NN 对外提供服务
HDFS-HA 自动故障转移机制
hdfs haadmin -failover 可以进行手动故障转移,在该模式下,即使现役 NN已经失效,系统也不会自动从现役 NN 转移到待机 NN。自动故障转移为 HDFS 部署增加了两个新组件:ZooKeeper 和 ZKFailoverController(ZKFC)进程,如下图。ZooKeeper是维护少量协调数据,通知客户端这些数据的改变和监视客户端故障的高可用服务。HA的自动故障转移依赖于ZooKeeper的以下功能:
(1)故障检测:集群中的每个 NN 在 ZK 中维护了一个持久会话,如果机器崩溃,ZK 中的会话将终止,ZK 通知另一个 NN 需要触发故障转移。
(2)现役 NN 选择:ZK 提供了一个简单的机制用于唯一的选择一个节点为 active 状态。如果目前现役 NN 崩溃,另一个节点可能从 ZK 获得特殊的排外锁以表明它应该成为现役 NN。
ZKFC 是自动故障转移中的另一个新组件,是 ZK 的客户端,也监视和管理 NN 的状态。每个运行 NN 的主机也运行了一个 ZKFC 进程,ZKFC 负责如下:
(1)健康检测:ZKFC 使用一个健康检查命令定期地 ping 与之在相同主机的 NN,只要该 NN 及时地回复健康状态,ZKFC 认为该节点是健康的。如果该节点崩溃,冻结或进入不健康状态,健康监测器标识该节点为非健康的。
(2)Zookeeper 会话管理:当本地 NN 是健康的,ZKFC 保持一个在 ZK 中打开的会话。如果本地 NN 处于 active 状态,ZKFC 也保持一个特殊的 znode 锁,该锁使用了 ZK对短暂节点的支持,如果会话终止,锁节点将自动删除。
(3)基于 Zookeeper 的选择:如果本地 NN 是健康的,且 ZKFC 发现没有其它的节点当前持有 znode 锁,它将为自己获取该锁。如果成功,则它已经赢得了选择,并负责运行故障转移进程以使它的本地 NN为 Active。故障转移进程与前面描述的手动故障转移相似,首先如果必要保护之前的现役 NN,然后本地 NN 转换为 Active 状态。
HDFS-HA 集群配置
环境准备
- 安装或克隆主机
- 修改主机 IP
- 修改主机名及主机名和 IP 的映射
- 关闭防火墙
- 实现 ssh 免密登录
- 安装 JDK,配置环境变量
集群规划
hadoop101 | hadoop102 | hadoop103 |
NameNode | NameNode | |
JournalNode | JournalNode | JournalNode |
DataNode | DataNode | DataNode |
ZK | ZK | ZK |
ResourceManager | ||
NodeManager | NodeManager | NodeManager |
配置 Zookeeper 集群
1、集群规划
在 hadoop101、hadoop102、hadoop103 三个节点上部署 Zookeeper
2、解压安装
(1)解压 Zookeeper 安装包到 /opt/modul/ 目录下
tar -zxvf zookeeper-3.4.10.tar.gz -C /opt/module/
(2)在 /opt/modul/zookeeper-3.4.10/ 这个目录下创建 zkData
mkdir -p zkData
(3)重命名 /opt/modul/zookeeper-3.4.10/conf 这个目录下的 zoo_sample.cfg 为 zoo.cfg
mv zoo_sample.cfg zoo.cfg
3、配置 zoo.cfg 文件
(1)具体配置
dataDir=/opt/module/zookeeper-3.4.10/zkData
增加如下配置
#######################cluster##########################
server.1=hadoop101:2888:3888
server.2=hadoop102:2888:3888
server.3=hadoop103:2888:3888
(2)参数解读
Server.A=B:C:D。
A 是一个数字,表示这个是第几号服务器;
B 是这个服务器的IP地址;
C 是这个服务器与集群中的 Leader 服务器交换信息的端口;
D 是万一集群中的 Leader 服务器挂了,需要一个端口来重新进行选举,选出一个新的 Leader,而这个端口就是用来执行选举时服务器相互通信的端口。
集群模式下配置一个文件 myid,这个文件在 dataDir 目录下,这个文件里面有一个数据就是 A 的值,ZK 启动时读取此文件,拿到里面的数据与 zoo.cfg 里面的配置信息比较从而判断到底是哪个 server。
4、集群操作
(1)在/opt/module/zookeeper-3.4.10/zkData目录下创建一个myid的文件
touch myid
(2)编辑myid文件
vim myid 在文件中添加与server对应的编号:如 1
(3)拷贝配置好的zookeeper到其他机器上
scp -r zookeeper-3.4.10/ root@hadoop102.atguigu.com:/opt/app/
scp -r zookeeper-3.4.10/ root@hadoop103.atguigu.com:/opt/app/并分别修改myid文件中内容为2、3
(4)分别启动zookeeper
[root@hadoop102 zookeeper-3.4.10]# bin/zkServer.sh start
[root@hadoop103 zookeeper-3.4.10]# bin/zkServer.sh start
[root@hadoop104 zookeeper-3.4.10]# bin/zkServer.sh start
(5)查看状态
bin/zkServer.sh status
两个 server 状态为 follower ,一个为 leader
配置 HDFS-HA 集群
1、在 opt 目录下创建 ha
mkdir ha
2、将 /opt/app/ 下的 hadoop-2.7.7 拷贝到 /opt/ha 目录下
cp -r hadoop-2.7.7/ /opt/ha/
3、配置hadoop-env.sh
export JAVA_HOME=/opt/module/jdk1.8.0_144
4、配置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.7.7/data/tmp</value>
</property>
</configuration>
5、配置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>hadoop101:9000</value>
</property><!-- nn2的RPC通信地址 -->
<property>
<name>dfs.namenode.rpc-address.mycluster.nn2</name>
<value>hadoop102:9000</value>
</property><!-- nn1的http通信地址 -->
<property>
<name>dfs.namenode.http-address.mycluster.nn1</name>
<value>hadoop101:50070</value>
</property><!-- nn2的http通信地址 -->
<property>
<name>dfs.namenode.http-address.mycluster.nn2</name>
<value>hadoop102:50070</value>
</property><!-- 指定NameNode元数据在JournalNode上的存放位置 -->
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://hadoop101:8485;hadoop102:8485;hadoop103: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>/home/root/.ssh/id_rsa</value>
</property><!-- 声明journalnode服务器存储目录-->
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/opt/ha/hadoop-2.7.7/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>
6、拷贝配置好的hadoop环境到其他节点
启动 HDFS-HA 集群
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、在[nn1]上,启动所有 datanode
sbin/hadoop-daemons.sh start datanode
6、将[nn1]切换为 Active
bin/hdfs haadmin -transitionToActive nn1
7、查看是否 Active
bin/hdfs haadmin -getServiceState nn1
配置 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>hadoop101:2181,hadoop102:2181,hadoop103: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)在各个 NN 节点上启动 DFSZK Failover Controller,先在哪台机器启动,哪个机器的 NN 就是 Active NameNode
sbin/hadoop-daemin.sh start zkfc
3、验证
(1)将Active NameNode 进程kill
kill -9 namenode的进程id
(2)将Active NameNode 机器断开网络
service network stop
YARN-HA 配置
YARN-HA 工作机制
配置YARN-HA 集群
1、准备环境
- 安装或克隆主机
- 修改 IP
- 修改主机名及主机名和 IP 的映射
- 关闭防火墙
- ssh 免密登录
- 安装 JDK,配置环境变量
- 配置 Zookeeper 集群
2、集群规划
hadoop101 | hadoop102 | hadoop103 |
NameNode | NameNode | |
JournalNode | JournalNode | JournalNode |
DataNode | DataNode | DataNode |
ZK | ZK | ZK |
ResourceManager | ResourceManager | |
NodeManager | NodeManager | NodeManager |
3、具体配置
(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>hadoop101</value>
</property><property>
<name>yarn.resourcemanager.hostname.rm2</name>
<value>hadoop102</value>
</property>
<!--指定zookeeper集群的地址-->
<property>
<name>yarn.resourcemanager.zk-address</name>
<value>hadoop101:2181,hadoop102:2181,hadoop103: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)同步更新其他节点的配置信息
4、启动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
5、启动 YARN
(1)在 hadoop101 中执行
sbin/start-yarn.sh
(2)在 hadoop102 中执行
sbin/yarn-daemon.sh start resourcemanager
(3)查看服务状态
bin/yarn rmadmin -getServiceState rm1
HDFS Federation架构设计
1、NameNode架构的局限性
(1)Namespace(命名空间)的限制
由于NameNode在内存中存储所有的元数据(metadata),因此单个NameNode所能存储的对象(文件+块)数目受到NameNode所在JVM的heap size的限制。50G的heap能够存储20亿(200million)个对象,这20亿个对象支持4000个DataNode,12PB的存储(假设文件平均大小为40MB)。随着数据的飞速增长,存储的需求也随之增长。单个DataNode从4T增长到36T,集群的尺寸增长到8000个DataNode。存储的需求从12PB增长到大于100PB。
(2)隔离问题
由于HDFS仅有一个NameNode,无法隔离各个程序,因此HDFS上的一个实验程序就很有可能影响整个HDFS上运行的程序。
(3)性能的瓶颈
由于是单个NameNode的HDFS架构,因此整个HDFS文件系统的吞吐量受限于单个NameNode的吞吐量。
2、HDFS Federation架构设计
能不能有多个 NN 呢?
NameNode | NameNode | NameNode |
元数据 | 元数据 | 元数据 |
Log | machine | 电商数据/话单数据 |
3、HDFS Federation应用思考
不同应用可以使用不同的 NameNode 进行数据管理
如:图片业务、日志审计业务、客户业务
Hadoop 生态系统中,不同的框架使用不同的 NameNode 进行管理 NameSpace。(隔离性)