一、概述

在 Hadoop 的 HDFS 首次部署好配置文件之后,并不能马上启动使用,而是先要对文件系统进行格式化操作:

1
hdfs namenode -format
  1. format 之前,HDFS 在物理上还不存在
  2. 此处的 format 并不是指传统意义上的本地磁盘格式化,而是一些清除与准备工作,比如创建元数据本地存储目录和一些初始化的元数据相关文件

1.1. 元数据文件存储目录

Namenode 元数据存储目录由参数: dfs.namenode.name.dir 指定,格式化完成之后,将会在 ${dfs.namenode.name.dir}/current 目录下创建如下的文件:

1
2
3
4
5
6
7
8
9
10
11
12
[root@5c515555707e current]# tree /data/hadoop/dfs/name
/data/hadoop/dfs/name
|-- current
| |-- VERSION
| |-- edits_0000000000000000001-0000000000000044061
| |-- edits_inprogress_0000000000000044062
| |-- fsimage_0000000000000000000
| |-- fsimage_0000000000000000000.md5
| |-- fsimage_0000000000000044061
| |-- fsimage_0000000000000044061.md5
| `-- seen_txid
`-- in_use.lock

其中的 dfs.namenode.name.dir 是在 hdfs-site.xml 文件中配置的

1
2
3
4
5
6
<configuration>
<property>
<name>dfs.namenode.name.dir</name>
<value>/data/hadoop/dfs/name</value>
</property>
</configuration>

dfs.namenode.name.dir 属性可以配置多个目录,各个目录存储的文件结构和内容都完全一样,相当于备份,当其中一个目录损坏了,也不会影响到hadoop的元数据,

如果其中一个目录是 NFS 之上,即使机器损坏了,元数据也得到保存。

1.2. 元数据相关文件

1.2.1. VERSION

1
2
3
4
5
6
7
8
[root@5c515555707e current]# cat VERSION
#Tue Aug 09 14:38:17 UTC 2022
namespaceID=730830636
clusterID=CID-835a3b87-7766-4cc4-a89d-bcb4be2bff91
cTime=1654693842150
storageType=NAME_NODE
blockpoolID=BP-815850884-172.17.0.2-1654693842150
layoutVersion=-63
  1. namespaceID/clusterID/blockpoolID

这些都是 HDFS 集群的唯一标识符。标识符被用来防止 Datanode 意外注册到另一个集群中的 Namenode 上。这些标识在联邦(federation)部署中特别重要。联邦模式下,会有多个 Namenode 独立工作。每个的 NameNode 提供唯一的命名空间(namespaceID),并管理一组唯一的文件块池(blockpoolID)。clusterID 将整个集群结合在一起作为单个逻辑单元,在集群中的所有节点上都是一样的。

  1. storageType

    说明这个文件存储的是什么进程的数据结构信息,如果是 Datanode,storageType=DATA_NODE。

  2. cTime

    Namenode 存储系统创建时间,首次格式化文件系统这个属性是0,当文件系统升级之后,该值会更新到升级之后的时间戳

  3. layoutVersion

    HDFS 元数据格式的版本。添加需要更改元数据格式的新功能时,请更改此数字。当前的 HDFS 软件使用比当前版本更新的布局版本时,需要进行HDFS 升级。

1.2.2. seen_txid

包含最后一个checkpoint的最后一个事务ID。这不是NameNode接受的最后一个事务ID。该文件不会在每个事务上更新,而只会在checkpoint或编辑日志记录上更新。该文件的目的是尝试识别edits启动期间是否丢失的文件。如果 edits目录被意外删除,然后自上一个checkpoint以来的所有事务都将消失,NameNode仅从最近的一次fsimage加载启动。为了防止这种情况,NameNode启动还检查 seen_txid以确认它至少可以加载该数目的事务。如果无法验证装入事务,它将中止启动。

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@5c515555707e current]# ll
total 11692
-rw-r--r-- 1 root root 213 Aug 9 14:38 VERSION
-rw-r--r-- 1 root root 10485760 Jun 9 12:05 edits_0000000000000000001-0000000000000044061
-rw-r--r-- 1 root root 1048576 Aug 13 00:02 edits_inprogress_0000000000000044062
-rw-r--r-- 1 root root 321 Jun 8 13:10 fsimage_0000000000000000000
-rw-r--r-- 1 root root 62 Jun 8 13:10 fsimage_0000000000000000000.md5
-rw-r--r-- 1 root root 415766 Aug 9 14:38 fsimage_0000000000000044061
-rw-r--r-- 1 root root 62 Aug 9 14:38 fsimage_0000000000000044061.md5
-rw-r--r-- 1 root root 6 Aug 9 14:38 seen_txid
[root@5c515555707e current]# cat seen_txid
44062
# edits_inprogress_0000000000000044062

1.2.3. fsimage

元数据镜像文件。每个fsimage文件还有一个对应的.md5文件,其中包含MD5校验和,HDFS使用该文件来防止磁盘损坏文件异常。

1.2.4. Editslog

已完成且不可修改的编辑日志。这些文件中的每个文件都包含文件名定义的范围内的所有编辑日志事务。在HA高可用性部署中,主备namenode之间可以通过 edits log 进行数据同步

二、fsimage 内存镜像文件

目前 Namenode 的实现是将命名空间信息记录在 fsimage(命名空间镜像)的二进制文件中,fsimage 将文件系统目录树中的每个文件或者目录的信息保存为一条记录,每条记录中包括了该文件(或目录)的名称、大小、用户、用户组、修改时间、创建时间等信息。Namenode 重启时,会读取这个 fsimage 文件来重构命名空间。

三、Edits log 编辑日志

为了避免两次持久化之间数据丢失的问题,又设计了 Edits log 编辑日志文件,HDFS 将新 fsimage 文件和上一个 fsimage 文件中进行的 Namenode 操作记录在 editlog (编辑日志) 文件中,editlog 是一个日志文件,文件中记录的是 HDFS 所有更改操作(文件创建,删除或修改)的日志,文件系统客户端执行的更改操作首先会被记录到 edits 文件中。