大数据之四 hadoop HDFS HA 高可用的完全分布式

本文详细介绍了Hadoop高可用(HA)集群的搭建过程,包括配置静态IP、时间同步、SSH免密登录、Zookeeper集群配置、Hadoop集群配置等关键步骤,以及如何实现NameNode的高可用性和自动故障转移。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

HDFS HA

HA即为High Availability,用于解决NameNode单点故障问题,该特性通过热备的方式为主NameNode提供一个备用者,一旦主NameNode出现故障,可以迅速切换至备用的NameNode,从而实现对外提供更稳定的服务

SecondaryNameNode(冷备):只是阶段性的合并edits和fsimage。当NN失效的时候,SNN无法立刻提供服务,甚至无法保证数据完整性:在SNN进行合并时,如果NN数据丢失的话,SNN也无法感知到,从而丢失部分操作

HDFS HA提供两个NameNode,一个处于active状态,对外提供服务;另一个处于standby状态,同步元数据(在内存中)。当active状态的NameNode挂掉时,standby转为active。HA 是通过代理对外提供服务,客户端请求由代理接收然后转发到active状态的NN

为了能够实时同步Active和Standby两个NameNode的元数据信息,我们将元数据状态(fsimage)和对元数据的操作(editlog)存放到 journalnode 集群中,standby状态的NN实时从JN中读取数据并执行重演,同时所有DataNode向两个NameNode都发送心跳,从而保证两个NameNode状态的同步

JNN集群遵从半数以上的势力划分,所以其节点数量总为奇数。active-NN向JNN写入editlog时,当半数以上的JNN节点存储成功则停止写入,其它JNN节点从这些已写入的节点copy editlog。正常情况下集群内各节点间保持通信,standby-NN可以从任意节点上读取到正确的数据,若是因为不可抗力而导致集群分裂(集群内节点通讯中断),此时还可以相互通信的节点组成集群小势力,那么规定势力范围(集群内节点数量)小于半数的集群提供的数据视为无效。例如现在有3个JNN,分裂成了 1+1 和 1 两股势力,那么此时即使 1 中的数据是正确的也会被视为无效,standby得知其节点数小于半数时会转而去 1+1 中读取数据

接下来,如果active状态的NN挂掉了,我们就将另一台切换为active状态。那么问题来了,active状态的NN什么时候会挂掉呢?难道我们要一直盯着服务器看吗?这当然是不可能的。这里我们用到了zookeeper作为一个管理者代替我们进行监视。当然管理员也有管理员的脾气,所以监视这种累人的工作zookeeper就交给了FailoverController。于是FailoverController就开始了兢兢业业的工作,认真的监视着两个NN,并定时向zookeeper汇报NN的状态信息。如果active的NN挂掉了,FailoverController就汇报情况给zookeeper,得知情况后的zookeeper就通知监视另一个NN的FailoverController将standby的NN转为active(如果有多个standby的NN则由zookeeper选举出一个转为active)。

那么这里有一个问题就是如果监视active状态NN的FailoverController不幸挂掉了,那么一定时间内没有得到来自FailoverController心跳的zookeeper无法得知当前active状态的NN究竟是否存活,就会认为其已经挂掉,会去选举启动一个新的active-NN,那么这时可能就会同时存在两台active-NN,这时对外提供服务的代理可能就感觉不太好了,因为它无法确定要将请求转发到哪一台active-NN上。所以当FailoverController启动新的active-NN的同时也会将原来为active状态的NN置为standby而不管其是否已经挂掉,确保同一时间avtive状态的NN只有一台

HDFS HA集群框架图

HDFS HA集群架构

集群设计

现在以四台虚拟机(centOS6.5)为例,主机名分别为node01,node02,node03,node04.
NN-1–>NameNode( active )
NN-2–>NameNode( standby )
DN–>DataNode
ZK–>zookeeper
ZKFC–>FailoverController
JNN–>journalnode
集群设计

HDFS HA搭建步骤

  1. 首先确保各节点都配置好静态IP

  2. 配置各节点的hosts,修改/etc/hosts文件

[root@node01 ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.23.130 node01
192.168.23.131 node02
192.168.23.133 node03
192.168.23.134 node04
  1. 关闭各节点的防火墙
    使用 service iptables status 命令查看当前防火墙状态
    使用 service iptables stop 暂时关闭防火墙(防火墙会在下次开机时启动)
    使用 chkconfig iptables off 永久关闭防火墙(该命令在下次重启时生效)

  2. 时间同步
    首先在各个节点上使用 yum install ntp 安装ntp命令
    执行 ntpdate ntp1.aliyun.com 来同步时间(这里使用阿里云服务器的时间)

  3. 配置SSH免密登录
    在所有节点上执行ssh-keygen -t rsa -P ‘’ -f ~/.ssh/id_rsa
    如果安装的虚拟机是 minimal 模式,则在各个节点上执行 yum install -y openssh-clients
    在node01节点上执行以下命令(将node01的公钥加入到其他节点的白名单中

    ssh-copy-id -i ~/.ssh/id_rsa.pub root@node01
    ssh-copy-id -i ~/.ssh/id_rsa.pub root@node02
    ssh-copy-id -i ~/.ssh/id_rsa.pub root@node03
    ssh-copy-id -i ~/.ssh/id_rsa.pub root@node04

在node02节点上执行如下命令(将node02的公钥加入node01,即配置node02免密登录node01,从而实现两个NameNode节点免密登录,方便主NameNode挂掉时 standby转active)

ssh-copy-id -i ~/.ssh/id_rsa.pub root@node01
  1. 所有节点安装配置JDK
    所有节点在 /etc/profile 或 ~/.bashrc 中配置JDK环境变量
export JAVA_HOME=/opt/zgl/jdk1.8.0_151		<!-- 你的JDK的实际位置 -->
export PATH=$PATH:$JAVA_HOME/bin

刷新文件使配置生效 source /etc/profile

  1. 下载zookeeper安装包并解压,这里以 zookeeper-3.4.12 为例。zookeeper是运行在 node02,node03 和 node04 上的,这里我们先将安装包放在node02上进行配置,配置结束后发送到 node03 和 node04

  2. 将 zookeeper 安装包下 conf 目录下的 zoo_simple.cfg 修改为 zoo.cfg

[root@node02 conf]# mv  zoo_simple.cfg  zoo.cfg
  1. 修改 zoo.cfg 文件,修改 dataDir 的位置(随意修改)并添加服务配置,其中1、2、3是zookeeper的服务编号,后面是对应服务器的主机名
dataDir=/var/zgl/zookeeper
server.1=node02:2888:3888
server.2=node03:2888:3888
server.3=node04:2888:3888
  1. 在 dataDir 声明的目录下创建一个myid文件,在这个文件中写上当前节点所对应的服务ID号。当前为 node02 节点,由上配置 server.1=node02:2888:3888 确定服务ID号为 1
[root@node02 ~]# cat /var/zgl/zookeeper/myid 
1
  1. 将配置好的zookeeper安装包发送到node03 node04(注意目录对应)
[root@node02 zgl]# scp -r zookeeper-3.4.12 root@node03:/opt/zgl/
[root@node02 zgl]# scp -r zookeeper-3.4.12 root@node04:/opt/zgl/
  1. 在node03,node04 上分别修改 myid 中的 ID号。node03–>2,node04–>3

  2. 在 node02 node03 node04 上配置zookeeper的环境变量,这里配置到用户环境中,在 ~/.bashrc 文件中添加如下

export PATH=$PATH:/opt/zgl/zookeeper-3.4.12/bin
  1. 在 node02 node03 node04 上执行 zkServer.sh start 命令启动 zookeeper。
    使用 jps 命令查看,如果 QuorumPeerMain 进程启动则配置成功,成功后一直开着就好
[root@node04 zgl]# jps
22035 QuorumPeerMain
23100 Jps
  1. 下载 hadoop 安装包并解压,这里以 hadoop-2.6.5为例,先在 node01 上进行配置,配置完成后发送到其他节点

  2. 修改 hdfs-site.xml 文件

<property>
        <name>dfs.nameservices</name>			<!-- 配置一个服务(集群名称) -->
        <value>mycluster</value>
</property>

<property>
        <name>dfs.ha.namenodes.mycluster</name>		<!--  提供服务的节点 -->
        <value>nn1,nn2</value>
</property>

<!-- 配置两个NameNode的rpc协议的地址和端口 -->
<property>
        <name>dfs.namenode.rpc-address.mycluster.nn1</name>
        <value>node01:8020</value>
</property>
<property>
        <name>dfs.namenode.rpc-address.mycluster.nn2</name>
        <value>node02:8020</value>
</property>

<!-- 配置两个NameNode的http协议的地址和端口 -->
<property>
        <name>dfs.namenode.http-address.mycluster.nn1</name>
        <value>node01:50070</value>
</property>
<property>
        <name>dfs.namenode.http-address.mycluster.nn2</name>
        <value>node02:50070</value>
</property>

<!-- 设置journalnade的位置信息 -->
<property>
        <name>dfs.namenode.shared.edits.dir</name>
        <value>qjournal://node01:8485;node02:8485;node03:8485/mycluster</value>
</property>

<!-- journalnade保存数据用的目录-->
<property>
        <name>dfs.journalnode.edits.dir</name>
        <value>/var/zgl/hadoop/ha/jn</value>
</property>

<!-- 通过代理类来让客户端连接active的NameNode -->
<property>
        <name>dfs.client.failover.proxy.provider.mycluster</name>
        <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>

<!-- 通过远程登录,杀掉失联的 NameNode来保证只有一个active的NameNode(前提已经设置了免密登录) -->
<property>
        <name>dfs.ha.fencing.methods</name>
        <value>sshfence</value>
</property>
<property>
        <name>dfs.ha.fencing.ssh.private-key-files</name>
        <value>/root/.ssh/id_rsa</value>
</property>

<!--配置NameNode的自动切换的开关 -->
<property>
        <name>dfs.ha.automatic-failover.enabled</name>
        <value>true</value>
</property>
  1. 修改core-site.xml 文件
<property>
   	<name>fs.defaultFS</name>	<!--  HDFS文件默认地址前缀(简化实际访问时路径书写) -->
  	<value>hdfs://mycluster</value>
</property>

<!--配置三台zookeeper的位置信息 -->
<property>
   	<name>ha.zookeeper.quorum</name>
   	<value>node02:2181,node03:2181,node04:2181</value>
</property>

<property>
       <name>hadoop.tmp.dir</name>	<!-- HDFS文件存储位置 -->
       <value>/var/zgl/hadoop/cluster</value>
</property>
  1. 修改slaves配置文件。配置DataNode节点,注意每行写一个
node02
node03
node04
  1. 修改hadoop-env.sh配置文件
# 导入java home
export JAVA_HOME=/opt/zgl/jdk1.8.0_151
# 在hadoop-env.sh 配置一条hadoop配置文件所在目录
export HADOOP_CONF_DIR=/opt/zgl/hadoop-2.6.5/etc/hadoop

刷新文件使配置生效 source hadoop-env.sh

  1. 将配置好的hadoop安装包分发到其他节点上
    使用 scp 命令将hadoop安装包分发到其他节点,注意其他节点提前建好目录且与node01目录(名称,层级)保持一致
    eg: node01 /opt/zgl/hadoop-2.6.5 其他节点 /opt/zgl
  scp -r hadoop-2.6.5 root@node02:/opt/zgl/
  scp -r hadoop-2.6.5 root@node03:/opt/zgl
  scp -r hadoop-2.6.5 root@node04:/opt/zgl/
  1. 在各个节点上配置 hadoop 环境变量
vim ~/.bashrc

export HADOOP_HOME=/opt/zgl/hadoop-2.6.5
export PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin

source ~/.bashrc
  1. 确认关闭所有节点上的HDFS相关进程,在 node01 上执行
stop-dfs.sh
  1. 启动所有journalnode,在node01、node02、node03分别执行如下命令
hadoop-daemon.sh start journalnode
  1. 随机选择一台NameNode,这里在 node01 上执行初始化并启动active-NN
  hdfs namenode -format	//格式化
  hadoop-daemon.sh start namenode	//启动 namanode
  1. 另外一台NameNode(node02)节点执行同步active-NN的元数据
hdfs namenode  -bootstrapStandby
  1. 在 node01 或 node02 上初始化zookeeper
hdfs zkfc -formatZK
  1. 再次关闭所有节点上的HDFS相关进程
stop-dfs.sh
  1. 在 node01上启动HDFS集群
start-dfs.sh
  1. 在各个节点上使用 jps 查看启动进程
[root@node01 zgl]# jps
4804 DFSZKFailoverController
4666 JournalNode
4476 NameNode

[root@node02 ~]# jps
23217 DataNode
23155 NameNode
23301 JournalNode
23385 DFSZKFailoverController
22410 QuorumPeerMain

[root@node03 hadoop]# jps
3697 DataNode
3765 JournalNode
3068 QuorumPeerMain

[root@node04 zgl]# jps
22035 QuorumPeerMain
22454 DataNode
  1. 通过hadoop提供的 web UI 来进行查看
    打开浏览器,输入http://192.168.23.130:50070(因为主机 hosts 文件中并未配置node01,所以这里不能使用 http://node01:50070来访问),然后我们就来到如下页面,可以看到当前 node01 为active状态
    node01

再输入http://192.168.23.131:50070查看 node02 为 standby状态
node02

然后我们在 node01 上使用 kill 停止NameNode 进程,刷新页面发现 node02 状态变为active
切换

思维导图

HA

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值