Hadoop-组件-HDFS-源码学习-HDFS 架构设计-NameNode 架构-元数据管理
看源码啦~~~😊
元数据主要是指整个集群的信息,包括数据目录信息、节点信息、数据块位置存储信息、集群通信信息以及心跳信息等等,最重要的用途就是方便集群管理,快速地找到正确有效的信息。
一、什么是元数据?
为了保证用户操作元数据高效,延迟低,NameNode 把所有的元数据(文件系统命名空间 namespace)都存储在内存中。内存中的元数据是最完整的,包括文件自身属性信息、文件块位置映射信息。但是内存的致命问题是,断点数据丢失,数据不会持久化。因此 NameNode 又辅佐了元数据文件(fsimage+edits)来保证元数据的安全完整。
HDFS 的目录和文件在内存中是以一棵树的形式存储的,这个目录树结构是由 Namenode 维护的,Namenode 会修改这个树形结构以对外提供添加和删除文件等操作功能。这也是我们通过管理界面可以对文件做的一些操作~
![截屏2022-08-09 22.41.27](https://note3.oss-cn-hangzhou.aliyuncs.com/source/%E6%88%AA%E5%B1%8F2022-08-09%2022.41.27.png)
文件系统目录树上的节点还保存了 HDFS 文件与数据块的对应关系, HDFS 中的每个文件都是被拆分成若干数据块冗余存放的,文件与数据块的对应关系也是由 Namenode 维护的。
二、内存元数据
元数据(文件系统的命名空间)在 Namenode 的内存中以一颗树的结构来存储。在 HDFS中,不管是目录还是文件,在文件系统目录树中都被看作是一个 INode 节点。如果是目录,则其对应的类为 INodeDireetory:如果是文件,则其对应的类为 INodeFile。 INode Directory 以及 INodeFile 类都是 INode 的派生类。INodeDirectory 中包含一个成员集合变量 children, 如果该目录下有子目录或者文件,其子目录或文件的 INode 引用就会被保存在 children 集合中。HDFS 就是通过这种方式来维护整个文件系统的目录结构的。
FSDirectory 维护着文件系统目录树的根节点(这个根节点是整个文件系统的 root,是一个 INodeDirectory 类型)。
![](https://note3.oss-cn-hangzhou.aliyuncs.com/source/%E6%88%AA%E5%B1%8F2022-08-13%2014.45.49.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,text_d3d3Lnp4Y2hvbWUuY29tCg==,size_30,g_center,color_FFFFFF,shadow_100,t_100,g_se,x_30,y_30)
三、元数据文件
在 Namenode 中,命名空间(namespace,指文件系统中的目录树、文件元数据等信息) 是被全部缓存在内存中的,一旦 Namenode 重启或者宕机,内存中的所有数据将会全部丢失,所以需要有一种机制能够将整个命名空间持久化保存,并且能在 Namenode 重启时重建命名空间。
3.1. fsimage 文件
HDFS 会将内存中命名空间保存到 Namenode 的本地文件系统上一个叫 fsimage(命名空间镜像)的文件中。利用这个文件,Namenode 每次重启时都能将整个 HDFS 的命名空间重构。fsimage 文件的操作由 FSImage 类负责。
3.2. editlog
另外,对 HDFS 的各种操作,Namenode 会在操作日志(editlog)中进行记录,以便周期性地将该日志与 fsimage 进行合并生成新的 fsimage。该日志文件也在 Namenode 的本地文件系统中保存,叫 editlog 文件,editlog 的相关操作由 FSEditLog 类管理,和 fsimage 文件不同,editlog 文件会随着 Namenode 的运行实时更新,所以 FSEditLog 类的实现依赖于底层的输入流和输出流,同时 FSEditLog 类还需要对外提供大量的 log*()
方法用于记录命名空间的修改操作。
四、元数据管理
4.1. 文件目录树操作
4.1.1. 创建目录 (mkdirs)
4.1.2. 创建文件 (create)
4.2. editlog 记录
为了避免 Namenode 两次持久化之间数据丢失的问题,设计了 Edits log 编辑日志文件,HDFS 将新 fsimage 文件和上一个 fsimage 文件中进行的 Namenode 操作记录在 editlog (编辑日志) 文件中,editlog 是一个日志文件,文件中记录的是 HDFS 所有更改操作(文件创建,删除或修改)的日志,文件系统客户端执行的更改操作首先会被记录到 edits 文件中。
4.3. checkpoint 机制
当 HDFS 集群运行一段事件后,editlog 文件会变得非常大,甚至将磁盘空间写满。在 Namenode 启动过程中一个很重要的部分就是逐条读取editlog 文件中的记录,之后与 Namenode 命名空间合并。巨大的 editlog 文件会导致一系列问题:
- editlog 变的很大,fsimage 将会变得很旧
- Namenode 重启需要将很多改动要合并到 fsimage 文件上,花费很长时间
为了避免 editlog 过大需要频繁进行 fsimage 持久化,但是 I/O 操作又是一种内存到磁盘的耗精力操作,会影响 NameNode 正常服务,为了解决这些问题,HDFS 引入了检查点机制。
HDFS 的检查点机制会定时将 editlog 文件与 fsimage 文件合并以产生新的 fsimage 文件。Namenode 可以直接从 fsimage 加载元数据,而不用读取与合并 editlog 中的记录,命名空间的重建效率会大大提高,同时 Namenode 的启动时间也会相应减少。但是合并 fsimage 与 editlog 以产生新的 fsimage 文件是一项非常消耗 I/O 和 CPU 资源的操作。在执行检查点操作期间,Namenode 还需要限制其他用户对 HDFS 的访问和操作,所以 HDFS 将检查点操作从 Namenode 移动到 Secondary Namenode
4.4. 保存
FSImage 类最重要的功能之一就是将当前时刻 Namenode 的命名空间保存到 fsimage 文件中。
4.5. 重建
当 Namenode 启动时,首先会将 fsimage 文件中记录的命名空间加载到 Namenode 内存中,然后将 editlog 文件中记录的更新操作加载并合并到命名空间中。接下来 Namenode 会等待各个 Datanode 向自己汇报数据块信息来组装 blockMap,从而离开安全模式。
五、总结
当客户端对 HDFS 中的文件进行新增或者修改操作,操作记录首先被记入 edits 日志文件中,当客户端操作成功后,相应的元数据会更新到内存元数据中。因为 fsimage 文件一般都很大,如果所有的更新操作都往 fsimage 文件中添加,这样会导致系统运行的十分缓慢。
HDFS 这种设计实现着手于: 一是内存中数据更新、查询快,极大缩短了操作响应时间;二是内存中元数据丢失风险颇高,因此辅佐元数据镜像文件(fsimage) + 编辑日志文件(edits) 的备份机制进行确保元数据的安全。
NameNode 维护整个文件系统元数据。因此,元数据的准确管理,影响着 HDFS 提供文件存储服务的能力。