HDFS联邦机制与HA

embedded/2025/2/27 22:14:51/

1.Federation背景介绍

从上图中,我们可以很明显地看出现有的HDFS数据管理,数据存储2层分层的结构。也就是说,所有关于存储数据的信息和管理是放在NameNode这边,而真实数据的存储则是在各个DataNode下。而这些隶属于同一个NameNode,所管理的数据都是在同一个命名空间下的“NS”,以上结构是一个NameNode管理集群中所有元数据信息。

举个例子,一般1GB内存放1,000,000 block元数据。200个节点的集群中每个节点有24TB存储空间,block大小为128MB,能存储大概4千万个block(200\*24\*1024\*1024M/128 约为4千万或更多)。100万需要1G内存存储元数据,4千万大概需要40G内存存储元数据,假设节点数如果更多、存储数据更多的情况下,需要的内存也就越多。

通过以上例子可以看出,单NameNode的架构使得 HDFS 在集群扩展性和性能上都有潜在的问题,当集群大到一定程度后,NameNode进程使用的内存可能会达到上百G,NameNode 成为了性能的瓶颈。这时该怎么办?元数据空间依然还是在不断增大,一味调高NameNode的JVM大小绝对不是一个持久的办法,这时候就诞生了 HDFS Federation 的机制。

HDFS Federation是解决namenode内存瓶颈问题的水平横向扩展方案。Federation中文意思为联邦、联盟,HDFS Federation是NameNode的Federation,也就是会有多个NameNode。这些 namenode之间是联合的,他们之间相互独立且不需要互相协调,各自分工,管理自己的区域。分布式的datanode被用作通用的数据块存储存储设备。每个datanode要向集群中所有的namenode注册,且周期性地向所有 namenode 发送心跳和块报告,并执行来自所有 namenode的命令。

1) NameNode节点之间是相互独立的联邦的关系,即它们之间不需要协调服务。

2) DataNode向集群中所有的NameNode注册,发送心跳和block块列表报告,处理来自NameNode的指令。

3) 用户可以使用ViewFs创建个性化的命名空间视图,ViewFs类似于在Unix/Linux系统中的客户端挂载表。

2.Federation搭建

Hadoop Federation机制可以看成将多个HDFS集群进行了统一管理,即:多个HDFS集群中,每个集群都有一个或者多个NameNode,每个NameNode只能属于一个集群且都有自己的NameSpace,集群间的NameSpace相互独立。通过Hadoop Federation机制可以将指定数据存储在不同的集群由不同的NS管理,且可以通过ViewFS进行统一访问。

2.1配置core-site.xml

进入 $HADOOP\_HOME/etc/hadoop路径下,修改core-site.xml文件,指定HDFS集群数据访问地址及集群数据存放路径。

#vim /software/hadoop-3.3.6/etc/hadoop/core-site.xml
<configuration><!-- 指定HDFS文件系统访问URI --><property><name>fs.defaultFS</name><value>viewfs://ClusterX</value></property><!-- 将 /data 目录挂载到 viewfs 中,并通过NN1集群进行管理--><property><name>fs.viewfs.mounttable.ClusterX.link./data</name><value>hdfs://node1:8020/data</value></property><!-- 将 /project 目录挂载到 viewfs 中,并通过NN1集群进行管理--><property><name>fs.viewfs.mounttable.ClusterX.link./project</name><value>hdfs://node1:8020/project</value></property><!-- 将 /user 目录挂载到 viewfs 中,并通过NN2集群进行管理--><property><name>fs.viewfs.mounttable.ClusterX.link./user</name><value>hdfs://node2:8020/user</value></property><!-- 将 /tmp 目录挂载到 viewfs 中,并通过NN2集群进行管理--><property><name>fs.viewfs.mounttable.ClusterX.link./tmp</name><value>hdfs://node2:8020/tmp</value></property><!-- 对于没有配置的路径存放在 /home目录并挂载到 viewfs 中,并通过NN2集群进行管理--><property><name>fs.viewfs.mounttable.ClusterX.linkFallback</name><value>hdfs://node2:8020/home</value></property><!-- 指定 Hadoop 数据存放的路径 --><property><name>hadoop.tmp.dir</name><value>/opt/data/hadoop/federation</value></property>
</configuration>

以上配置就是配置将不同数据目录交由不同的HDFS集群进行管理以减少元数据所占NN空间,并将各个目录挂载到viewfs中方便统一访问。

2.2配置hdfs-site.xml

进入 $HADOOP\_HOME/etc/hadoop路径下,修改hdfs-site.xml文件,指定NameNode和SecondaryNameNode节点和端口。在Hadoop Federation联邦中需要指定多个NN及相应SNN地址。

#vim /software/hadoop-3.3.6/etc/hadoop/hdfs-site.xml
<configuration><!-- block副本数 --><property><name>dfs.replication</name><value>3</value></property><!-- 指定 两个NS --><property><name>dfs.nameservices</name><value>ns1,ns2</value></property><!-- NS1 NameNode 地址和端口号--><property><name>dfs.namenode.rpc-address.ns1</name><value>node1:8020</value></property><!-- NS1 NameNode WebUI访问地址--><property><name>dfs.namenode.http-address.ns1</name><value>node1:9870</value></property><!-- NS1 SecondaryNameNode WebUI访问地址--><property><name>dfs.namenode.secondary.http-address.ns1</name><value>node3:9868</value></property><!-- NS2 NameNode 地址和端口号--><property><name>dfs.namenode.rpc-address.ns2</name><value>node2:8020</value></property><!-- NS2 NameNode WebUI访问地址--><property><name>dfs.namenode.http-address.ns2</name><value>node2:9870</value></property><!-- NS2 SecondaryNameNode WebUI访问地址--><property><name>dfs.namenode.secondary.http-address.ns2</name><value>node4:9868</value></property>
</configuration>

2.3配置workers指定DataNode节点

进入 $HADOOP\_HOME/etc/hadoop路径下,修改workers配置文件,加入以下内容:

#vim /software/hadoop-3.3.6/etc/hadoop/workers 
node3
node4
node5

3.Federation问题

HDFS Federation 并没有完全解决单点故障问题。虽然 namenode/namespace 存在多个,但是从单个namenode/namespace看,仍然存在单点故障:如果某个 namenode 挂掉了,其管理的相应的文件便不可以访问。当然Federation中每个namenode仍然像之前HDFS上实现一样,配有一个secondary namenode,以便主namenode 挂掉重启后,用于还原元数据信息,需要手动将挂掉的namenode重新启动。

所以一般集群规模真的很大的时候,会采用HA+Federation 的部署方案。也就是每个联合的namenodes都是HA(High Availablity - 高可用)的。

3.NameNode HA 背景

在Hadoop1中NameNode存在一个单点故障问题,如果NameNode所在的机器发生故障,整个集群就将不可用(Hadoop1中虽然有个SecorndaryNameNode,但是它并不是NameNode的备份,它只是NameNode的一个助理,协助NameNode工作,SecorndaryNameNode会对fsimage和edits文件进行合并,并推送给NameNode,防止因edits文件过大,导致NameNode重启变慢),这是Hadoop1的不可靠实现。

在Hadoop2中这个问题得以解决,Hadoop2中的高可靠性是指同时启动NameNode,其中一个处于active工作状态,另外一个处于随时待命standby状态。这样,当一个NameNode所在的服务器宕机时,可以在数据不丢失的情况下,手工或者自动切换到另一个NameNode提供服务。这些NameNode之间通过共享数据,保证数据的状态一致。多个NameNode之间共享数据,可以通过Network File System或者Quorum Journal Node。前者是通过Linux共享的文件系统,属于操作系统的配置,后者是Hadoop自身的东西,属于软件的配置。

注意:

  1. NameNode HA 与HDFS Federation都有多个NameNode,当NameNode作用不同,在HDFS Federation联邦机制中多个NameNode解决了内存受限问题,而在NameNode HA中多个NameNode解决了NameNode单点故障问题。
  2. 在Hadoop2.x版本中,NameNode HA 支持2个节点,在Hadoop3.x版本中,NameNode高可用可以支持多台节点。

3.1HA实现原理

NameNode中存储了HDFS中所有元数据信息(包括用户操作元数据和block元数据),在NameNode HA中,当Active NameNode(ANN)挂掉后,StandbyNameNode(SNN)要及时顶上,这就需要将所有的元数据同步到SNN节点。如向HDFS中写入一个文件时,如果元数据同步写入ANN和SNN,那么当SNN挂掉势必会影响ANN,所以元数据需要异步写入ANN和SNN中。如果某时刻ANN刚好挂掉,但却没有及时将元数据异步写入到SNN也会引起数据丢失,所以向SNN同步元数据需要引入第三方存储,在HA方案中叫做“共享存储”。每次向HDFS中写入文件时,需要将edits log同步写入共享存储,这个步骤成功才能认定写文件成功,然后SNN定期从共享存储中同步editslog,以便拥有完整元数据便于ANN挂掉后进行主备切换。

HDFS将Cloudera公司实现的QJM(Quorum Journal Manager)方案作为默认的共享存储实现。在QJM方案中注意如下几点:

  • 基于QJM的共享存储系统主要用于保存Editslog,并不保存FSImage文件,FSImage文件还是在NameNode本地磁盘中。
  • QJM共享存储采用多个称为JournalNode的节点组成的JournalNode集群来存储EditsLog。每个JournalNode保存同样的EditsLog副本。
  • 每次NameNode写EditsLog时,除了向本地磁盘写入EditsLog外,也会并行的向JournalNode集群中每个JournalNode发送写请求,只要大多数的JournalNode节点返回成功就认为向JournalNode集群中写入EditsLog成功。
  • 如果有2N+1台JournalNode,那么根据大多数的原则,最多可以容忍有N台JournalNode节点挂掉。

NameNode HA 实现原理图如下:

当客户端操作HDFS集群时,Active NameNode 首先把 EditLog 提交到 JournalNode 集群,然后 Standby NameNode 再从 JournalNode 集群定时同步 EditLog。当处 于 Standby 状态的 NameNode 转换为 Active 状态的时候,有可能上一个 Active NameNode 发生了异常退出,那么 JournalNode 集群中各个 JournalNode 上的 EditLog 就可能会处于不一致的状态,所以首先要做的事情就是让 JournalNode 集群中各个节点上的 EditLog 恢复为一致,然后Standby NameNode会从JournalNode集群中同步EditsLog,然后对外提供服务。

注意:在NameNode HA中不再需要SecondaryNameNode角色,该角色被StandbyNameNode替代。

通过Journal Node实现NameNode HA时,可以手动将Standby NameNode切换成Active NameNode,也可以通过自动方式实现NameNode切换。

上图需要手动进行切换StandbyNamenode为Active NameNode,对于高可用场景时效性较低,那么可以通过zookeeper进行协调自动实现NameNode HA,实现代码通过Zookeeper来检测Activate NameNode节点是否挂掉,如果挂掉立即将Standby NameNode切换成Active NameNode,这种方式也是生产环境中常用情况。其原理如下:

上图中引入了zookeeper作为分布式协调器来完成NameNode自动选主,以上各个角色解释如下:

  • AcitveNameNode:主 NameNode,只有主NameNode才能对外提供读写服务。
  • Standby NameNode:备用NameNode,定时同步Journal集群中的editslog元数据。
  • ZKFailoverController:ZKFailoverController 作为独立的进程运行,对 NameNode 的主备切换进行总体控制。ZKFailoverController 能及时检测到 NameNode 的健康状况,在主 NameNode 故障时借助 Zookeeper 实现自动的主备选举和切换。
  • Zookeeper集群:分布式协调器,NameNode选主使用。
  • Journal集群:Journal集群作为共享存储系统保存HDFS运行过程中的元数据,ANN和SNN通过Journal集群实现元数据同步。
  • DataNode节点:除了通过共享存储系统共享 HDFS 的元数据信息之外,主 NameNode 和备 NameNode 还需要共享 HDFS 的数据块和 DataNode 之间的映射关系。DataNode 会同时向主 NameNode 和备 NameNode 上报数据块的位置信息。

3.2NameNode主备切换流程

 NameNode 主备切换主要由 ZKFailoverController、HealthMonitor 和 ActiveStandbyElector 这 3 个组件来协同实现:

  • ZKFailoverController 作为 NameNode 机器上一个独立的进程启动 (在 hdfs 集群中进程名为 zkfc),启动的时候会创建 HealthMonitor 和 ActiveStandbyElector 这两个主要的内部组件,ZKFailoverController 在创建 HealthMonitor 和 ActiveStandbyElector 的同时,也会向 HealthMonitor 和 ActiveStandbyElector 注册相应的回调方法。
  • HealthMonitor 主要负责检测 NameNode 的健康状态,如果检测到 NameNode 的状态发生变化,会回调 ZKFailoverController 的相应方法进行自动的主备选举。
  • ActiveStandbyElector 主要负责完成自动的主备选举,内部封装了 Zookeeper 的处理逻辑,一旦 Zookeeper 主备选举完成,会回调 ZKFailoverController 的相应方法来进行 NameNode 的主备状态切换。

NameNode主备切换流程如下:

  • HealthMonitor 初始化完成之后会启动内部的线程来定时调用对应 NameNode 的 HAServiceProtocol RPC 接口的方法,对 NameNode 的健康状态进行检测。
  • HealthMonitor 如果检测到 NameNode 的健康状态发生变化,会回调 ZKFailoverController 注册的相应方法进行处理。
  • 如果 ZKFailoverController 判断需要进行主备切换,会首先使用 ActiveStandbyElector 来进行自动的主备选举。
  • ActiveStandbyElector 与 Zookeeper 进行交互完成自动的主备选举。
  • ActiveStandbyElector 在主备选举完成后,会回调 ZKFailoverController 的相应方法来通知当前的 NameNode 成为主 NameNode 或备 NameNode。
  • ZKFailoverController 调用对应 NameNode 的 HAServiceProtocol RPC 接口的方法将 NameNode 转换为 Active 状态或 Standby 状态。

3.3脑裂问题

当网络抖动时,ZKFC检测不到Active NameNode,此时认为NameNode挂掉了,因此将Standby NameNode切换成Active NameNode,而旧的Active NameNode由于网络抖动,接收不到zkfc的切换命令,此时两个NameNode都是Active状态,这就是脑裂问题。那么HDFS HA中如何防止脑裂问题的呢?

HDFS集群初始启动时,Namenode的主备选举是通过 ActiveStandbyElector 来完成的,ActiveStandbyElector 主要是利用了 Zookeeper 的写一致性和临时节点机制,具体的主备选举实现如下:

1. 创建锁节点

如果 HealthMonitor 检测到对应的 NameNode 的状态正常,那么表示这个 NameNode 有资格参加 Zookeeper 的主备选举。如果目前还没有进行过主备选举的话,那么相应的 ActiveStandbyElector 就会发起一次主备选举,尝试在 Zookeeper 上创建一个路径为/hadoop-ha/${dfs.nameservices}/ActiveStandbyElectorLock 的临时节点 (${dfs.nameservices} 为 Hadoop 的配置参数 dfs.nameservices 的值,下同),Zookeeper 的写一致性会保证最终只会有一个 ActiveStandbyElector 创建成功,那么创建成功的 ActiveStandbyElector 对应的 NameNode 就会成为主 NameNode,ActiveStandbyElector 会回调 ZKFailoverController 的方法进一步将对应的 NameNode 切换为 Active 状态。而创建失败的 ActiveStandbyElector 对应的NameNode成为备用NameNode,ActiveStandbyElector 会回调 ZKFailoverController 的方法进一步将对应的 NameNode 切换为 Standby 状态。

2. 注册 Watcher 监听

不管创建/hadoop-ha/${dfs.nameservices}/ActiveStandbyElectorLock 节点是否成功,ActiveStandbyElector 随后都会向 Zookeeper 注册一个 Watcher 来监听这个节点的状态变化事件,ActiveStandbyElector 主要关注这个节点的 NodeDeleted 事件。

3. 自动触发主备选举

如果 Active NameNode 对应的 HealthMonitor 检测到 NameNode 的状态异常时, ZKFailoverController 会主动删除当前在 Zookeeper 上建立的临时节点/hadoop-ha/${dfs.nameservices}/ActiveStandbyElectorLock,这样处于 Standby 状态的 NameNode 的 ActiveStandbyElector 注册的监听器就会收到这个节点的 NodeDeleted 事件。收到这个事件之后,会马上再次进入到创建/hadoop-ha/${dfs.nameservices}/ActiveStandbyElectorLock 节点的流程,如果创建成功,这个本来处于 Standby 状态的 NameNode 就选举为主 NameNode 并随后开始切换为 Active 状态。

当然,如果是 Active 状态的 NameNode 所在的机器整个宕掉的话,那么根据 Zookeeper 的临时节点特性,/hadoop-ha/${dfs.nameservices}/ActiveStandbyElectorLock 节点会自动被删除,从而也会自动进行一次主备切换。

以上过程中,Standby NameNode成功创建 Zookeeper 节点/hadoop-ha/${dfs.nameservices}/ActiveStandbyElectorLock 成为Active NameNode之后,还会创建另外一个路径为/hadoop-ha/${dfs.nameservices}/ActiveBreadCrumb 的持久节点,这个节点里面保存了这个 Active NameNode 的地址信息。Active NameNode 的ActiveStandbyElector 在正常的状态下关闭 Zookeeper Session 的时候 (注意由于/hadoop-ha/${dfs.nameservices}/ActiveStandbyElectorLock 是临时节点,也会随之删除)会一起删除节点/hadoop-ha/${dfs.nameservices}/ActiveBreadCrumb。但是如果 ActiveStandbyElector 在异常的状态下 Zookeeper Session 关闭 (比如 Zookeeper 假死),那么由于/hadoop-ha/${dfs.nameservices}/ActiveBreadCrumb 是持久节点,会一直保留下来。后面当另一个 NameNode 选主成功之后,会注意到上一个 Active NameNode 遗留下来的这个节点,从而会回调 ZKFailoverController 的方法对旧的 Active NameNode 进行隔离(fencing)操作以避免出现脑裂问题,fencing操作会通过SSH将旧的Active NameNode进程尝试转换成Standby状态,如果不能转换成Standby状态就直接将对应进程杀死。

3.4zookeeper集群搭建

这里搭建zookeeper版本为3.6.3,搭建zookeeper对应的角色分布如下:

3.4.1HDFS节点规划

搭建HDFS NameNode HA不再需要原来的SecondaryNameNode角色,对应的角色有NameNode、DataNode、ZKFC、JournalNode在各个节点分布如下:

配置zoo.cfg中内容如下:

tickTime=2000
initLimit=10
syncLimit=5
dataDir=/opt/data/zookeeper
clientPort=2181
server.1=node3:2888:3888
server.2=node4:2888:3888
server.3=node5:2888:3888

各个节点上创建数据目录,并配置zookeeper环境变量

在node3,node4,node5各个节点上创建zoo.cfg中指定的数据目录“/opt/data/zookeeper”。

mkdir -p /opt/data/zookeeper

在node4,node5节点配置zookeeper环境变量

#进入vim /etc/profile,在最后加入:
export ZOOKEEPER_HOME=/software/apache-zookeeper-3.6.3-bin/
export PATH=$PATH:$ZOOKEEPER_HOME/bin#使配置生效
source /etc/profile

5) 各个节点创建节点ID

在node3,node4,node5各个节点路径“/opt/data/zookeeper”中添加myid文件分别写入1,2,3:

#在node3的/opt/data/zookeeper中创建myid文件写入1
#在node4的/opt/data/zookeeper中创建myid文件写入2
#在node5的/opt/data/zookeeper中创建myid文件写入3

6) 各个节点启动zookeeper,并检查进程状态

#各个节点启动zookeeper命令
zkServer.sh start#检查各个节点zookeeper进程状态
zkServer.sh status

配置core-site.xml

进入 $HADOOP_HOME/etc/hadoop路径下,修改core-site.xml文件,指定HDFS集群数据访问地址及集群数据存放路径。

#vim /software/hadoop-3.3.6/etc/hadoop/core-site.xml
<configuration><property><!-- 为Hadoop 客户端配置默认的高可用路径  --><name>fs.defaultFS</name><value>hdfs://mycluster</value></property><property><!-- Hadoop 数据存放的路径,namenode,datanode 数据存放路径都依赖本路径,不要使用 file:/ 开头,使用绝对路径即可namenode 默认存放路径 :file://${hadoop.tmp.dir}/dfs/namedatanode 默认存放路径 :file://${hadoop.tmp.dir}/dfs/data--><name>hadoop.tmp.dir</name><value>/opt/data/hadoop/</value></property><property><!-- 指定zookeeper所在的节点 --><name>ha.zookeeper.quorum</name><value>node3:2181,node4:2181,node5:2181</value></property></configuration>

配置hdfs-site.xml

进入 $HADOOP_HOME/etc/hadoop路径下,修改hdfs-site.xml文件,指定NameNode和JournalNode节点和端口。这里配置NameNode节点为3个。

#vim /software/hadoop-3.3.6/etc/hadoop/hdfs-site.xml
<configuration><!-- 指定副本的数量 --><property><name>dfs.replication</name><value>3</value></property><!-- 解析参数dfs.nameservices值hdfs://mycluster的地址 --><property><name>dfs.nameservices</name><value>mycluster</value></property><!-- mycluster由以下三个namenode支撑 --><property><name>dfs.ha.namenodes.mycluster</name><value>nn1,nn2,nn3</value></property><property><!-- dfs.namenode.rpc-address.[nameservice ID].[name node ID] namenode 所在服务器名称和RPC监听端口号  --><name>dfs.namenode.rpc-address.mycluster.nn1</name><value>node1:8020</value></property><property><!-- dfs.namenode.rpc-address.[nameservice ID].[name node ID] namenode 所在服务器名称和RPC监听端口号  --><name>dfs.namenode.rpc-address.mycluster.nn2</name><value>node2:8020</value></property><property><!-- dfs.namenode.rpc-address.[nameservice ID].[name node ID] namenode 所在服务器名称和RPC监听端口号  --><name>dfs.namenode.rpc-address.mycluster.nn3</name><value>node3:8020</value></property><property><!-- dfs.namenode.http-address.[nameservice ID].[name node ID] namenode 监听的HTTP协议端口 --><name>dfs.namenode.http-address.mycluster.nn1</name><value>node1:9870</value></property><property><!-- dfs.namenode.http-address.[nameservice ID].[name node ID] namenode 监听的HTTP协议端口 --><name>dfs.namenode.http-address.mycluster.nn2</name><value>node2:9870</value></property><property><!-- dfs.namenode.http-address.[nameservice ID].[name node ID] namenode 监听的HTTP协议端口 --><name>dfs.namenode.http-address.mycluster.nn3</name><value>node3:9870</value></property><!-- namenode高可用代理类 --><property><name>dfs.client.failover.proxy.provider.mycluster</name><value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value></property><!-- 指定三台journal node服务器的地址 --><property><name>dfs.namenode.shared.edits.dir</name><value>qjournal://node3:8485;node4:8485;node5:8485/mycluster</value></property><!-- journalnode 存储数据的地方 --><property><name>dfs.journalnode.edits.dir</name><value>/opt/data/journal/node/local/data</value></property><!--启动NN故障自动切换 --><property><name>dfs.ha.automatic-failover.enabled</name><value>true</value></property><!-- 当active nn出现故障时,ssh到对应的服务器,将namenode进程kill掉  --><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>
</configuration>

配置workers指定DataNode节点

进入 $HADOOP_HOME/etc/hadoop路径下,修改workers配置文件,加入以下内容:

#vim /software/hadoop-3.3.6/etc/hadoop/workers 
node3
node4
node5

配置start-dfs.sh&stop-dfs.sh

进入 $HADOOP_HOME/sbin路径下,在start-dfs.sh和stop-dfs.sh文件顶部添加操作HDFS的用户为root,防止启动错误。

#分别在start-dfs.sh 和stop-dfs.sh文件顶部添加如下内容
HDFS_NAMENODE_USER=root
HDFS_DATANODE_USER=root
HDFS_JOURNALNODE_USER=root
HDFS_ZKFC_USER=root

格式化并启动HDFS集群

HDFS HA 集群搭建完成后,首次使用需要进行格式化。步骤如下:

#在node3,node4,node5节点上启动zookeeper
zkServer.sh start#在node1上格式化zookeeper
[root@node1 ~]# hdfs zkfc -formatZK#在每台journalnode中启动所有的journalnode,这里就是node3,node4,node5节点上启动
hdfs --daemon start journalnode#在node1中格式化namenode,只有第一次搭建做,以后不用做
[root@node1 ~]# hdfs namenode -format#在node1中启动namenode,以便同步其他namenode
[root@node1 ~]# hdfs --daemon start namenode#高可用模式配置namenode,使用下列命令来同步namenode(在需要同步的namenode中执行,这里就是在node2、node3上执行):
[root@node2 software]# hdfs namenode -bootstrapStandby
[root@node3 software]# hdfs namenode -bootstrapStandby

以上格式化集群完成后就可以在NameNode节点上执行如下命令启动集群:

#在node1节点上启动集群
[root@node1 ~]# start-dfs.sh

 

 

 

以上三个NameNode只有一个是Active状态,其余两个都是Standby状态,三个NameNode节点不一定哪个为active节点,这取决于争夺zookeeper锁,哪个节点先启动争夺到锁,那么就是active节点。

停止集群时只需要在NameNode节点上执行stop-dfs.sh命令即可。后续再次启动HDFS集群只需要在NameNode节点执行start-dfs.sh命令,不需要再次格式化集群。

测试NameNode HA

首先查看Zookeeper中的数据目录内容,可以看到当前Active NameNode节点为Node3。

[root@node3 ~]# zkCli.sh 
[zk: localhost:2181(CONNECTED) 3] get /hadoop-ha/mycluster/ActiveBreadCrumb
myclusternn3node3 �>(�>

当在node3节点kill掉对应的NameNode进程时,会在node1和node2中重新选取Active NameNode,如下:

#在对应Active节点kill NameNode进程
[root@node3 ~]# kill -9 38111#再次查看zookeeper中节点信息
[zk: localhost:2181(CONNECTED) 5] get /hadoop-ha/mycluster/ActiveBreadCrumb myclusternn2node2 �>(�>

此时,可以执行命令重新启动node3上的NameNode,但启动后状态为Standby。

#重新启动挂掉的NameNode节点
[root@node3 ~]# hdfs --daemon start namenode

注意:如果以上测试NameNode节点不能正常切换,那么就查看各个NameNode节点$HADOOP_HOME/logs目录下对应的进行日志错误,根据具体错误来解决问题。


http://www.ppmy.cn/embedded/167643.html

相关文章

java基础面试-Java 内存模型(JMM)相关介绍

Java 内存模型&#xff08;JMM&#xff09;详解&#xff1a;从入门到进阶 前言 在现代计算机体系中&#xff0c;多线程编程是一个绕不开的话题。而 Java 作为一门面向对象且支持并发的编程语言&#xff0c;在处理多线程问题时表现得尤为突出。然而&#xff0c;Java 的内存模型…

48.日常算法

1.面试题 03.06. 动物收容所 题目来源 动物收容所。有家动物收容所只收容狗与猫&#xff0c;且严格遵守“先进先出”的原则。在收养该收容所的动物时&#xff0c;收养人只能收养所有动物中“最老”&#xff08;由其进入收容所的时间长短而定&#xff09;的动物&#xff0c;或…

如何在 WPS 中集成 DeepSeek

如何在 WPS 中集成 DeepSeek&#xff1a;从零基础到高阶开发的完整指南 DeepSeek 作为国内领先的 AI 办公助手&#xff0c;与 WPS 的深度整合可显著提升文档处理效率。本文提供 ​4 种集成方案&#xff0c;覆盖从「小白用户」到「企业开发者」的全场景需求&#xff0c;并包含 …

Apache Pinpoint工具介绍

Apache Pinpoint&#xff1a;分布式系统性能分析与链路追踪 一、Pinpoint 简介 Apache Pinpoint 是一个开源的 分布式追踪系统&#xff0c;专为微服务架构设计&#xff0c;支持 HTTP、RPC、MQTT 等协议的调用链追踪。其核心功能包括&#xff1a; 链路可视化&#xff1a;展示…

【代码解读】阿里最新开源视频生成模型 Wan 2.1 实现解析

昨晚阿里巴巴开源了最新视频生成模型的代码和权重&#xff0c;从给出的 demo 效果来看还是非常惊艳的。这个模型目前也是在 VBench 榜单上排到了第一名&#xff0c;超越了 Sora 以及 HunyuanVideo 等一系列知名方法。 从官方给出的方法架构图来说&#xff0c;Wan 2.1 并没有使…

LangChain构建行业知识库实践:从架构设计到生产部署全指南

文章目录 引言:行业知识库的进化挑战一、系统架构设计1.1 核心组件拓扑1.2 模块化设计原则二、关键技术实现2.1 文档预处理流水线2.2 混合检索增强三、领域适配优化3.1 医学知识图谱融合3.2 检索结果重排序算法四、生产环境部署4.1 性能优化方案4.2 安全防护体系五、评估与调优…

马士兵java面试八股文及答案

马士兵java面试八股文及答案 Java面向对象有哪些特征&#xff0c;如何应用HashMap原理是什么&#xff0c;在jdk1.7和1.8中有什么区别ArrayList和LinkedList有什么区别高并发中的集合有哪些问题jdk1.8的新特性有哪些 一、接口的默认方法二、Lambda 表达式三、函数式接口四、方法…

根据经纬度获取时区并返回当前时间

我使用的是 NodaTime 可以按照程序包或者引用dll文件 引用命名空间 using NodaTime; using NodaTime.TimeZones; 代码 var systemClock SystemClock.Instance; var timeZoneDb TzdbDateTimeZoneSource.Default; var timeZone timeZoneDb.ForId(timeZoneId); var n…