
在 Hadoop 生态系统中,NameNode 是文件系统的中心管理器,负责管理 HDFS 的元数据。为了避免单点故障(Single Point of Failure,SPOF),Hadoop 引入了 NameNode 的高可用性架构。主要组件包括:
Zookeeper 在 Hadoop HA 架构中用于管理 NameNode 的选主(leader election)和状态协调。它帮助确定当前哪个 NameNode 是 Active 的,并在故障发生时进行切换。
QJM 是管理 JournalNode 的组件,确保在集群中至少一半以上的 JournalNode 写入成功后,操作才被认为是持久化成功的。
Hadoop HA 中的 Failover 控制器(比如 ZKFailoverController)用于自动化主备 NameNode 的切换。它监控 Active NameNode 的健康状态,当检测到故障时,会自动切换到 Standby NameNode。
Standby NameNode 会定期从 JournalNode 读取编辑日志,并将它们应用到自己的内存中。与此同时,它还会创建新的检查点(checkpoint),以减少系统重启时的恢复时间。
这种 HA 架构确保了即使一个 NameNode 发生故障,另一个 NameNode 也能迅速接管,保证 HDFS 的高可用性和数据可靠性。
当前高可用在以下三台节点组成的hadoop3.3.4集群中进行配置,当前已经完成了集群安装,hdfs的验证,并且zookeeper组件已经安装完成。
hostname | ip |
|---|---|
ubuntu1 | 172.16.167.131 |
ubuntu2 | 172.16.167.132 |
ubuntu3 | 172.16.167.133 |
这是我当前配置 Hadoop HA(高可用)集群的hdfs-site.xml配置文件。
<configuration>
<property>
<name>dfs.replication</name>
<value>2</value>
</property>
<property>
<name>dfs.namenode.secondary.http-address</name>
<value>ubuntu2:9868</value>
</property>
<property>
<name>dfs.namenode.name.dir</name>
<value>file:/home/hadoop/dfs/name</value>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>file:/home/hadoop/dfs/data</value>
</property>
<property>
<name>dfs.namenode.rpc-address</name>
<value>ubuntu1:8020</value>
</property>
<property>
<name>dfs.namenode.rpc-address</name>
<value>ubuntu2:8020</value>
</property>
<!-- 高可用配置开始 -->
<property>
<name>dfs.nameservices</name>
<value>mycluster</value>
</property>
<property>
<name>dfs.ha.namenodes.mycluster</name>
<value>nn1,nn2</value>
</property>
<property>
<name>dfs.namenode.rpc-address.mycluster.nn1</name>
<value>ubuntu1:8020</value>
</property>
<property>
<name>dfs.namenode.rpc-address.mycluster.nn2</name>
<value>ubuntu2:8020</value>
</property>
<property>
<name>dfs.namenode.http-address.mycluster.nn1</name>
<value>ubuntu1:50070</value>
</property>
<property>
<name>dfs.namenode.http-address.mycluster.nn2</name>
<value>ubuntu2:50070</value>
</property>
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/usr/local/hadoop/data/journalnode</value>
</property>
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://ubuntu1:8485;ubuntu2:8485;ubuntu3:8485/mycluster</value>
</property>
<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>
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/root/.ssh/id_rsa</value>
</property>
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
<!-- 高可用配置结束 -->
</configuration>mycluster。mycluster 集群中包含的 NameNode,这里为 nn1 和 nn2。nn1 的 RPC 地址,提供 HDFS 服务。nn2 的 RPC 地址。nn1 的 HTTP Web 界面地址。nn2 的 HTTP Web 界面地址。qjournal://{host1:port};{host2:port};{host3:port}/clustername。ConfiguredFailoverProxyProvider,用于在 NameNode 之间自动切换。sshfence,即通过 SSH 命令来隔离失效的 NameNode。<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://mycluster</value>
</property>
<!--2.指定hadoop 数据的存储目录默认为/tmp/hadoop-${user.name} -->
<property>
<name>hadoop.tmp.dir</name>
<value>/home/hadoop/tmp</value>
</property>
<!--hive.hosts 允许 root 代理用户访问 Hadoop 文件系统设置 -->
<property>
<name>hadoop.proxyuser.root.hosts</name>
<value>*</value>
</property>
<!--hive.groups 允许 Hive 代理用户访问 Hadoop 文件系统设置 -->
<property>
<name>hadoop.proxyuser.root.groups</name>
<value>*</value>
</property>
<!-- 配置 HDFS 网页登录使用的静态用户为 root -->
<property>
<name>hadoop.http.staticuser.user</name>
<value>root</value>
</property>
<!--配置缓存区的大小,实际可根据服务器的性能动态做调整-->
<property>
<name>io.file.buffer.size</name>
<value>4096</value>
</property>
<!--开启hdfs垃圾回收机制,可以将删除数据从其中回收,单位为分钟-->
<property>
<name>fs.trash.interval</name>
<value>10080</value>
</property>
<!--zookeeper-->
<property>
<name>ha.zookeeper.quorum</name>
<value>ubuntu1:2181,ubuntu2:2181,ubuntu3:2181</value>
</property>
</configuration> core-site.xml 基于高可用的配置,主要用于配置 Hadoop 的核心设置,这里重点是zookeeper的配置项要加上。以下是每个配置项的解释:
hdfs://mycluster,表示使用高可用集群 mycluster 的 HDFS 作为默认文件系统。/tmp/hadoop-${user.name} 目录中,这里指定为 /home/hadoop/tmp。root 用户代理其他用户访问 Hadoop 文件系统的主机。* 表示允许所有主机。root 用户代理其他用户访问 Hadoop 文件系统的用户组。* 表示允许所有用户组。root。这意味着访问 HDFS Web UI 时将默认使用 root 用户身份。ubuntu1、ubuntu2 和 ubuntu3 上,端口号为 2181。修改完hdfs-site.xml和core-site.xml一定要向集群中所有节点分发。
由于更改了配置文件,所以要关闭集群再重启才能使高可用生效。
将hadoop集群所有组件停止服务。
stop-all.sh要保证zookeeper进程在后台运行,QuorumPeerMain需要在三台节点都运行。
在三台节点执行:
zkServer.sh start查看zookeeper状态:
zkServer.sh status成功显示leader和follower

journalnode在三台节点上都要启动:
hdfs --daemon start journalnode如果因为启动失败而重新配置,需要将目录中的数据删除,再次启动:
rm -rf /usr/local/hadoop/data/journalnode/mycluster/*NameNode的格式化,如果是第一次配置启动hadoop则需要格式化hdfs namenode -formathdfs namenode -initializeSharedEditsstart-dfs.sh
# 或者使用群起命令
start-all.sh如果启动时没有datanode进程,则应删除hdfs数据文件,避免clusterID冲突:
rm -rf /home/hadoop/dfs/data/*hdfs namenode -bootstrapStandby
在主节点ubuntu1执行:
hdfs zkfc -formatZK

通过以下命令可以看到,ubuntu1为standby,ubuntu2为active。
root@ubuntu1:/home/guoyachao# hdfs haadmin -getServiceState nn1
2024-07-28 17:13:09,214 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
standby
root@ubuntu1:/home/guoyachao# hdfs haadmin -getServiceState nn2
2024-07-28 17:13:11,292 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
active注意查看jps进程,我将ubuntu2的namenode进程kill掉,造成节点故障的现象。
root@ubuntu2:/usr/local/hadoop/etc/hadoop# jps
89712 NameNode
63362 ZooKeeperMain
89799 DataNode
90152 Jps
88796 NodeManager
89900 JournalNode
90015 DFSZKFailoverController
66399 QuorumPeerMain
root@ubuntu2:/usr/local/hadoop/etc/hadoop# jps|grep NameNode|awk '{print $1}'|xargs kill -9
root@ubuntu2:/usr/local/hadoop/etc/hadoop# jps
63362 ZooKeeperMain
90180 Jps
89799 DataNode
88796 NodeManager
89900 JournalNode
90015 DFSZKFailoverController
66399 QuorumPeerMain此时查看节点状态,无法连接到Ubuntu2的namenode
root@ubuntu2:/usr/local/hadoop/etc/hadoop# hdfs haadmin -getServiceState nn1
2024-07-28 17:16:20,249 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
standby
root@ubuntu2:/usr/local/hadoop/etc/hadoop# hdfs haadmin -getServiceState nn2
2024-07-28 17:16:25,256 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
2024-07-28 17:16:26,292 INFO ipc.Client: Retrying connect to server: ubuntu2/172.16.167.132:8020. Already tried 0 time(s); retry policy is RetryUpToMaximumCountWithFixedSleep(maxRetries=1, sleepTime=1000 MILLISECONDS)
Operation failed: Call From ubuntu2/172.16.167.132 to ubuntu2:8020 failed on connection exception: java.net.ConnectException: Connection refused; For more details see: http://wiki.apache.org/hadoop/ConnectionRefused再次启动ubuntu2的namenode,并查看高可用状态,此时ubuntu1已经完成了状态切换。回显表示ubuntu2已经切换为了standby。
root@ubuntu2:/usr/local/hadoop/etc/hadoop# hdfs --daemon start namenode
root@ubuntu2:/usr/local/hadoop/etc/hadoop# hdfs haadmin -getServiceState nn2
2024-07-28 17:19:14,086 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
standbyactive的切换:

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。