思考

思考:NameNode中的元数据是存储在哪里的?

首先,我们做个假设,如果存储在NameNode节点的磁盘中,因为经常需要进行随机访问,还有响应客户请求,必然是效率过低。
但如果只存在内存中,一旦断电,元数据丢失,整个集群就无法工作了。
因此元数据在内存中+在磁盘中备份元数据的FsImage

这样又会带来新的问题,当在内存中的元数据更新时,如果同时更新FsImage,就会导致效率过低,但如果不更新,就会发生一致性 问题,一旦NameNode节点断电,就会产生数据丢失。

因此,引入Edits文件(只进行追加操作,效率很高)。每当元数据有更新或者添加元数据时,修改内存中的元数据并追加到Edits中。这样,一旦NameNode节点断电,可以通过FsImage和Edits的合并,合成元数据。

但是,如果长时间添加数据到Edits中,会导致该文件数据过大,效率降低,而且一旦断电,恢复元数据需要的时间过长。因此,需要定期进行FsImage和Edits的合并,如果这个操作由NameNode节点完成,又会效率过低。因此,引入一个新的节点SecondaryNamenode,专门用于FsImageEdits的合并。
image.png

元数据快照-fsimage

fsimage 是 HDFS(Hadoop Distributed File System)中 NameNode 存储的元数据文件,它保存了整个文件系统的元数据快照。该文件记录了 HDFS 文件系统中所有文件、目录及其关联的块信息,但不包括块的实际数据(数据存储在 DataNode 上)。

fsimage 的作用

fsimageNameNode 的核心元数据文件,用于保存文件系统的结构和状态。它可以被看作是 HDFS 在某个时间点上的完整元数据备份。fsimage 文件的主要功能是帮助 NameNode 快速重启并恢复文件系统的状态,而不需要重放所有的操作日志(edits 文件)。

只存储时间点:时间点到当前时间的修改,存储在edits中

fsimage 的内容

fsimage 文件保存以下关键信息:

  1. 目录树结构:HDFS 中所有文件和目录的层次结构。
  2. 文件到块的映射:每个文件包含的块的列表,文件与块的对应关系。
  3. 块副本的位置:每个块存储在哪些 DataNode 上。
  4. 文件权限和属性:包括文件大小、拥有者、权限、修改时间等元信息。
  5. 配额信息:目录或文件的存储配额限制。

fsimage 的维护和生成

  1. 创建新的 fsimageSecondaryNameNode 定期从 NameNode 获取当前的 fsimageedits 文件,将它们合并生成一个新的 fsimage 文件。这个过程被称为 checkpoint

  2. 清理旧文件:在新的 fsimage 生成后,旧的 fsimage 文件和合并前的 edits 文件会被删除。

  3. 重启时的作用:当 NameNode 重启时,它会读取最新的 fsimage 文件,以恢复文件系统的基本结构,然后应用 edits 文件中记录的操作来恢复最新状态。这大大缩短了 NameNode 的启动时间。

    查看fsimage文件

    
    #webhdfs的方式查看
    hdfs oiv    -i fsimage_0000000000000000699
    #开启后会生成IP+端口
    hdfs dfs -ls webhdfs://127.0.0.1:5978/

导出的方式查看

导出为XML文件,copy到本地查看

hdfs oiv -p XML -i fsimage_0000000000000000699 -o /tmp/oiv.xml

![image.png|675](http://zjyun.cc:6001/wangzijian/202409282338434.png)

## 修改记录-Edits
edits 文件是 HDFS(Hadoop Distributed File System)中 NameNode 保存的操作日志文件,记录了对文件系统的所有修改操作。与 fsimage 文件(HDFS 的元数据快照)不同,edits 文件主要保存的是自上次 fsimage 生成以来的文件系统变化记录。
### edits 文件的作用
- **记录文件系统的所有变更**:每当文件系统发生变更时(如创建、删除、修改文件或目录等操作),这些操作都会首先记录在 edits 文件中。
- **确保数据一致性**:在 NameNode 重启时,它可以通过读取 fsimage 文件恢复系统的基础状态,然后通过重放 edits 文件中的日志恢复文件系统的最新状态,确保数据一致性。
- **延续系统操作历史**:HDFS 不会每次修改文件系统时都重写整个 fsimage 文件,而是先记录到 edits 文件中,从而提高性能。

### edits 文件的内容
- **操作日志**:edits 文件中记录的是一系列对 HDFS 文件系统的操作,比如创建文件、删除文件、修改权限等。
- **顺序记录**:所有操作日志按顺序记录,这些操作会在 NameNode 启动时依次重放,以恢复系统状态。

### edits 文件的使用
- **文件系统操作**:当客户端对 HDFS 进行任何文件操作(如创建文件、删除文件等),这些操作首先会被记录到 edits 文件中。只有在这些操作成功写入 edits 文件后,NameNode 才会返回操作成功的响应给客户端。
- **恢复系统状态**:当 NameNode 重启时,系统会先加载 fsimage 文件中的元数据快照,然后从 edits 文件中重放所有记录的操作,以恢复到最新的状态。

当 edits 文件过大时,NameNode 重启时需要重放的操作日志会变得非常多,这会导致启动时间延长。为了解决这个问题,HDFS 引入了 checkpoint 机制。

### 配置参数
HDFS 提供了相关配置来优化 edits 文件的管理:

- **dfs.namenode.checkpoint.period**:设置 checkpoint 操作的时间间隔。
- **dfs.namenode.checkpoint.txns**:设置 edits 文件中允许记录的最大操作数,超过后将触发 checkpoint。
### 查看edits文件

文件导出的方式查看

hdfs oev -p XML -i edits_0000000000000000686-0000000000000000699 -o /tmp/oev.xml


![image.png](http://zjyun.cc:6001/wangzijian/202409282340836.png)

## edits 与 fsimage 的关系?
- **fsimage**:记录了 HDFS 在某个特定时刻的元数据快照。
- **edits**:记录了自上次 fsimage 生成以来所有对文件系统的修改。随着时间的推移,edits 文件会不断增长。

## Checkpoint 机制
checkpoint 通过 SecondaryNameNode 定期将 edits 文件与 fsimage 文件合并,生成新的 fsimage 文件,并清理旧的 edits 文件。

具体过程如下:
1. **合并操作**:SecondaryNameNode 获取当前的 fsimageedits 文件,将它们合并生成新的 fsimage,同时创建一个新的空的 edits 文件来记录新的操作。
2. **定期执行**:HDFS 根据配置参数定期进行 checkpoint,避免 edits 文件无限增长。
3. **性能优化**:通过 checkpoint 机制,可以减少 NameNode 重启时需要重放的操作数量,缩短启动时间。
![image.png](http://zjyun.cc:6001/wangzijian/202409281708459.png)
### 前提
- 当前的修改信息在edit_inprogress_001中。
- 镜像在fsimage中。
- 内存中为edit_inprogress_001+fsimage。
- SecondaryNameNode请每5秒求是否需要,dfs.namenode.checkpoint.check.period。
### 触发checkpoint
- **edits 文件的大小超过设定的阈值**:
    - 当 edits 文件的大小达到某个预定义的上限时(比如默认的 64MB),SecondaryNameNode 会触发一个 **Checkpoint** 过程,将 fsimageedits 合并,生成新的 fsimage 快照。
- **时间间隔达到设定的周期**
    - HDFS 系统会定期触发 Checkpoint 以防止 edits 文件积累过多操作。默认情况下,这个时间间隔为 1 小时(3600 秒),可以通过配置参数 dfs.namenode.checkpoint.period 来调整。
- **手动触发**:
    - 系统管理员可以通过命令手动触发 Checkpoint。比如在维护或重启 NameNode 前进行一次 Checkpoint,确保数据一致性。
### checkpoint流程
1. SecondaryNameNode请求是否需要CheckPoint。
2. 请求CheckPoint。
3. 滚动edits,原来写入到001,现在写入到新的002edits文件中。
4. 将fsimageedits复制到SecondaryNameNode节点。
5. 合并加载到内存中。
6. 生成新的fsimage
7. 复制到需要checkpoint 的namenode。
8. 替换掉原来的fsimages,完成镜像的更新。