HDFS 文件结构

原文地址:http://www.pluscn.net/?p=833

本文主要描述HDFS中的NameNode、DataNode、Secondary NameNode 是如何在磁盘上组织、存储持久化数据的。

1. NameNode 结构

在HDFS中,namenode提供整个HDFS文件系统的namespace管理,块管理以及与metadata相关的服务。

最新格式化的NameNode会创建以下目录结构:

${dfs.name.dir}/current/{VERSION,edits,fsimage,fstime}

其中,dfs.name.dir是一个目录列表,存储每个目录的镜像。VERSION文件是Java属性文件,包含运行HDFS的版本信息。

edits,是编辑日志文件。当客户断执行写操作的时,NameNode首先会在编辑日志中写下记录,并在内存中保存一个文件系统元数据,这个描述符会在编辑日志有了改动后更新。内存中的元数据用来提供读数据请求服务。

编辑日志会在每次成功操作之后,且成功代码尚未返回给客户端之前进行刷新和同步。对于要写入多个目录的操作,该写入流要刷新和同步到所有的副本上,这就保证了操作不会因故障丢失数据。

fsimage 是一个二进制文件,当中记录了HDFS中所有文件和目录的元数据信息。

该文件中保存的以序列化格式存储的文件inodes和文件目录的格式如下:

其中,每个inodes 表征一个文件或目录的元数据信息,以及文件的副本数、访问和修改时间等信息。

在namenode启动时,就需要对fsimage按照上面的格式进行顺序的加载,以将fsimage中记录的HDFS元数据信息加载到内存中。

和编辑日志不同的是,它不会在每个文件系统的写操作后进行更新,因为写出fsimage文件会非常慢(fsimage可能增长到GB大小)。

fstime,是上一次新打开一个操作日志的时间(long型)。

NameNode启动过程

fsimage加载过程

Fsimage加载过程完成的操作主要是为了:

1.      从fsimage中读取该HDFS中保存的每一个目录和每一个文件

2.      初始化每个目录和文件的元数据信息

3.      根据目录和文件的路径,构造出整个namespace在内存中的镜像

4.      如果是文件,则读取出该文件包含的所有blockid,并插入到BlocksMap中。

整个加载流程如下图所示:

如上图所示,namenode在加载fsimage过程其实非常简单,就是从fsimage中不停的顺序读取文件和目录的元数据信息,并在内存中构建整个namespace,同时将每个文件对应的blockid保存入BlocksMap中,此时BlocksMap中每个block对应的datanodes列表暂时为空。当fsimage加载完毕后,整个HDFS的目录结构在内存中就已经初始化完毕。

2.DataNode结构

DataNode是文件系统中真正存储数据的地方,其周期性的向元数据节点回报期存储的数据块信息。

datanode的存储目录由dfs.data.dir属性设置,该目录是datanode启动时自动创建的,不需要进行格式化,目录的结构如下所示:

${dfs.data.dir}/current/VERSION
                       /blk_<id_1>
                       /blk_<id_1>.meta
                       /blk_<id_1>
                       /blk_<id_1>.meta
                       /...
                       /blk_<id_64>
                       /blk_<id_64>.meta
                       /subdir0/
                       /subdir1/
                       /...
                       /subdir63/
               /previous/
               /detach/
               /tmp/
               /in_use.lock
               /storage

current是当前的工作目录,previous是升级HDFS之前的工作目录,在升级时,HDFS并不会将文件从previous拷贝到current目录中,而是遍历previous中的所有文件,在current目录中创建硬链接。

detach目录保存用于copy-on-write的文件,在Datanode重启时需要恢复。

tmp目录保存一些临时数据。

in_use.lock文件用于对datanode加锁,storage文件保存了布局版本及升级版本提示信息。

下面来看current目录的结构,目录中的文件都有blk_前缀,有两类文件:块文件和块元数据文件(.meta后缀)。当目录中数据块的数量增加到64个(由dfs.datanode.numblocks属性设置,子目录的数量也是由该属性设置),datanode会创建一个子目录来存放新的数据。采用树状结构的组织方式,datanode可以有效管理各个目录中的文件,避免将很多文件放在一个目录之中。

3. Secondary NameNode

Secondary NameNode(从元数据节点或者辅助节点)是一个辅助NameNode 处理fsimage和编辑日志的节点,它从NameNode中拷贝fsimage和编辑日志到临时目录,并定期的合并成一个新的fsimage,随后会将新的fsimage上传到NameNode。

辅助Namenode的存储目录由fs.checkpoint.dir属性设置,目录的结构如下所示:

$(fs.checkpoint.dir}/current/VERSION
                            /edits
                            /fsimage
                            /fstime
                    /previous.checkpoint/VERSION
                                        /edits
                                        /fsimage
                                        /fstime

Secondary NameNode并不是NameNode的备用节点,它与NameNode有着不同的职责(二者的服务可以运行在一台机器上),其主要功能是周期性的将元数据节点的命名空间镜像文件和修改日志合并,以防止日志文件过大,合并后的命名空间镜像文件在从元数据节点中叶保存一份,以防元数据节点失效的时候用于恢复。

元数据节点使用日志记录元数据的修改,其工作主要包括:

当文件系统客户端(client)进行写操作时,首先把它记录在修改日志中(edit log)

元数据节点在内存中保存了文件系统的元数据信息,在记录了修改日志后,元数据节点则修改内存中的数据结构。

每次的写操作成功之前,修改日志都会同步(sync)到文件系统。

命名空间映像文件(fsimage)是内存中的元数据在硬盘上的checkpoint,它是一种序列化的格式,并不能够在硬盘上直接修改。

当元数据节点失败时,则最新checkpoint的元数据信息从fsimage加载到内存中,然后逐一重新执行修改日志中的操作。

从元数据节点用来帮助元数据节点将内存中的元数据信息checkpoint到硬盘上,checkpoint的过程如下图所示:

  1. 从元数据节点通知元数据节点生成新的日志文件,以后的日志都写到新的日志文件中。
  2. 从元数据节点用http get从元数据节点获得fsimage文件及旧的日志文件。
  3. 从元数据节点将fsimage文件加载到内存中,并执行日志文件中的操作,然后生成新的fsimage文件。
  4. 从元数据节点奖新的fsimage文件用http post传回元数据节点
  5. 元数据节点可以将旧的fsimage文件及旧的日志文件,换为新的fsimage文件和新的日志文件,然后更新fstime文件,写入此次checkpoint的时间。
  6. 这样元数据节点中的fsimage文件保存了最新的checkpoint的元数据信息,日志文件也重新开始,不会变的很大了,从而使得元数据节点启动时花费很少的时间进行日志的合并。
在这个过程结束后,NameNode就有了新的fsimage文件和更小的edits文件。上述过程也清晰的表明了威斯敏Secondary NameNode要有和原NameNode 一样的内存需求(要把fsimage 加载到内存中),因此econdary NameNode在集群中也需要专用机器。

参考

http://blog.jeoygin.org/2012/02/hdfs-overview.html

http://blog.youkuaiyun.com/wuzongpo/article/details/7399920

### HDFS 存储结构图解析 HDFS(Hadoop Distributed File System)的存储结构是基于分布式文件系统设计的,其核心组件包括 NameNode 和 DataNode。HDFS 的体系结构采用 Master/Slave 模型,其中 NameNode 是集群的管理者,而 DataNode 负责实际的数据存储[^1]。 #### 1. HDFS 存储结构概述 HDFS 中的文件会被分割为多个块(Block),这些块会被分布到不同的 DataNode 上进行存储。每个块的副本数量由用户设置,默认值为 3。这种设计确保了数据的高可用性和容错能力。NameNode 负责管理文件系统的命名空间和控制客户端对文件的访问,同时记录每个文件的块信息以及这些块在 DataNode 上的分布情况。 #### 2. HDFS 存储结构图解 以下是一个典型的 HDFS 存储结构图解说明: - **NameNode**:作为主节点,负责管理文件系统的元数据,例如文件与块的映射关系、块的位置信息等。它还维护了一个名为 fsimage 的镜像文件,用于持久化存储文件系统的元数据[^3]。 - **DataNode**:作为从节点,负责存储实际的数据块,并定期向 NameNode 汇报其状态和所存储的块信息。 - **Client**:客户端通过与 NameNode 交互来获取文件的块位置信息,然后直接与 DataNode 进行数据读写操作。 ```plaintext +-------------------+ | Client | +-------------------+ | v +-------------------+ | NameNode | (管理元数据) +-------------------+ | v +-------------------+ +-------------------+ +-------------------+ | DataNode 1 |<---->| DataNode 2 |<---->| DataNode 3 | +-------------------+ +-------------------+ +-------------------+ ``` #### 3. 数据分布与机架感知 为了提高数据的可靠性,HDFS 实现了机架感知(Rack Awareness)。机架感知是一种硬件拓扑感知机制,能够根据 DataNode 所在的物理机架位置来优化数据的存储和传输策略。具体来说,HDFS 会尽量将文件的副本存储在不同的机架上,以防止单个机架故障导致数据丢失[^2]。 #### 4. 存储策略 HDFS 提供了灵活的存储策略,允许用户根据需求选择不同的存储方式。例如,可以通过 `hdfs storagepolicies` 命令设置特定路径的存储策略,从而优化存储成本和性能[^4]。 ```bash # 查看支持的存储策略 hdfs storagepolicies -listPolicies # 设置路径的存储策略 hdfs storagepolicies -setStoragePolicy -path /user/data -policy HOT ``` #### 5. 元数据管理 NameNode 使用两个主要文件来管理元数据: - **fsimage**:命名空间镜像文件,包含文件系统元数据的完整快照。 - **edits**:编辑日志文件,记录自上次检查点以来的所有更改。 当 NameNode 启动时,它会加载 fsimage 文件并应用 edits 日志中的更改,从而恢复文件系统的状态。 --- ### 示例代码:查看 fsimage 文件内容 以下是使用 Hadoop 提供的工具查看 fsimage 文件内容的示例命令: ```bash hdfs oiv -i fsimage_0000000000000000052 -o ~/fs52.xml -p XML ``` 该命令将 fsimage 文件转换为 XML 格式,便于分析文件系统的元数据结构。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值