HDFS 元数据管理机制

我与影子孤独终老i 提交于 2019-11-29 20:47:52

HDFS 元数据管理机制

元数据管理概述

HDFS 元数据,按类型分,主要包括以下几个部分

  1. 文件、目录自身的属性信息,例如文件名,目录名,修改信息等。

  2. 文件记录的信息的存储相关的信息,例如存储块信息,分块情况,副本个数等。

  3. 记录 HDFS 的 Datanode 的信息,用于 DataNode 的管理。

按形式分为内存元数据和元数据文件两种,分别存在内存和磁盘上。
HDFS 磁盘上元数据文件分为两类,用于持久化存储:
fsimage 镜像文件:是元数据的一个持久化的检查点,包含 Hadoop 文件系统中的所有目录和文件元数据信息,但不包含文件块位置的信息。文件块位置信息只存储在内存中,是在 datanode 加入集群的时候,namenode 询问 datanode 得到的,并且间断的更新。
Edits 编辑日志存放的是 Hadoop 文件系统的所有更改操作(文件创建,删除或修改)的日志,文件系统客户端执行的更改操作首先会被记录到 edits 文件中。
fsimage 和 edits 文件都是经过序列化的,在 NameNode 启动的时候,它会将 fsimage 文件中的内容加载到内存中,之后再执行 edits 文件中的各项操作,使得内存中的元数据和实际的同步,存在内存中的元数据支持客户端的读操作,也是最完整的元数据。

当客户端对 HDFS 中的文件进行新增或者修改操作,操作记录首先被记入 edits 日志文件中,当客户端操作成功后,相应的元数据会更新到内存元数据中。因为 fsimage 文件一般都很大(GB 级别的很常见),如果所有的更新操作都往 fsimage 文件中添加,这样会导致系统运行的十分缓慢。

HDFS 这种设计实现着手于:
一是内存中数据更新、查询快,极大缩短了操作响应时间;
二是内存中元数据丢失风险颇高(断电等),因此辅佐元数据镜像文件(fsimage)+编辑日志文件(edits)的备份机制进行确保元数据的安全。
**NameNode 维护整个文件系统元数据。**因此,元数据的准确管理,影响着 HDFS 提供文件存储服务的能力。

元数据目录相关文件

在 Hadoop 的 HDFS 首次部署好配置文件之后,并不能马上启动使用,而是先要对文件系统进行格式化。需要在 NameNode(NN)节点上进行如下的操作:
$HADOOP_HOME/bin/hdfs namenode –format
在这里要注意两个概念,一个是文件系统,此时的文件系统在物理上还不存在;二就是此处的格式化并不是指传统意义上的本地磁盘格式化,而是一些清除与准备工作。
格式化完成之后,将会在 $dfs.namenode.name.dir/current 目录下创建如下的文件结构,这个目录也正是 namenode 元数据相关的文件目录

[外链图片转存失败(img-XJsRI9mI-1568680566703)(D:\学习笔记\hadoop\保存图片\HDFS元数据\01NameNode元数据结构.jpg)]

dfs.namenode.name.dir

其中的 dfs.namenode.name.dir 是在 hdfs-site.xml 文件中配置的,默认值如下:

[外链图片转存失败(img-a5JWSndZ-1568680566705)(D:\学习笔记\hadoop\保存图片\HDFS元数据\02dfs.namenode.name.dir.jpg)]

dfs.namenode.name.dir 属性可以配置多个目录,各个目录存储的文件结构和内容都完全一样,相当于备份,这样做的好处是当其中一个目录损坏了,也不会影响到 Hadoop 的元数据,特别是当其中一个目录是 NFS(网络文件系统 Network File System,NFS)之上,即使你这台机器损坏了,元数据也得到保存。

下面对 $dfs.namenode.name.dir/current/ 目录下的文件进行解释。

VERSION

[外链图片转存失败(img-OXIJ4Zk7-1568680566705)(D:\学习笔记\hadoop\保存图片\HDFS元数据\03VERSION.jpg)]

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

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

cTime NameNode 存储系统创建时间,首次格式化文件系统这个属性是 0,当文件系统升级之后,该值会更新到升级之后的时间戳;
layoutVersion 表示 HDFS 永久性数据结构的版本信息,是一个负整数。
补充说明:
格式化集群的时候,可以指定集群的 cluster_id,但是不能与环境中其他集群有冲突。
如果没有提供 cluster_id,则会自动生成一个唯一的 ClusterID。
$HADOOP_HOME/bin/hdfs namenode -format -clusterId <cluster_id>

seen_txid

$dfs.namenode.name.dir/current/seen_txid 非常重要,是存放 transactionId 的文件,format 之后是 0,它*代表的是 namenode 里面的 edits_文件的尾数,namenode 重启的时候,会按照 seen_txid 的数字,循序从头跑 edits_0000001~到 seen_txid 的数字。所以当你的 hdfs 发生异常重启的时候,一定要比对 seen_txid 内的数字是不是你 edits 最后的尾数。

Fsimage & edits

$dfs.namenode.name.dir/current 目录下在 format 的同时也会生成 fsimage 和 edits文件,及其对应的 md5 校验文件。

secondary namenode

[外链图片转存失败(img-21pxQqBD-1568680566706)(D:\学习笔记\hadoop\保存图片\HDFS元数据\04secondary namenode.jpg)]

NameNode 职责是管理元数据信息,DataNode 的职责是负责数据具体存储,那么 SecondaryNameNode 的作用是什么?从它的名字上看,它给人的感觉就像是 NameNode 的备份。但它实际上却不是。
猜想一下,当 HDFS 集群运行一段事件后,就会出现下面一些问题:

  • edit logs 文件会变的很大,怎么去管理这个文件是一个挑战。
  • NameNode 重启会花费很长时间,因为有很多改动要合并到 fsimage 文件上。
  • 如果 NameNode 挂掉了,那就丢失了一些改动。因为此时的 fsimage 文件非常旧。

因此为了克服这个问题,我们需要一个易于管理的机制来帮助我们减小 edit logs 文件的大小和得到一个最新的 fsimage 文件,这样也会减小在 NameNode 上的压力。这跟Windows 的恢复点是非常像的,Windows 的恢复点机制允许我们对 OS 进行快照,这样当系统发生问题时,我们能够回滚到最新的一次恢复点上。
SecondaryNameNode 就是来帮助解决上述问题的,它的职责是合并 NameNode 的 edit logs 到 fsimage 文件中。

Checkpoint

每达到触发条件,会由 secondary namenode 将 namenode 上积累的所有 edits 和一个最新的 fsimage 下载到本地,并加载到内存进行 merge(这个过程称为 checkpoint),如下图所示:

[外链图片转存失败(img-4fcNSiXR-1568680566707)(D:\学习笔记\hadoop\保存图片\HDFS元数据\05checkpoint流程.png)]

Checkpoint 详细步骤

  1. NameNode 管理着元数据信息,其中有两类持久化元数据文件:edits 操作日志文件和 fsimage 元数据镜像文件。新的操作日志不会立即与 fsimage 进行合并,也不会刷到 NameNode 的内存中,而是会先写到 edits 中(因为合并需要消耗大量的资源),操作成功之后更新至内存。
  2. 有 dfs.namenode.checkpoint.period 和 dfs.namenode.checkpoint.txns 两个配置,只要达到这两个条件任何一个,secondarynamenode 就会执行 checkpoint 的操作。
  3. 当触发 checkpoint 操作时,NameNode 会生成一个新的 edits 即上图中的 edits.new 文件,同时 SecondaryNameNode 会将 edits 文件和 fsimage 复制到本地(HTTP GET 方式)。
  4. secondarynamenode 将下载下来的 fsimage 载入到内存,然后一条一条地执行 edits 文件中的各项更新操作,使得内存中的 fsimage 保存最新,这个过程就是 edits 和 fsimage文件合并,生成一个新的 fsimage 文件即上图中的 Fsimage.ckpt 文件。
  5. secondarynamenode 将新生成的 Fsimage.ckpt 文件复制到 NameNode 节点。在 NameNode 节点的 edits.new 文件和 Fsimage.ckpt 文件会替换掉原来的 edits 文件和 fsimage 文件,至此刚好是一个轮回,即在 NameNode 中又是 edits 和 fsimage 文件。
  6. 等待下一次 checkpoint 触发 SecondaryNameNode 进行工作,一直这样循环操作。

Checkpoint 触发条件

Checkpoint 操作受两个参数控制,可以通过 core-site.xml 进行配置:

<property>
	<name> dfs.namenode.checkpoint.period</name>
 	<value>3600</value>
	<description>
		两次连续的 checkpoint 之间的时间间隔。默认 1 小时
	</description>
</property>

<property>
 	<name>dfs.namenode.checkpoint.txns</name>
 	<value>1000000</value>
 	<description>
		最大的没有执行 checkpoint 事务的数量,满足将强制执行紧急 checkpoint,即使尚未达到检查点周期。默认设置为 100 万。 
	</description>
</property>

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!