打怪升级之小白的大数据之旅(五十八)
HadoopHA高可用
上次回顾
上一章,我们学习了Hadoop扩展内容–压缩的相关知识,本章为大家带来Hadoop的另一个扩展内容HA高可用技术,有了它,我们就再也不怕HDFS的NameNode泵机导致数据丢失了…
HA概述
- HA的意思就是高可用,即7*24小时不中断服务,有了它996什么的弱爆了
- 实现高可用最关键的策略是消除单点故障。HA严格来说应该分成各个组件的HA机制:HDFS的HA和YARN的HA
为什么要使用HA
- 还记得前面介绍HDFS的时候,提到过NameNode的节点遇到特殊情况会造成单点故障,我们通过2NN来恢复数据,并不能完全恢复数据吗?下面再来回顾一下NameNode可能发生单点故障的原因
- NameNode机器发生意外,如宕机,集群将无法使用,直到管理员重启
- NameNode机器需要升级,包括软件、硬件升级,此时集群也将无法使用
HA的工作原理
- HA通过双NameNode消除单点故障
- HDFS HA功能通过配置Active/Standby两个NameNodes实现在集群中对NameNode的热备来解决上述问题。
- 如果出现故障,如机器崩溃或机器需要升级维护,这时可通过此种方式将NameNode很快的切换到另外一台机器。
当然了,既然是双NameNode,必然会消耗我们的内存,对我们的硬件要求就高一些,相对来说,能用钱解决的问题就都不是问题…
HDFS-HA工作机制
详细工作机制我们可以参考官方文档:http://hadoop.apache.org/docs/r3.1.3/hadoop-yarn/hadoop-yarn-site/ResourceManagerHA.html
YARN-HA工作机制比较简单,我就直接总结了
- YARN-HA同样是建立在zookeeper基础之上,我们同样建立多台ResourceManager来解决单点故障问题
- 通过zookeeper来监控每一台ResourceManager,并且有active和standby两个状态
- 当监控状态出现异常,zookeeper会重新选另外一台ResourceManager,如果ResourceManager是假死,就会强制关闭假死的ResourceManager,并将该ResourceManager设为standby
HDFS-HA工作要点
- 元数据管理方式需要改变
- 内存中各自保存一份元数据;
- Edits日志只有Active状态的NameNode节点可以做写操作;
- 两个NameNode都可以读取Edits;
- 共享的Edits放在一个共享存储中管理(qjournal和NFS两个主流实现);
- 需要一个状态管理功能模块
- 实现了一个zkfailover,常驻在每一个namenode所在的节点,每一个zkfailover负责监控自己所在NameNode节点,
- 利用zk进行状态标识,当需要进行状态切换时,由zkfailover来负责切换,切换时需要防止brain split现象的发生。
- 必须保证两个NameNode之间能够ssh无密码登录
- 隔离(Fence),即同一时刻仅仅有一个NameNode对外提供服务
HDFS-HA自动故障转移的工作原理
-
故障检测
- 集群中的每个NameNode在ZooKeeper中维护了一个持久会话,如果机器崩溃,ZooKeeper中的会话将终止,
- ZooKeeper通知另一个NameNode需要触发故障转移。
-
现役NameNode选择
- ZooKeeper提供了一个简单的机制用于唯一的选择一个节点为active状态。
- 如果目前现役NameNode崩溃,另一个节点可能从ZooKeeper获得特殊的排外锁以表明它应该成为现役NameNode。
- ZKFC是自动故障转移中的另一个新组件,是ZooKeeper的客户端,也监视和管理NameNode的状态。
- 每个运行NameNode的主机也运行了一个ZKFC进程,ZKFC负责:
-
健康监测
- ZKFC使用一个健康检查命令定期地ping与之在相同主机的NameNode,
- 只要该NameNode及时地回复健康状态,ZKFC认为该节点是健康的。如果该节点崩溃,冻结或进入不健康状态,健康监测器标识该节点为非健康的。
-
ZooKeeper会话管理
- 当本地NameNode是健康的,ZKFC保持一个在ZooKeeper中打开的会话
- 如果本地NameNode处于active状态,ZKFC也保持一个特殊的znode锁,该锁使用了ZooKeeper对短暂节点的支持,
- 如果会话终止,锁节点将自动删除。
-
基于ZooKeeper的选择
- 如果本地NameNode是健康的,且ZKFC发现没有其它的节点当前持有znode锁,它将为自己获取该锁。
- 如果成功,则它已经赢得了选择,并负责运行故障转移进程以使它的本地NameNode为Active。
- 故障转移进程与前面描述的手动故障转移相似,首先如果必要保护之前的现役NameNode,然后本地NameNode转换为Active状态
-
注意一下,在Hadoop2.x版本,HA只有两台NameNode,而Hadoop3.x版本之后,可以同时有多台NameNode,那么自动故障转移是如何选取NameNode的呢?
-
其实,在它内部,会有一把锁,我们也就是前面说的隔离机制,在切换Namenode的时候,就让它们自己去抢锁,谁抢到了,谁就将状态改为Acitve
总结一下自动故障转移的流程哈:
- 首先我们NameNode工作时,会创建一个ZKFC,这个ZKFC我可以理解为zookeeper的客户端,ZKFC的主要工作就是监控当前NameNode的状态
- 每个NameNode会通过Edits文件管理系统qjournal来完成元数据的同步工作
- ZKFS会为NameNode做一个标识,active和standby,当前集群只会有一个active状态
- 如果状态异常,就会将状态通知zookeeper,zookeeper就会通过ZKFC将active的NameNode关闭并且通过抢锁来选出下一个Active的NameNode
NameNode的brain split脑裂
- 我们大概了解了HA的工作过程,就是通过zookeeper来使用多台NameNode,并为每台NameNode打上一个标识,工作active和待机standby
- 当active的NameNode因为网络延迟等原因进入了假死状态时,通过zookeeper已经让另外一台NameNode上位(变成active)
- 此时就会出现两台工作的NameNode,这个就是脑裂,为了防止脑裂的情况发生,zkfc就会对假死的那台NameNode进行补刀,强制让它下线
HDFS-HA集群配置
在官网中,官方给了我们两种设置HA的方式,我介绍的是QJM的方式来配置NameNode,如果大家想使用NFS的方式,直接进入官网查看即可
具体步骤如下:
第一步:准备工作
- 停掉Hadoop集群
- 创建快照(如果出现问题可以随时恢复)
- 在三台节点上 /opt下创建ha并设置所属主和所属组为hadoopuser
sudo mkdir ha sudo chown atguigu:atguigu ha
- 复制一份Hadoop软件包,专门用于HA,为了以后可以随时切换
cp -r /opt/module/hadoop-3.1.3/ /opt/ha/
- 删除拷贝过来的hadoop中的data logs (三台节点都要做)
rm -rf /opt/ha/hadoop-3.1.3/ data/ logs/ sudo rm -rf /tmp/*
- 修改环境变量(三台节点都要做)
- 将HADOOP_HOME指向ha下的hadoop
- 注意:一定要source。最好 echo $HADOOP_HOME查看是否生效
# 编辑配置文件 sudo vim /etc/profile.d/my_env.sh # 配置文件内容如下 #JAVA_HOME export JAVA_HOME=/opt/module/jdk1.8.0_212 # Hadoop_home # export HADOOP_HOME=/opt/module/hadoop-3.1.3 export HADOOP_HOME=/opt/ha/hadoop-3.1.3 # hive export HIVE_HOME=/opt/module/hive # zookeeper export ZOOKEPEER_HOME=/opt/module/zookeeper-3.5.7 export PATH=$PATH:$JAVA_HOME/bin export PATH=$PATH:$HADOOP_HOME/bin export PATH=$PATH:$HADOOP_HOME/sbin export PATH=$PATH:$ZOOKEPEER_HOME/bin export PATH=$PATH:$HIVE_HOME/bin
第二步: 配置HA
-
配置core-site.xml
<property> <name>fs.defaultFS</name> <value>hdfs://mycluster</value> </property> <property> <name>hadoop.data.dir</name> <value>/opt/ha/hadoop-3.1.3/data</value> </property>
-
配置hdfs-site.xml
<property> <name>dfs.namenode.name.dir</name> <value>file://${hadoop.data.dir}/name</value> </property> <property> <name>dfs.datanode.data.dir</name> <value>file://${hadoop.data.dir}/data</value> </property> <property> <name>dfs.nameservices</name> <value>mycluster</value> </property> <property> <name>dfs.ha.namenodes.mycluster</name> <value>nn1,nn2,nn3</value> </property> <property> <name>dfs.namenode.rpc-address.mycluster.nn1</name> <value>hadoop102:9820</value> </property> <property> <name>dfs.namenode.rpc-address.mycluster.nn2</name> <value>hadoop103:9820</value> </property> <property> <name>dfs.namenode.rpc-address.mycluster.nn3</name> <value>hadoop104:9820</value> </property> <property> <name>dfs.namenode.http-address.mycluster.nn1</name> <value>hadoop102:9870</value> </property> <property> <name>dfs.namenode.http-address.mycluster.nn2</name> <value>hadoop103:9870</value> </property> <property> <name>dfs.namenode.http-address.mycluster.nn3</name> <value>hadoop104:9870</value> </property> <property> <name>dfs.namenode.shared.edits.dir</name> <value>qjournal://hadoop102:8485;hadoop103:8485;hadoop104:8485/mycluster</value> </property> <!-- 访问代理类,client用于确定哪个NN为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</value> </property> <!-- 使用隔离机制时需要ssh无密登录 --> <property> <name>dfs.ha.fencing.ssh.private-key-files</name> <value>/home/atguigu/.ssh/id_rsa</value> </property> <!-- 指定NN的元数据在JournalNode的哪个位置存放 --> <property> <name>dfs.journalnode.edits.dir</name> <value>${hadoop.data.dir}/jn</value> </property>
-
分发配置文件
xsync /opt/ha/hadoop /opt/ha/hadoop
-
在三台节点上启动Edit文件管理系统journalnode
hdfs --daemon start journalnode
-
在任意一台节点格式化NameNode并启动,我以hadoop102为例
hdfs namenode -format hdfs --daemon start namenode
-
其他节点通过journalnode完成元数据同步
hdfs namenode -bootstrapStandby
-
在[hadoop103]和[hadoop104]上启动namenode并验证是否启动成功
hdfs --daemon start namenode
-
在所有节点上上,启动datanode
hdfs --daemon start datanode
-
将[nn1]切换为Active
hdfs haadmin -transitionToActive nn1
-
查看是否Active
hdfs haadmin -getServiceState nn1
第三步:配置自动故障转移
- 在hdfs-site.xml中增加下面配置信息
<property> <name>dfs.ha.automatic-failover.enabled</name> <value>true</value> </property>
- 在core-site.xml文件中增加下面配置信息
<property> <name>ha.zookeeper.quorum</name> <value>hadoop102:2181,hadoop103:2181,hadoop104:2181</value> </property>
- 分发配置文件
xsync /opt/ha/hadoop /opt/ha/hadoop
- 重新启动集群,并开启自动故障检测
(1)关闭所有HDFS服务: stop-dfs.sh (2)启动Zookeeper集群: zkServer.sh start (3)初始化HA在Zookeeper中状态: hdfs zkfc -formatZK (4)启动HDFS服务: start-dfs.sh
YARN-HA集群配置
准备工作:
- 在NN的HA已经配好的前提
YARN具体步骤如下
- 配置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,rm3</value> </property> <property> <name>yarn.resourcemanager.hostname.rm1</name> <value>hadoop102</value> </property> <property> <name>yarn.resourcemanager.hostname.rm3</name> <value>hadoop104</value> </property> <property> <name>yarn.resourcemanager.hostname.rm2</name> <value>hadoop103</value> </property> <!--指定zookeeper集群的地址--> <property> <name>yarn.resourcemanager.zk-address</name> <value>hadoop102:2181,hadoop103:2181,hadoop104: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>
- 在任意一台节点中执行yarn服务,我这里是在hadoop103节点上执行
start-yarn.sh
- 查看服务状态
yarn rmadmin -getServiceState rm1
总结
本章节对Hadoop的HA进行总结,当然了HA是在我们的数据量很大并且已经通过大数据分析,将我们的数据抽取出大量有用信息后,为了防止出现单机故障导致数据丢失而实现的一种解决方案,大家了解有这个东西,真的有这个需求了,回看这篇博客,按照我的方法进行配置即可