Hadoop 1.x 与 2.x 中 fsimage 和 edits 合并实现

本文深入探讨了Hadoop中fsimage与edits合并的背景需求及实现方式,包括从Hadoop 1.x到2.x版本的合并机制变化。详细解释了SecondaryNamenode的角色与配置,以及在Hadoop 2.x中通过JournalNode实现的合并过程。此外,还总结了fsimage和edits合并的处理逻辑与关键配置参数。

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

本文部分转自 Hadoop 1.x中fsimage和edits合并实现
本文部分转自 Hadoop 2.x中fsimage和edits合并实现
本文部分转自 hadoop 2.2.0 关于 fsimage & edit log 的相关配置


一. Hadoop fsimage 和 edits 合并背景需求

《Hadoop NameNode元数据相关文件目录解析》文章中谈到了 fsimage 和 edits 的概念、作用等相关知识,正如前面说到,在 NameNode 运行期间,HDFS 的所有更新操作都是直接写到 edits 中,久而久之 edits 文件将会变得很大;虽然这对 NameNode 运行时候是没有什么影响的,但是我们知道当 NameNode 重启的时候,NameNode 先将 fsimage 里面的所有内容映像到内存中,然后再一条一条地执行 edits 中的记录,当 edits 文件非常大的时候,会导致 NameNode 启动操作非常地慢,而在这段时间内 HDFS 系统处于安全模式,这显然不是用户要求的。能不能在 NameNode 运行的时候使得 edits 文件变小一些呢?



二. Hadoop 1.x 中 fsimage 和 edits 合并实现

其实是可以的,接下来主要是针对 Hadoop 1.x 版本,说明其是怎么将 edits 和 fsimage 文件合并的。


2.1 SecondaryNamenode 简介

用过 Hadoop 的用户应该都知道在 Hadoop 里面有个 SecondaryNamenode 进程,从名字看来大家很容易将它当作 NameNode 的热备进程。其实真实的情况不是这样的。

SecondaryNamenode 是 HDFS 架构中的一个组成部分,它是用来保存 namenode 中对 HDFS metadata 的信息的备份,并减少 namenode 重启的时间而设定的!


2.2 SecondaryNamenode 工作情况

一般都是将 SecondaryNamenode 单独运行在一台机器上,那么 SecondaryNamenode 是如何减少 namenode 重启的时间的呢?来看看 SecondaryNamenode 的工作情况:

  • SecondaryNamenode 会定期的和 NameNode 通信,请求其停止使用 edits 文件,暂时将新的写操作写到一个新的文件 edit.new 上来,这个操作是瞬间完成,上层写日志的函数完全感觉不到差别

  • SecondaryNamenode 通过 HTTP GET 方式从 NameNode 上获取到 fsimage 和 edits 文件,并下载到本地的相应目录下

  • SecondaryNamenode 将下载下来的 fsimage 载入到内存,然后一条一条地执行 edits 文件中的各项更新操作,使得内存中的 fsimage 保存最新;这个过程就是 edits 和 fsimage 文件合并

  • SecondaryNamenode 执行完上述操作之后,会通过 post 方式将新的 fsimage 文件发送到 NameNode 节点上

  • NameNode 将从 SecondaryNamenode 接收到的新的 fsimage 替换旧的 fsimage 文件,同时将 edit.new 替换 edits 文件,通过这个过程 edits 就变小了!

整个过程的执行可以通过下面的图说明:

这里写图片描述


2.3 SecondaryNamenode 具体配置

在第一步时,我们谈到 SecondaryNamenode 会定期的和 NameNode 通信,这个是需要配置的,可以通过 core-site.xml 进行配置,下面是默认关于检查时间的配置

<property>
  <name>fs.checkpoint.period</name>
  <value>3600</value>
  <description>The number of seconds between two periodic checkpoints.
  </description>
</property>

其实如果当 fs.checkpoint.period 配置的时间还没有到期,我们也可以通过判断当前的 edits 大小来触发一次合并的操作,可以通过下面配置

<property>
  <name>fs.checkpoint.size</name>
  <value>67108864</value>
  <description>The size of the current edit log (in bytes) that triggers
       a periodic checkpoint even if the fs.checkpoint.period hasn't expired.
  </description>
</property>

edits 文件大小超过以上配置,即使 fs.checkpoint.period 还没到,也会进行一次合并。顺便说说 SecondaryNamenode 下载下来的 fsimage 和 edits 暂时存放的路径可以通过下面的属性进行配置:

<property>
  <name>fs.checkpoint.dir</name>
  <value>${hadoop.tmp.dir}/dfs/namesecondary</value>
  <description>Determines where on the local filesystem the DFS secondary
      name node should store the temporary images to merge.
      If this is a comma-delimited list of directories then the image is
      replicated in all of the directories for redundancy.
  </description>
</property>

<property>
  <name>fs.checkpoint.edits.dir</name>
  <value>${fs.checkpoint.dir}</value>
  <description>Determines where on the local filesystem the DFS secondary
      name node should store the temporary edits to merge.
      If this is a comma-delimited list of directoires then teh edits is
      replicated in all of the directoires for redundancy.
      Default value is same as fs.checkpoint.dir
  </description>
</property>

从上面的描述我们可以看出,SecondaryNamenode 根本就不是 Namenode 的一个热备,其只是将 fsimage 和 edits 合并。其拥有的 fsimage 不是最新的,因为在它从 NameNode 下载 fsimage 和 edits 文件时候,新的更新操作已经写到 edit.new 文件中去了。而这些更新在 SecondaryNamenode 是没有同步到的!当然,如果 NameNode 中的 fsimage 真的出问题了,还是可以用 SecondaryNamenode 中的 fsimage 替换一下 NameNode 上的 fsimage,虽然已经不是最新的 fsimage,但是我们可以将损失减小到最少!



三. Hadoop 2.x 版本 edits 和 fsimage 文件合并

我们知道,在 Hadoop 2.x 中解决了 NameNode 的单点故障问题;同时 SecondaryName 已经不用了,而之前的 Hadoop 1.x 中是通过 SecondaryName 来合并 fsimage 和 edits 以此来减小 edits 文件的大小,从而减少 NameNode 重启的时间。而在 Hadoop 2.x 中已经不用 SecondaryName,那它是怎么来实现 fsimage 和 edits 合并的呢?


3.1 edits 和 fsimage 文件合并方式

在 Hadoop 2.x 通过配置 JournalNode 来实现 Hadoop 的高可用性,这样主备 NameNode上 的 fsimage 和 edits 都是最新的,任何时候只要有一台 NameNode 挂了,也可以使得集群中的 fsimage 是最新状态!在 Hadoop 2.x 中提供了 HA 机制(解决 NameNode 单点故障),可以通过配置奇数个 JournalNode 来实现 HA,如何配置今天就不谈了!HA 机制通过在同一个集群中运行两个 NN(active NN & standby NN)来解决 NameNode 的单点故障,在任何时间,只有一台机器处于 Active 状态;另一台机器是处于 Standby 状态。Active NN 负责集群中所有客户端的操作;而 Standby NN 主要用于备用,它主要维持足够的状态,如果必要,可以提供快速的故障恢复。

为了让 Standby NN 的状态和 Active NN 保持同步,即元数据保持一致,它们都将会和 JournalNodes 守护进程通信。当 Active NN 执行任何有关命名空间的修改,它需要持久化到一半以上的 JournalNodes上(通过 edits log 持久化存储),而 Standby NN 负责观察 edits log 的变化,它能够读取从 JNs 中读取 edits 信息,并更新其内部的命名空间。一旦 Active NN 出现故障,Standby NN 将会保证从 JNs 中读出了全部的 Edits,然后切换成 Active 状态。Standby NN 读取全部的 edits 可确保发生故障转移之前,是和 Active NN 拥有完全同步的命名空间状态。


3.2 edits 和 fsimage 文件合并实现机制

那么这种机制是如何实现 fsimage 和 edits 的合并?在 standby NameNode 节点上会一直运行一个叫做 CheckpointerThread 的线程,这个线程调用 StandbyCheckpointer 类的 doWork() 函数,而 doWork 函数会每隔 Math.min(checkpointCheckPeriod, checkpointPeriod) 秒来坐一次合并操作,相关代码如下:

try {
          Thread.sleep(1000 * checkpointConf.getCheckPeriod());
        } catch (InterruptedException ie) {
}

public long getCheckPeriod() {
    return Math.min(checkpointCheckPeriod, checkpointPeriod);
}

checkpointCheckPeriod = conf.getLong(
        DFS_NAMENODE_CHECKPOINT_CHECK_PERIOD_KEY,
        DFS_NAMENODE_CHECKPOINT_CHECK_PERIOD_DEFAULT);

checkpointPeriod = conf.getLong(DFS_NAMENODE_CHECKPOINT_PERIOD_KEY, 
                                DFS_NAMENODE_CHECKPOINT_PERIOD_DEFAULT);

上面的 checkpointCheckPeriod 和 checkpointPeriod 变量是通过获取 hdfs-site.xml 以下两个属性的值得到:

<property>
  <name>dfs.namenode.checkpoint.period</name>
  <value>3600</value>
  <description>The number of seconds between two periodic checkpoints.
  </description>
</property>

<property>
  <name>dfs.namenode.checkpoint.check.period</name>
  <value>60</value>
  <description>The SecondaryNameNode and CheckpointNode will poll the NameNode
  every 'dfs.namenode.checkpoint.check.period' seconds to query the number
  of uncheckpointed transactions.
  </description>
</property>

当达到下面两个条件的情况下,将会执行一次 checkpoint:

boolean needCheckpoint = false;
if (uncheckpointed >= checkpointConf.getTxnCount()) {
     LOG.info("Triggering checkpoint because there have been " + 
                uncheckpointed + " txns since the last checkpoint, which " +
                "exceeds the configured threshold " +
                checkpointConf.getTxnCount());
     needCheckpoint = true;
} else if (secsSinceLast >= checkpointConf.getPeriod()) {
     LOG.info("Triggering checkpoint because it has been " +
            secsSinceLast + " seconds since the last checkpoint, which " +
             "exceeds the configured interval " + checkpointConf.getPeriod());
     needCheckpoint = true;
}

当上述 needCheckpoint 被设置成 true 的时候,StandbyCheckpointer 类的 doWork() 函数将会调用 doCheckpoint() 函数正式处理 checkpoint。当 fsimage 和 edits 的合并完成之后,它将会把合并后的 fsimage 上传到 Active NameNode 节点上,Active NameNode 节点下载完合并后的 fsimage,再将旧的 fsimage 删掉(Active NameNode上的)同时清除旧的 edits 文件。步骤可以归类如下:

步骤一:配置好 HA 后,客户端所有的更新操作将会写到 JournalNodes 节点的共享目录中,可以通过下面配置

<property>
  <name>dfs.namenode.shared.edits.dir</name>
  <value>qjournal://XXXX/mycluster</value>
</property>

<property>
  <name>dfs.journalnode.edits.dir</name>
  <value>/export1/hadoop2x/dfs/journal</value>
</property>

步骤二: Active Namenode 和 Standby NameNode 从 JournalNodes 的 edits 共享目录中同步 edits 到自己 edits 目录中

步骤三: Standby NameNode 中的 StandbyCheckpointer 类会定期的检查合并的条件是否成立,如果成立会合并 fsimage 和 edits 文件

步骤四: Standby NameNode 中的 StandbyCheckpointer 类合并完之后,将合并之后的 fsimage 上传到 Active NameNode 相应目录中;

步骤五: Active NameNode 接到最新的 fsimage 文件之后,将旧的 fsimage 和 edits 文件清理掉

步骤六:通过上面的几步,fsimage 和 edits 文件就完成了合并,由于 HA 机制,会使得 Standby NameNode 和 Active NameNode 都拥有最新的 fsimage 和 edits 文件(之前 Hadoop 1.x 的 SecondaryNameNode 中的 fsimage 和 edits 不是最新的)



四. Hadoop 2.x 日志合并的处理逻辑与配置总结

4.1 fsimage 和 edit logs 的处理逻辑

在类 org.apache.hadoop.hdfs.server.namenode.NNStorageRetentionManager 的 purgeOldStorage() 方法中描述了 fsimage 和 edit logs 的处理逻辑:

一、找到存在于 fsimage 中的最小 txid,删除比最小 txid 小的 fsimage

二、最小 txid - dfs.namenode.num.extra.edits.retained = 可以删除 txid 集合

三、可删除 txid 集合 > dfs.namenode.max.extra.edits.segments.retained 时,删除集合中的最小值

该逻辑中的 dfs.namenode.max.extra.edits.segments.retained 在下面属性中设置

<property>  
  <name>dfs.namenode.max.extra.edits.segments.retained</name>  
  <value>10000</value>  
  <description>The maximum number of extra edit log segments which should be retained  
  beyond what is minimally necessary for a NN restart. When used in conjunction with  
  dfs.namenode.num.extra.edits.retained, this configuration property serves to cap  
  the number of extra edits files to a reasonable value.  
  </description>  
</property>  

4.2 fsimage 和 edit logs 的配置总结

1. 设置 secondary namenode 放置临时 image 位置目录

<property>  
  <name>dfs.namenode.checkpoint.dir</name>  
  <value>file://${hadoop.tmp.dir}/dfs/namesecondary</value>  
  <description>Determines where on the local filesystem the DFS secondary  
      name node should store the temporary images to merge.  
      If this is a comma-delimited list of directories then the image is  
      replicated in all of the directories for redundancy.  
  </description>  
</property>  

<property>  
  <name>dfs.namenode.checkpoint.edits.dir</name>  
  <value>${dfs.namenode.checkpoint.dir}</value>  
  <description>Determines where on the local filesystem the DFS secondary  
      name node should store the temporary edits to merge.  
      If this is a comma-delimited list of directoires then teh edits is  
      replicated in all of the directoires for redundancy.  
      Default value is same as dfs.namenode.checkpoint.dir  
  </description>  
</property>  

2. 设置 checkpoint 和 checkpoint.check 周期

<property>  
  <name>dfs.namenode.checkpoint.period</name>  
  <value>3600</value>  
  <description>The number of seconds between two periodic checkpoints.  
  </description>  
</property>  

<property>  
  <name>dfs.namenode.checkpoint.check.period</name>  
  <value>60</value>  
  <description>The SecondaryNameNode and CheckpointNode will poll the NameNode  
  every 'dfs.namenode.checkpoint.check.period' seconds to query the number  
  of uncheckpointed transactions.  
  </description>  
</property>  

3. 设置最大的 txns,超出后会合并文件

<property>  
  <name>dfs.namenode.checkpoint.txns</name>  
  <value>1000000</value>  
  <description>The Secondary NameNode or CheckpointNode will create a checkpoint  
  of the namespace every 'dfs.namenode.checkpoint.txns' transactions, regardless  
  of whether 'dfs.namenode.checkpoint.period' has expired.  
  </description>  
</property>  

4. 设置最大的重试 checkpoint 次数

<property>  
  <name>dfs.namenode.checkpoint.max-retries</name>  
  <value>3</value>  
  <description>The SecondaryNameNode retries failed checkpointing. If the   
  failure occurs while loading fsimage or replaying edits, the number of  
  retries is limited by this variable.   
  </description>  
</property>  

5. 设置 fsimage 和 edit log 保存的记录数,默认保存 2 份 fsimge 和 1000000 份 edits 日志信息

<property>  
  <name>dfs.namenode.num.checkpoints.retained</name>  
  <value>2</value>  
  <description>The number of image checkpoint files that will be retained by  
  the NameNode and Secondary NameNode in their storage directories. All edit  
  logs necessary to recover an up-to-date namespace from the oldest retained  
  checkpoint will also be retained.  
  </description>  
</property>  

<property>  
  <name>dfs.namenode.num.extra.edits.retained</name>  
  <value>1000000</value>  
  <description>The number of extra transactions which should be retained  
  beyond what is minimally necessary for a NN restart. This can be useful for  
  audit purposes or for an HA setup where a remote Standby Node may have  
  been offline for some time and need to have a longer backlog of retained  
  edits in order to start again.  
  Typically each edit is on the order of a few hundred bytes, so the default  
  of 1 million edits should be on the order of hundreds of MBs or low GBs.  

  NOTE: Fewer extra edits may be retained than value specified for this setting  
  if doing so would mean that more segments would be retained than the number  
  configured by dfs.namenode.max.extra.edits.segments.retained.  
  </description>  
</property>  
<think>嗯,用户问的是HDFS中的SecondaryNameNodeHA中的Standby NameNode是不是同一个概念。首先,我需要确认自己对这两个概念的理解是否正确。 SecondaryNameNode,我记得在早期的Hadoop版本中,它的作用主要是帮助NameNode合并FsImageEdits,防止Edits日志过大导致恢复时间过长。它并不是NameNode的备份,而是一个辅助节点,定期执行检查点操作。所以它的主要职责是维护元数据,而不是提供高可用性。 而Standby NameNode是在Hadoop高可用性(HA)架构中引入的。在HA模式下,通常有一个Active NameNode一个或多个Standby NameNodeStandby NameNode会实时同步Active NameNodeEdits日志,保持元数据的最新状态,以便在主节点故障时快速接管。这里Standby NameNode确实作为热备份存在,确保高可用性。 用户可能混淆了这两个概念,因为它们都涉及到NameNode的辅助节点,但功能完全不同。需要明确区分SecondaryNameNode的作用是合并元数据,而Standby NameNode是为了故障转移。此外,用户可能是在学习HDFS架构时遇到了困惑,或者在配置集群时对这两个节点的角色不清楚,需要澄清它们的不同用途。 还需要考虑用户的实际应用场景。如果他们正在设置HA集群,了解Standby NameNode的重要性是关键;而如果是在处理元数据合并的问题,SecondaryNameNode的角色更相关。同时,用户可能没有意识到在启用HA后,SecondaryNameNode通常不再需要,因为Standby NameNode会接管其检查点功能。 在回答时,要结构清晰,分点说明两者的定义、职责工作机制的不同,并指出在HA环境下SecondaryNameNode是否还存在。可能需要提到Hadoop版本的变化,比如在HA引入后,SecondaryNameNode的角色被Standby替代,帮助用户理解演进过程。此外,使用示例或比喻可能有助于用户更好地区分两者的不同,比如将SecondaryNameNode比作“清洁工”,而Standby则是“备胎”。</think>以下是关于SecondaryNameNodeStandby NameNode的详细对比分析: --- ### **一、核心结论** **不是同一个概念**。两者虽然都是NameNode的辅助节点,但在功能定位、工作机制适用场景上有本质区别。 --- ### **二、SecondaryNameNode详解** #### 1. **设计目标** - **非高可用组件**:专为解决单NameNode架构下元数据合并问题 - **核心任务**:定期执行**检查点(checkpoint)** 操作,合并FsImageEdits文件 #### 2. **工作机制** - **定期触发条件**: - 默认每小时执行一次 - Edits文件大小达到阈值(默认64MB) - **操作流程**: 1.NameNode请求当前FsImageEdits 2. 在本地合并生成新FsImage 3. 将新FsImage传回NameNode - **关键限制**: - **不提供故障接管能力** - 合并期间NameNode可能短暂卡顿 #### 3. **典型部署场景** ```mermaid graph LR A[Active NameNode] -->|推送FsImage+Edits| B(SecondaryNameNode) B -->|返回新FsImage| A ``` --- ### **三、Standby NameNode详解** #### 1. **设计目标** - **HA架构的核心组件**:实现NameNode的热备份 - **核心能力**:实时故障转移(RTO<30秒) #### 2. **工作机制** - **实时同步**: - 通过JournalNode集群同步Edits日志 - 保持Active NameNode的**元数据一致性** - **检查点合并**: - **接管SecondaryNameNode的职责**,在后台自动执行合并 - **故障转移流程**: 1. ZKFC检测到Active节点故障 2. 通过ZooKeeper完成锁抢占 3. 加载最新FsImage并应用未合并Edits 4. 切换为Active状态 #### 3. **典型部署场景** ```mermaid graph TD A[Active NameNode] -->|写入Edits| J[JournalNode集群] S[Standby NameNode] -->|读取Edits| J Z[ZKFC] -->|心跳检测| A Z -->|心跳检测| S ``` --- ### **四、关键差异对比表** | 特征 | SecondaryNameNode | Standby NameNode | |---------------------|-------------------------|---------------------------| | **设计目的** | 元数据合并 | 故障热备 | | **高可用支持** | 不支持 | 必需组件 | | **数据同步方式** | 定期拉取 | 实时同步 | | **故障接管能力** | 无 | 自动接管(30秒内) | | **元数据一致性** | 合并时可能有延迟 | 实时一致 | | **Hadoop版本依赖** | 早于2.x版本 | Hadoop 2.x+ HA架构 | | **典型部署数量** | 1个 | ≥1个(通常11备) | --- ### **五、版本演进关系** 1. **Hadoop 1.x时代**: - 只有SecondaryNameNode,无HA方案 - 单点故障风险显著 2. **Hadoop 2.x+**: - 引入HA架构后,**Standby NN完全取代SecondaryNameNode** - 检查点合并Standby NN后台自动完成 - 若启用HA后仍配置SecondaryNameNode,会导致: - 资源浪费 - 潜在元数据冲突 --- ### **六、实际部署建议** 1. **非HA集群**: - 必须部署SecondaryNameNode - 建议配置检查点间隔: ```xml <!-- hdfs-site.xml --> <property> <name>dfs.namenode.checkpoint.period</name> <value>3600</value> <!-- 单位:秒 --> </property> ``` 2. **HA集群**: - 禁止部署SecondaryNameNode - Standby NN自动优化合并策略: ```xml <property> <name>dfs.ha.automatic-failover.enabled</name> <value>true</value> </property> ``` --- ### **七、常见误区澄清** - **误区1**:"Standby NN是SecondaryNameNode的升级版" - 事实:两者解决不同维度问题(HA vs 元数据维护) - **误区2**:"可以同时部署两种节点" - 后果:会导致Edits日志被重复修改,引发元数据损坏 - **误区3**:"SecondaryNameNode能提供读服务" - 实际:它不响应任何客户端请求 --- 通过这种对比分析,可以清晰理解两者在HDFS架构中的不同定位。实际生产环境中,建议直接采用HA方案,既解决单点故障问题,又自动包含元数据维护功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值