ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

HDFS的高可用

2021-07-16 09:32:53  阅读:227  来源: 互联网

标签:HDFS 可用 hadoop bigdata02 bigdata01 namenode root 2026


下面我们首先来看一下HDFS的高可用,也可以称之为HA(High Available)
在这里插入图片描述
HDFS的HA,指的是在一个集群中存在多个NameNode,分别运行在独立的物理节点上。在任何时间 点,只有一个NameNode是处于Active状态,其它的是处于Standby状态。 Active NameNode(简写为 Active NN)负责所有的客户端的操作,而Standby NameNode(简写为Standby NN)用来同步Active NameNode的状态信息,以提供快速的故障恢复能力。

为了保证Active NN与Standby NN节点状态同步,即元数据保持一致。除了DataNode需要向这些 NameNode发送block位置信息外,还构建了一组独立的守护进程”JournalNodes”(简写为JN),用来同 步Edits信息。当Active NN执行任何有关命名空间的修改,它需要持久化到一半以上的JNs上。而 Standby NN负责观察JNs的变化,读取从Active NN发送过来的Edits信息,并更新自己内部的命名空间。 一旦Active NN遇到错误,Standby NN需要保证从JNs中读出了全部的Edits,然后切换成Active状态,如 果有多个Standby NN,还会涉及到选主的操作,选择一个切换为Active 状态。

需要注意一点,为了保证Active NN与Standby NN节点状态同步,即元数据保持一致

这里的元数据包含两块,一个是静态的,一个是动态的

静态的是fsimage和edits,其实fsimage是由edits文件合并生成的,所以只需要保证edits文件内容的一 致性。这个就是需要保证多个NameNode中edits文件内容的事务性同步。这块的工作是由JournalNodes 集群进行同步的

动态数据是指block和DataNode节点的信息,这个如何保证呢? 当DataNode启动的时候,上报数据信息的时候需要向每个NameNode都上报一份。 这样就可以保证多个NameNode的元数据信息都一样了,当一个NameNode down掉以后,立刻从 Standby NN中选择一个进行接管,没有影响,因为每个NameNode 的元数据时刻都是同步的。

注意:使用HA的时候,不能启动SecondaryNameNode,会出错。 之前是SecondaryNameNode负责合并edits到fsimage文件 那么现在这个工作被standby NN负 责了。

NameNode 切换可以自动切换,也可以手工切换,如果想要实现自动切换,需要使用到zookeeper集群。

使用zookeeper集群自动切换的原理是这样的:

当多个NameNode 启动的时候会向zookeeper中注册一个临时节点,当NameNode挂掉的时候,这个临 时节点也就消失了,这属于zookeeper的特性,这个时候,zookeeper就会有一个watcher监视器监视 到,就知道这个节点down掉了,然后会选择一个节点转为Active,把down掉的节点转为Standby。

下面开始配置HDFS 的HA
HA集群规划
nodenamenodedatanodejournalnodezkfczookeeper
bigdata01yesyesyesyes
bigdata02yesyesyesyesyes
bigdata03yesyesyesyes

解释:针对HDFS的HA集群,在这里我们只需要启动HDFS相关的进程即可,YARN相关的进程可以不启动,它们两个的进程本来就是相互独立的。

在HDFS的HA集群中,就不需要启动SecondaryNameNode进程了

  • namenode: hdfs的主节点
  • datanode: hdfs的从节点
  • journalnode: JournalNode进程,用来同步Edits信息的
  • zkfc(DFSZKFailoverController): 监视namenode的状态,负责切换namenode节点的状态
  • zookeeper(QuorumPeerMain): 保存ha集群的节点状态信息
环境准备:三个节点
bigdata01 192.168.182.100
bigdata02 192.168.182.101
bigdata03 192.168.182.102

每个节点的基础环境都要先配置好,先把ip、hostname、firewalld、ssh免密码登录、host、免密码登录,JDK这些基础环境配置好

我们在这里需要使用到zookeeper这个组件,所以先把它安装起来。这里可以参考《Zookeeper急速入门与集群环境搭建》

安装完成后,分别在bigdata01、bigdata02、bigdata03上启动zookeeper进程

验证

分别在bigdata01、bigdata02、bigdata03上执行jps命令验证是否有QuorumPeerMain进程 如果都有就说明zookeeper集群启动正常了 如果没有就到对应的节点的logs目录下查看zookeeper*-*.out日志文件

执行bin/zkServer.sh status 命令会发现有一个节点显示为leader,其他两个节点为follower

  • bigdata01
[root@bigdata01 apache-zookeeper-3.5.8-bin]# bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /data/soft/apache-zookeeper-3.5.8-bin/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost.
Mode: follower
  • bigdata02
[root@bigdata02 apache-zookeeper-3.5.8-bin]# bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /data/soft/apache-zookeeper-3.5.8-bin/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost.
Mode: leader
  • bigdata03
[root@bigdata03 apache-zookeeper-3.5.8-bin]# bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /data/soft/apache-zookeeper-3.5.8-bin/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost.
Mode: follower
接下来我们来配置Hadoop集群
  1. 先在bigdata01节点上进行配置
[root@bigdata01 soft]# tar -zxvf hadoop-3.2.0.tar.gz
  1. 修改hadoop相关配置文件
    进入配置文件所在目录
[root@bigdata01 soft]# cd hadoop-3.2.0/etc/hadoop/
[root@bigdata01 hadoop]# vi hadoop-env.sh
export JAVA_HOME=/data/soft/jdk1.8
export HADOOP_LOG_DIR=/data/hadoop_repo/logs/hadoop

修改core-site.xml文件

<configuration>
	# mycluster是集群的逻辑名称,需要和hdfs-site.xml中dfs.nameservices值一致 
	<property>
        <name>fs.defaultFS</name>
        <value>hdfs://mycluster</value>
    </property>
    <property>
        <name>hadoop.tmp.dir</name>
        <value>/data/hadoop_repo</value>
	</property>
	# 用户角色配置,不配置此项会导致web页面报错 
	<property>
        <name>hadoop.http.staticuser.user</name>
        <value>root</value>
    </property>
	# zookeeper集群地址 
	<property>
        <name>ha.zookeeper.quorum</name>
        <value>bigdata01:2181,bigdata02:2181,bigdata03:2181</value>
    </property>
</configuration>

修改hdfs-site.xml文件

<configuration>
    <property>
        <name>dfs.replication</name>
        <value>2</value>
	</property>
	# 自定义的集群名称 
	<property>
        <name>dfs.nameservices</name>
        <value>mycluster</value>
    </property>
	# 所有的namenode列表,逻辑名称,不是namenode所在的主机名 
	<property>
        <name>dfs.ha.namenodes.mycluster</name>
        <value>nn1,nn2</value>
    </property>
	# namenode之间用于RPC通信的地址,value填写namenode所在的主机地址 # 默认端口8020,注意mycluster与nn1要和前面的配置一致
	<property>
        <name>dfs.namenode.rpc-address.mycluster.nn1</name>
        <value>bigdata01:8020</value>
    </property>
    <property>
        <name>dfs.namenode.rpc-address.mycluster.nn2</name>
        <value>bigdata02:8020</value>
    </property>
    # namenode的web访问地址,默认端口9870
    <property>
    	<name>dfs.namenode.http-address.mycluster.nn1</name>
        <value>bigdata01:9870</value>
    </property>
    <property>
        <name>dfs.namenode.http-address.mycluster.nn2</name>
        <value>bigdata02:9870</value>
	</property>
	# journalnode主机地址,最少三台,默认端口8485 
	<property>
        <name>dfs.namenode.shared.edits.dir</name>
		<value>qjournal://bigdata01:8485;bigdata02:8485;bigdata03:8485/myclus
    </property>
	# 故障时自动切换的实现类 
	<property>
        <name>dfs.client.failover.proxy.provider.mycluster</name>
		<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverPr
    </property>
	# 故障时相互操作方式(namenode要切换active和standby),使用ssh方式 	
	<property>
    	<name>dfs.ha.fencing.methods</name>
		<value>sshfence</value> 
	</property>
	# 修改为自己用户的ssh key存放地址 
	<property>
     	<name>dfs.ha.fencing.ssh.private-key-files</name>
		<value>/root/.ssh/id_rsa</value>
	</property>
	# namenode日志文件输出路径,即journalnode读取变更的位置 
	<property>
        <name>dfs.journalnode.edits.dir</name>
        <value>/data/hadoop_repo/journalnode</value>
    </property>
    # 启用自动故障转移 
    <property>
        <name>dfs.ha.automatic-failover.enabled</name>
        <value>true</value>
    </property>
</configuration>

mapred-site.xml和yarn-site.xml在这暂时就不修改了,因为我们只需要启动hdfs相关的服务。

修改workers文件,增加所有从节点的主机名,一个一行

[root@bigdata01 hadoop]# vi workers
bigdata02
bigdata03

修改启动脚本
修改 start-dfs.shstop-dfs.sh 这两个脚本文件,在文件前面增加如下内容

[root@bigdata01 hadoop]# cd /data/soft/hadoop-3.2.0/sbin
[root@bigdata01 sbin]# vi start-dfs.sh
HDFS_DATANODE_USER=root
HDFS_DATANODE_SECURE_USER=hdfs
HDFS_NAMENODE_USER=root
HDFS_ZKFC_USER=root
HDFS_JOURNALNODE_USER=root


[root@bigdata01 sbin]# vi stop-dfs.sh
HDFS_DATANODE_USER=root
HDFS_DATANODE_SECURE_USER=hdfs
HDFS_NAMENODE_USER=root
HDFS_ZKFC_USER=root
HDFS_JOURNALNODE_USER=root

start-yarn.sh , stop-yarn.sh 这两个脚本暂时也不需要修改了,因为不启动YARN相关的进程用不到。

  1. 把bigdata01节点上将修改好配置的安装包拷贝到其他两个从节点
[root@bigdata01 sbin]# cd /data/soft/
[root@bigdata01 soft]# scp -rq hadoop-3.2.0 bigdata02:/data/soft/
[root@bigdata01 soft]# scp -rq hadoop-3.2.0 bigdata03:/data/soft/
  1. 格式化HDFS【此步骤只需要在第一次配置HA集群的时候操作一次即可】
    注意:此时在格式化HDFS之前需要先启动所有的journalnode
[root@bigdata01 hadoop-3.2.0]# bin/hdfs --daemon start journalnode
[root@bigdata02 hadoop-3.2.0]# bin/hdfs --daemon start journalnode
[root@bigdata03 hadoop-3.2.0]# bin/hdfs --daemon start journalnode

接下来就可以对HDFS进行格式化了,此时在哪个namenode节点上操作都可以(bigdata01或者 bigdata02),在这我们使用bigdata01

能看到has been successfully formatted就说明hdfs格式化成功了

[root@bigdata01 hadoop-3.2.0]# bin/hdfs namenode -format
....
....
2026-02-07 00:35:06,212 INFO common.Storage: Storage directory /data/hadoop_r
2026-02-07 00:35:06,311 INFO namenode.FSImageFormatProtobuf: Saving image fil
2026-02-07 00:35:06,399 INFO namenode.FSImageFormatProtobuf: Image file /data
2026-02-07 00:35:06,405 INFO namenode.NNStorageRetentionManager: Going to ret
2026-02-07 00:35:06,432 INFO namenode.NameNode: SHUTDOWN_MSG:
/************************************************************
SHUTDOWN_MSG: Shutting down NameNode at bigdata01/192.168.182.100
************************************************************/

然后启动此namenode进程

[root@bigdata01 hadoop-3.2.0]# bin/hdfs --daemon start namenode

接下来在另一个namenode节点(bigdata02)上同步信息,看到下面的信息,则说明同步成功

[root@bigdata02 hadoop-3.2.0]# bin/hdfs namenode -bootstrapStandby
....
....
=====================================================
About to bootstrap Standby ID nn2 from:
           Nameservice ID: mycluster
        Other Namenode ID: nn1
  Other NN's HTTP address: http://bigdata01:9870
  Other NN's IPC address: bigdata01/192.168.182.100:8020
  Namespace ID: 1820763709
              Block pool ID: BP-1332041116-192.168.182.100-1770395706205
               Cluster ID: CID-c12130ca-3a7d-4722-93b0-a79b0df3ed84
           Layout version: -65
       isUpgradeFinalized: true
=====================================================
2026-02-07 00:39:38,594 INFO common.Storage: Storage directory /data/hadoop_r
2026-02-07 00:39:38,654 INFO namenode.FSEditLog: Edit logging is async:true
2026-02-07 00:39:38,767 INFO namenode.TransferFsImage: Opening connection to
2026-02-07 00:39:38,854 INFO common.Util: Combined time for file download and
2026-02-07 00:39:38,855 INFO namenode.TransferFsImage: Downloaded file fsimag
2026-02-07 00:39:38,894 INFO namenode.NameNode: SHUTDOWN_MSG:
/************************************************************
SHUTDOWN_MSG: Shutting down NameNode at bigdata02/192.168.182.101
************************************************************/
  1. 格式化zookeeper节点【此步骤只需要在第一次配置HA集群的时候操作一次即可】
    在任意一个节点上操作都可以,在这里我使用bigdata01节点
    能看到日志中输出Successfully created /hadoop-ha/mycluster in ZK,则说明操作成功
[root@bigdata01 hadoop-3.2.0]# bin/hdfs zkfc -formatZK
....
....
2026-02-07 00:42:17,212 INFO zookeeper.ClientCnxn: Socket connection establis 2026-02-07 00:42:17,220 INFO zookeeper.ClientCnxn: Session establishment comp 2026-02-07 00:42:17,244 INFO ha.ActiveStandbyElector: Successfully created /h 2026-02-07 00:42:17,249 INFO zookeeper.ZooKeeper: Session: 0x100001104b00098 2026-02-07 00:42:17,251 WARN ha.ActiveStandbyElector: Ignoring stale result f 2026-02-07 00:42:17,251 INFO zookeeper.ClientCnxn: EventThread shut down for 2026-02-07 00:42:17,254 INFO tools.DFSZKFailoverController: SHUTDOWN_MSG: /************************************************************  SHUTDOWN_MSG: Shutting down DFSZKFailoverController at bigdata01/192.168.182. ************************************************************/
  1. 启动HDFS的HA集群
    注意:以后启动HDFS的HA集群直接使用这里面的命令即可,不需要再执行4、5步中的操作了
    在bigdata01上执行下面命令
[root@bigdata01 hadoop-3.2.0]# sbin/start-dfs.sh
Starting namenodes on [bigdata01 bigdata02]
Last login: Sat Feb  7 00:02:27 CST 2026 on pts/0
bigdata01: namenode is running as process 6424.  Stop it first.
Starting datanodes
Last login: Sat Feb  7 00:47:13 CST 2026 on pts/0
Starting journal nodes [bigdata01 bigdata03 bigdata02]
Last login: Sat Feb  7 00:47:13 CST 2026 on pts/0
bigdata02: journalnode is running as process 4864.  Stop it first.
bigdata01: journalnode is running as process 6276.  Stop it first.
bigdata03: journalnode is running as process 2479.  Stop it first.
Starting ZK Failover Controllers on NN hosts [bigdata01 bigdata02]
Last login: Sat Feb  7 00:47:18 CST 2026 on pts/0
  1. 验证HA集群
    此时访问两个namenode节点的9870端口http://bigdata01:9870/dfshealth.html, http://bigdata02:9870/dfshealth.html,其中一个显示为Active,另一个显示为Standby

我们也可以来手工停掉active状态的namenode,模拟namenode宕机的情况,验证一下另一个standby的 namenode是否可以自动切换为active

[root@bigdata01 hadoop-3.2.0]# jps
8758 DFSZKFailoverController
8267 NameNode
1581 QuorumPeerMain
8541 JournalNode
8814 Jps
[root@bigdata01 hadoop-3.2.0]# kill 8267
[root@bigdata01 hadoop-3.2.0]# jps
8758 DFSZKFailoverController
1581 QuorumPeerMain
8541 JournalNode
8845 Jps

此时再刷新查看bigdata02的信息,会发现它的状态变为了active

接着我们再把bigdata01中的namenode启动起来,会发现它的状态变为了standby

通过前面的操作可以发现,现在的namenode其实就解决了单点故障的问题,实现了高可用。

  1. 停止HDFS的HA集群
[root@bigdata01 hadoop-3.2.0]# sbin/stop-dfs.sh
Stopping namenodes on [bigdata01 bigdata02]
Last login: Sat Feb  7 00:52:01 CST 2026 on pts/0
Stopping datanodes
Last login: Sat Feb  7 01:03:23 CST 2026 on pts/0
Stopping journal nodes [bigdata01 bigdata03 bigdata02]
Last login: Sat Feb  7 01:03:25 CST 2026 on pts/0
Stopping ZK Failover Controllers on NN hosts [bigdata01 bigdata02]
Last login: Sat Feb  7 01:03:29 CST 2026 on pts/0

到这里,我们HDFS的高可用搭建就结束了!

标签:HDFS,可用,hadoop,bigdata02,bigdata01,namenode,root,2026
来源: https://blog.csdn.net/lt326030434/article/details/118784002

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有