Hadoop-组件-HDFS-源码学习-元数据管理-设计-内存元数据
一、概述
元数据(文件系统的命名空间)在 Namenode 的内存中以一颗树的结构来存储。在 HDFS中,不管是目录还是文件,在文件系统目录树中都被看作是一个 INode 节点。如果是目录,则其对应的类为 INodeDireetory:如果是文件,则其对应的类为 INodeFile。 INode Directory 以及 INodeFile 类都是 INode 的派生类。INodeDirectory 中包含一个成员集合变量 children, 如果该目录下有子目录或者文件,其子目录或文件的 INode 引用就会被保存在 children 集合中。HDFS 就是通过这种方式来维护整个文件系统的目录结构的。
二、实现
HDFS 元数据(文件系统的命名空间)在 Namenode 的内存中以一颗树的结构来存储。在 HDFS 中,不管是目录还是文件,在文件系统目录树中都被看作是一个 INode 节点。如果是目录,则其对应的类为 INodeDirectory,如果是文件,则其对应的类为 INodeFile。
INodeDirectory 以及 INodeFile 类都是 INode 的派生类。INodeDirectory 中包含一个成员集合变量 children,如果该目录下有子目录或者文件,其子目录或文件的 INode 引用就会被保存在 children 集合中。HDFS 就是通过这种方式来维护整个文件系统的目录结构的。
![](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_36,g_center,color_FFFFFF,shadow_100,t_100,g_se,x_30,y_130)
2.1. 相关类
2.1.1. INode 相关类
HDFS 借鉴了 Linux 的 inode,将 HDFS中文件和目录的抽象类命名为 INode。在 HDFS的文件系统目录树中,不管是目录还是文件,都会被看作是一个 INode 类的引用。
INode 类是一个抽象类,是 INodeDirectory 和 INodeFile 的父类。如果是目录,则其实际类为INodeDirectory;如果是文件,则其对应的类为 INodeFile。INodeDirectory 中包含一个成员集合变量 children,如果该目录下有子目录或者文件,其子目录或文件的引用就会保存在 children
集合中。
INode 类是整个 INode 体系的根接口,它是一个抽象类,保存了 HDFS 目录和文件的所有共同属性,包括当前节点的父节点的 INode 对象的引用(只能是 INodeDirectory 类或者INodeReference 类)、文件/目录名、用户组、访问权限、最后修改时间、上次访问时间、完整路径名、文件扩展属性等。
INode 类中只有一个字段,就是 parent,表明当前 INode 的父目录。HDFS中除了根目录外,其他所有的文件与目录都存在一个父目录。
父目录的类型只能是 INodeDirectory 类或者 INodeReference 类之一。
![](https://hexo-blog-3494269.oss-cn-beijing.aliyuncs.com/images/%E6%88%AA%E5%B1%8F2021-04-29%20%E4%B8%8A%E5%8D%889.11.52.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,text_d3d3Lnp4Y2hvbWUuY29tCg==,size_36,g_center,color_FFFFFF,shadow_100,t_100,g_se,x_30,y_130)
INodeDirectory
INodeDirectory 抽象了 HDFS 文件系统中的目录,里面保存了一组文件和其他一些目录。在 INodeDirectory 的实现中,添加了成员变量 children 用来保存目录中所有子目录项的 INode 对象。
INodeDirectory 中的方法分为如下几类:
INodeFile
在文件系统目录树中,使用 INodeFile 类抽象一个 HDFS 文件,INodeFile 类中保存了 HDFS 文件最重要的两个信息: 文件头 header 字段和文件对应的数据块信息 blocks 字段。
header 字段保存了当前文件有多少个副本,以及文件数据块的大小
header 字段类似于 INode 中的 permission 字段,前4个比特用于保存存储策略,中间12 个比特用于保存文件备份系数,后 48 个比特用于保存数据块大小。
blocks 字段是一个 BlockInfo 类型的数组,保存了当前文件对应的所有数据块信息。
blocks 字段是一个 BlockInfo 类型的数组,Blocklnfo 类继承自 Block 类,它保存了数据块与文件、数据块与数据节点的对应关系。从 Blockinfo 对象可以获得数据块所属的文件,即文件的 INodeFile 对象,也可以获得保存数据块副本的所有数据节点的信息。
INodeReference
当 HDFS 文件/目录处于某个快照中,并且这个文件/目录被重命名或者移动到其他路径时,该文件/目录就会存在多条访问路径。INodeReference 及其子类就是为了解决这个问题而产生的。
2.1.2. Feature 相关类
在 HDFS 2.6 版本中引入了特性(Feature),定义了 INode.Feature 接口抽象 INode 特性的根接口,INode 的所有特性都实现了这个接口,每个特性都对应一个 Feature 子类。
SnapshotFeature 实现
FileUnderConstructionFeature 实现
当客户端为写或者追加写(append) 数据打开 HDFS 文件时,文件所处的状态就是构建状态。当客户端打开一个文件进行写或者追加写操作前,会首先调用 INodeFile.toUnderConstruction() 方法将该文件转变为构建状态。
FileUnderConstructionFeature 记录了一些与写操作相关的属性:
- clientName: 发起文件写操作的客户端名称,这个属性也用于租约管理功能。在 HDFS 中,租约是名字节点维护的给予客户端在一定期限内可以进行文件写操作的权限的合同。
- clientMachine: 客户端所在主机。
2.1.3. FSDirectory
HDFS 文件系统的命名空间(namespace),是以 “/“ 为根的整个目录树,FSDirectory 维护着文件系统目录树的根节点(这个根节点是整个文件系统的 root,是一个 INodeDirectory 类型)。
FSNamesystem 也提供了管理目录树结构的方法,但 FSNamesystem 中的方法多是调用 FSDirectory 类的实现,FSNamesystem 在FSDirectory 类方法的基础上添加了 editlog 日志记录的功能,而 FSDirectory 的操作则全部是在内存中进行的。
HDFS 引入 FSDirectory 将文件系统目录树的所有操作抽象成一个统一的接口,其他子系统在调用目录树操作时不需要了解目录树内部实现的复杂逻辑了,只需调用 FSDirectory 对象上的指定方法即可,FSDirectory 实现对应的逻辑。