Hadoop系列:基于ZooKeeper搭建Hadoop高可用集群
高可用简介 Hadoop的高可用可以分为HDFS高可用和YARN高可用。它们的实现基本相似,但是HDFS NameNode比YARN Resource Manger需要更高的数据存储和一致性,所以它的实现更加复杂。因此,让我们解释以下内容: 1.1 高可用架构 HDFS高可用架构如下: 图片引用自:https://www.edureka.co/blog/how-to-set-up-hadoop-c
高可用简介
Hadoop的高可用可以分为HDFS高可用和YARN高可用。它们的实现基本相似,但是HDFS NameNode比YARN Resource Manger需要更高的数据存储和一致性,所以它的实现更加复杂。因此,让我们解释以下内容:
1.1 高可用架构
HDFS高可用架构如下:
图片引用自:https://www.edureka.co/blog/how-to-set-up-hadoop-cluster-with-hdfs-high-availability/
HDFS 高可用性架构由以下组件组成:
-
Active NameNode和Standby NameNode:两个NameNode是互为可用的。一个处于Active状态,主NameNode,另一个处于Standby状态。只有主 NameNode 才能对外提供读写服务。
-
ZKFailover Controller:ZKFailover Controller作为一个独立的进程运行,它控制着NameNode的主开关。 ZKFailover Controller可以及时检测NameNode的健康状态,并在主NameNode出现故障时与Zookeeper实现自动备份选举和切换。当然,NameNode 也支持无需 Zookeeper 的手动备份切换。
-
Zookeeper Cluster:为备份切换控制器提供备份选举支持。
-
共享存储系统:共享存储系统是实现NameNode高可用最关键的部分。共享存储系统保存了 NameNode 在运行过程中产生的 HDFS 的元数据。 Master NameNode和NameNode通过共享存储系统实现元数据同步。在主备切换时,新的主NameNode只有在确认元数据完全同步后才能继续提供服务。
-
DataNode节点:除了通过共享存储系统共享HDFS的元数据信息外,主NameNode和备用NameNode也需要HDFS数据块与DataNode的映射关系。 DataNode 向主 NameNode 和备用 NameNode 上报数据块的位置信息。
1.2 基于QJM的共享存储系统数据同步机制分析
目前,Hadoop 支持使用 Quorum Journal Manager (QJM) 或 Network File System (NFS) 作为共享存储系统。本文以QJM集群为例进行说明:Active NameNode首先向Journal Node集群提交EditLog,然后Standby NameNode从Journal Node集群同步EditLog,当A的active NameNode宕机后,Standby NameNode可以对外提供服务确认元数据已完全同步。
需要注意的是,将EditLog写入JournalNode集群遵循“过半写入成功”的策略,因此至少需要三个JournalNode节点。当然,你可以继续增加节点数,但要保证总节点数为奇数。同时,如果有2N+1个JournalNode,那么按照过半写的原则,最多可以容忍N个JournalNode节点挂掉。
1.3 NameNode主备切换
NameNode的主备切换流程如下图所示:
- Health Monitor初始化完成后,启动内部线程周期性调用NameNode的HASERVICE Protocol RPC接口对应的方法,检测NameNode的健康状态。
2、如果Health Monitor检测到NameNode的健康状态发生变化,则回调ZKFailover Controller注册的相应方法进行处理。
3、如果ZKFailover Controller判断需要主备切换,会先使用Active Standby Elector进行自动主选举。
- Active Standby选举人与Zookeeper交互,完成一次自动备份选举。
5、Active Standby Elector回调ZKFailover Controller的相应方法,通知当前NameNode在主选举完成后成为主NameNode或备用NameNode。
6、ZKFailover Controller调用NameNode对应的HASERVICE Protocol RPC接口,将NameNode转换为Active或Standby状态。
1.4 YARN 高可用
YARN Resource Manager 的高可用类似于 HDFS NameNode 的高可用。但是与NameNode不同的是,ResourceManager没有那么多元数据信息需要维护,所以它的状态信息可以直接写入Zookeeper,依赖Zookeeper进行主备选举。
二.集群规划
按照高可用的设计目标,至少需要保证2个NameNode和2个ResourceManager,同时至少需要3个Journal Node,才能满足“过半写入成功”的原则。三台主机用于构建集群。集群规划如下:
前置条件
-
JDK安装在所有服务器上。安装步骤可以看如下:Linux下JDK的安装;
-
搭建ZooKeeper集群,步骤可以看如下:Zookeeper单机环境和集群环境搭建
-
所有服务器之间配置SSH免密登录。
四.集群配置
4.1 下载解压
下载 Hadoop。这里我下载了CDH版本的Hadoop,下载地址是:http://archive.cloudera.com/cdh5/cdh/5/
# tar -zvxf hadoop-2.6.0-cdh5.15.2.tar.gz
4.2 配置环境变量
编辑配置文件:
# vim /etc/profile
添加以下配置:
导出 HADOOP_HOMEu003d/usr/app/hadoop-2.6.0-cdh5.15.2
导出 PATHu003d${HADOOP_HOME}/bin:$PATH
执行source命令使配置立即生效:
# 源 /etc/profile
4.3 配置修改
进入 ${HADOOP_HOME}/etc/hadoop 目录,修改配置文件。每个配置文件的内容如下:
1. hadoop-env.sh
# 指定JDK的安装位置
导出 JAVA_HOMEu003d/usr/java/jdk1.8.0_201/
2.核心站点.xml
<配置>
<属性>
<!-- 指定namenode的hdfs协议文件系统通信地址-->
<name>fs.defaultFS</name>
<value>hdfs://hadoop001:8020</value>
</属性>
<属性>
<!-- 指定hadoop集群中存储的临时文件目录 -->
<name>hadoop.tmp.dir</name>
<值>/home/hadoop/tmp</值>
</属性>
<属性>
<!-- 集群的 ZooKeeper 地址 -->
<name>ha.zookeeper.quorum</name>
<value>hadoop001:2181,hadoop002:2181,hadoop002:2181</value>
</属性>
<属性>
<!-- ZKFC 连接到 ZooKeeper 超时持续时间 -->
<name>ha.zookeeper.session-timeout.ms</name>
<值>10000</值>
</属性>
</配置>
3. hdfs-site.xml
<配置>
<属性>
<!-- 指定HDFS副本数-->
<name>dfs.replication</name>
<值>3</值>
</属性>
<属性>
<!-- namenode 节点数据(即元数据)的存储位置,可以指定多个目录进行容错,多个目录之间用逗号分隔。 -->
<name>dfs.namenode.name.dir</name>
<value>/home/hadoop/namenode/data</value>
</属性>
<属性>
<!-- datanode 节点数据(即数据块)的存储位置 -->
<name>dfs.datanode.data.dir</name>
<value>/home/hadoop/datanode/data</value>
</属性>
<属性>
<!-- 集群服务的逻辑名-->
<name>dfs.nameservices</name>
<value>我的集群</value>
</属性>
<属性>
<!-- NameNode ID 列表-->
<name>dfs.ha.namenodes.mycluster</name>
<value>nn1,nn2</value>
</属性>
<属性>
<!-- nn1 的 RPC 邮件地址 -->
<name>dfs.namenode.rpc-address.mycluster.nn1</name>
<value>hadoop001:8020</value>
</属性>
<属性>
<!-- nn2 的 RPC 邮件地址 -->
<name>dfs.namenode.rpc-address.mycluster.nn2</name>
<value>hadoop002:8020</value>
</属性>
<属性>
<!-- nn1 的http 邮件地址-->
<name>dfs.namenode.http-address.mycluster.nn1</name>
<value>hadoop001:50070</value>
</属性>
<属性>
<!-- nn2 的http 邮件地址-->
<name>dfs.namenode.http-address.mycluster.nn2</name>
<value>hadoop002:50070</value>
</属性>
<属性>
<!-- NameNode Metadata in JournalNode 共享存储目录上 -->
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://hadoop001:8485;hadoop002:8485;hadoop003:8485/mycluster</value>
</属性>
<属性>
<!-- 期刊编辑文件存储目录-->
<name>dfs.journalnode.edits.dir</name>
<value>/home/hadoop/journalnode/data</value>
</属性>
<属性>
<!-- 配置隔离机制,保证任何时候只有一个NameNode处于活动状态-->
<name>dfs.ha.fencing.methods</name>
<value>sshfence</value>
</属性>
<属性>
<!-- 使用 sshfence 需要的机制 ssh 隐私免费登录 -->
<name>dfs.ha.fencing.ssh.private-key-files</name>
<值>/root/.ssh/id_rsa</值>
</属性>
<属性>
<!-- SSH 超时 -->
<name>dfs.ha.fencing.ssh.connect-timeout</name>
<值>30000</值>
</属性>
<属性>
<!-- 访问代理类判断当前状态Active State NameNode -->
<name>dfs.client.failover.proxy.provider.mycluster</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</属性>
<属性>
<!-- 开启自动故障转移 -->
<name>dfs.ha.automatic-failover.enabled</name>
<值>真</值>
</属性>
</配置>
4.纱线站点.xml
<配置>
<属性>
<!--配置NodeManager上运行的Accessory服务。需要配置 mapreduce_shuffle 才可以 Yarn Up 操作 MapReduce 程序。-->
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</属性>
<属性>
<!-- 是否开启日志聚合(可选)-->
<name>yarn.log-aggregation-enable</name>
<值>真</值>
</属性>
<属性>
<!-- 聚合日志的存储时间(可选)-->
<name>yarn.log-aggregation.retain-seconds</name>
<值>86400</值>
</属性>
<属性>
<!-- 启用 RM HA -->
<name>yarn.resourcemanager.ha.enabled</name>
<值>真</值>
</属性>
<属性>
<!-- RM 集群标识符 -->
<name>yarn.resourcemanager.cluster-id</name>
<value>我的纱线集群</value>
</属性>
<属性>
<!-- RM 逻辑 ID 列表 -->
<name>yarn.resourcemanager.ha.rm-ids</name>
<值>rm1,rm2</值>
</属性>
<属性>
<!-- RM1 服务地址 -->
<name>yarn.resourcemanager.hostname.rm1</name>
<value>hadoop002</value>
</属性>
<属性>
<!-- RM2 服务地址 -->
<name>yarn.resourcemanager.hostname.rm2</name>
<value>hadoop003</value>
</属性>
<属性>
<!-- RM1 应用程序的网址 -->
<name>yarn.resourcemanager.webapp.address.rm1</name>
<value>hadoop002:8088</value>
</属性>
<属性>
<!-- RM2 申请网址 -->
<name>yarn.resourcemanager.webapp.address.rm2</name>
<value>hadoop003:8088</value>
</属性>
<属性>
<!-- 集群的 ZooKeeper 地址 -->
<name>yarn.resourcemanager.zk-address</name>
<value>hadoop001:2181,hadoop002:2181,hadoop003:2181</value>
</属性>
<属性>
<!-- 开启自动恢复 -->
<name>yarn.resourcemanager.recovery.enabled</name>
<值>真</值>
</属性>
<属性>
<!-- 持久存储类 -->
<name>yarn.resourcemanager.store.class</name>
<value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value>
</属性>
</配置>
5. mapred-site.xml
<配置>
<属性>
<!--指定mapreduce作业在yarn upper-->
<name>mapreduce.framework.name</name>
<值>纱线</值>
</属性>
</配置>
5.奴隶
配置所有下级节点的主机名或IP地址,每行一个。启动所有依赖节点上的DataNode服务和NodeManager服务。
hadoop001
hadoop002
hadoop003
4.4 分发程序
Hadoop安装包分发到另外两台服务器,建议两台服务器都配置Hadoop环境变量。
# 安装包分发到Hadoop 002
scp -r /usr/app/hadoop-2.6.0-cdh5.15.2/hadoop002:/usr/app/
分发安装包到Hadoop 003
scp -r /usr/app/hadoop-2.6.0-cdh5.15.2/hadoop003:/usr/app/
五、启动集群
5.1 启动ZooKeeper
在三台服务器上启动 ZooKeeper 服务:
zkServer.sh 启动
5.2 启动日志节点
在三台服务器的${HADOOP_HOME}/sbin目录下启动journalnode进程:
hadoop-daemon.sh 启动日志节点
5.3 初始化NameNode
在hadop001上执行NameNode初始化命令:
hdfs 名称节点-格式
执行初始化命令后,需要将NameNode元数据目录的内容复制到其他未格式化的NameNode。元数据存储目录是hdfs-site.xml中的dfs.namenode.name.dir属性指定的目录。这里我们需要将其复制到 Hadoop 002:
scp -r /home/hadoop/namenode/data hadoop002:/home/hadoop/namenode/
5.4 HA状态的初始化
在任何 NameNode 上使用以下命令来初始化 ZooKeeper 中的 HA 状态:
hdfs zkfc -formatZK
5.5 启动HDFS
进入Hadoop 001的${HADOOP_HOME}/sbin目录,启动HDFS。此时会启动hadoop001和hadoop002上的NameNode服务以及三台服务器上的DataNode服务:
开始-dfs.sh
5.6 启动YARN
进入 Hadoop 002 的 ${HADOOP_HOME}/sbin 目录并启动 YARN。此时会启动hadoop002上的ResourceManager服务和三台服务器上的NodeManager服务:
启动-yarn.sh
需要注意的是,此时hadoop003上的ResourceManager服务通常是没有启动的,需要手动启动:
yarn-daemon.sh 启动资源管理器
6.查看集群
6.1 查看进程
启动成功后,每台服务器上的进程应该如下:
[root@hadoop001 sbin]# jps
4512 DFSZK故障转移控制器
3714 日志节点
4114 名称节点
3668 QuorumPeerMain
5012 数据节点
4639 节点管理器
[root@hadoop002 sbin]# jps
4499 资源管理器
4595 节点管理器
3465 QuorumPeerMain
3705 名称节点
3915 DFSZK故障转移控制器
5211 数据节点
3533 日志节点
[root@hadoop003 sbin]# jps
3491 日志节点
3942 节点管理器
4102 资源管理器
4201 数据节点
3435 QuorumPeerMain
6.2 查看网页界面
HDFS和YARN的端口号分别是50070和8080。界面应该如下:
Hadoop 001 上的 NameNode 目前可用:
Hadoop 002 上的 NameNode 处于待机状态:
<br/>
<br/>
Hadoop 002 上的资源管理器可用:
<br/>
! zoz100076](https://programming.vip/images/doc/0e56504d2610a34abcb91aa15b1eb146.jpg)
<br/>
hadoop003上的ResourceManager处于待机状态:
<br/>
<br/>
同时,界面中还有Journal Manager的相关信息:
<br/>
七.集群二次启动
上面集群的初始启动涉及到一些必要的初始化操作,所以过程略显繁琐。但是一旦集群搭建好了,再启动起来也很方便。步骤如下(首先确保ZooKeeper集群已经启动):
在Hadoop 001中启动HDFS时,会启动所有与HDFS相关的服务,包括NameNode、DataNode和JournalNode:
开始-dfs.sh
在 Hadoop 002 启动 YARN:
启动-yarn.sh
此时hadoop003上的ResourceManager服务通常没有启动,需要手动启动:
yarn-daemon.sh 启动资源管理器
参考资料
以上步骤主要参考官方文档:
-
使用 Quorum Journal Manager 的 HDFS 高可用性
-
ResourceManager 高可用性
Hadoop高可用原理的详细分析,请阅读:
Hadoop NameNode 高可用实现解析
更多大数据系列文章见GitHub开源项目:大数据介绍指南
更多推荐
所有评论(0)