HDFS的数据结构

作为管理员,深入了解namenode、secondary namenode和datanode等HDFS组件如何在磁盘上组织永久性数据非常重要。洞悉各文件的用法有助于进行故障诊断和故障检出。

一、namenode的目录结构

运行中的namenode有如下目录结果:

${dfs.namenode.name.dir}/
|–current
| |–VERSION
| |–edits_000000000000000000001-000000000000000000019
| |–edits_inprogress-000000000000000000020
| |–fsimage_000000000000000000000
| |–fsimage_000000000000000000000.md5
| |–fsimage_000000000000000000019
| |–fsimage_000000000000000000019.md5
| |–seen_txid
|–in_use.lock

dfs.namenode.name.dir属性描述了一组目录,各个目录存储着镜像内容。该机制使系统具备了一定的复原能力,特别是当其中一个目录是NFS的一个挂载时(推荐配置)。下面分别说明namenode各目录结构的功能:

1、VERSION

VERSION文件是一个java属性文件,其中包含正在运行的HDFS版本信息。该文件一般包含以下内容:

namespaceID=90522394
clusterID=CID-71ed8f31-3100-47bf-8dd2-de32b3710122
cTime=0
storageType=NAME_NODE
blockpoolID=BP-1586979323-10.200.4.117-1554279471989
layoutVersion=-60

namespaceID:文件系统命名空间的唯一标识符,是在namenode首次格式化时创建的。

clusterID:将HDFS集群作为一个整体赋予的唯一标识符,对于联邦HDFS非常重要,这是一个集群有多个命名空间祖晨个,且每个命名空间由一个namenode管理。

cTime:标记了namenode存储系统的创建时间。对于刚格式化的存储系统,此属性值为0;在文件系统升级后,该值会更新。

storageType:说明该存储目录包含的是namenode的数据结构。

blockpoolID:数据块池的唯一标识符,数据块池中包含了由一个namenode管理的命名空间中的所有文件。

layoutVersion:是一个负整数,描述HDFS持久性数据结构(也称布局)的版本,但该版本号与Hadoop发行包的版本号无关。只有布局变更,版本号便会递减,此时,HDFS也需升级。否则,磁盘仍然使用旧版本的布局,新版本的namenode(或datanode)就无法正常工作。

2、in_use.lock

锁文件,namenode使用该文件为存储目录加锁。可以避免其他namenode实例同时使用(可能会破坏)同一个存储目录的情况。

3、文件系统映像(fsimage开头的文件)

每个fsimage文件都是文件系统元数据的一个完整的永久性检查点。并非每一个写操作都会更新该文件,因为fsimage是一个大型文件(甚至可高达几个GB),如果频繁地执行写操作,会使系统运行极为缓慢。但这个特性根本不会降低系统的恢复能力,因为如果namenode发生故障,最近的fsimage文件将被载入到内存以重构元数据的最近状态,再从相关点开始向前执行编辑日志中记录的每个事务。事实上,namenode在启动阶段正是这样做的。

4、编辑日志(edits开头的文件)

文件系统客户端执行写操作时(例如创建或移动文件),这些事务首先被记录到编辑日志中。namenode在内存中维护文件系统的元数据;当编辑日志被修改时,相关元数据信息也同步更新。内存中的元数据可支持客户端的读请求。

编辑日志在概念上是单个实体,但是它体现为磁盘上的多个文件。每个文件称为一个“段”(segment),名称由前缀edits及后缀组成,后缀指示出该文件所包含的事务ID。任一时刻只有一个文件处于打开可写状态(前面例子中的edits_inprogress-000000000000000000020),在每个事务完成之后,且在向客户端发送成功代码之前,文件都需要更新和同步。当namenode向多个目录写数据时,只有在所有写操作更新并同步到每个副本之后方可返回成功代码,以确保任何事务都不会因为机器故障而丢失。

5、seen_txid

存放transactionId的文件,format之后是0,它代表的是namenode里面的edits_文件的尾数。namenode重启的时候,会按照seen_txid的数字, 循序从头跑edits_0000001~到seen_txid的数字。所以当hdfs发生异常重启的时候,一定要比对seen_txid内的数字是不是edits最后的尾数(就是edits_inprogress_000000000 后边的那串数字,inprogress就是正在使用的edits文件),不然会发生建置namenode时metaData的资料有缺失。

二、datanode的目录结构

和namenode不同的是,datanode的存储目录是初始阶段自动创建的,不需要额外格式化。datanode的关键文件和目录如下:

${dfs.datanode.data.dir}/
|–current
| |–BP-1586979323-10.200.4.117-1554279471989
| | |–current
| | |–VERSION
| | |–finalized
| | | |–subdir0
| | | |–subdir0
| | | |–blk_1073741828
| | | |–blk_1073741828_1004.meta
| | | |–blk_1073741837
| | | |–blk_1073741837_1013.meta
| | |–rbw
| |–VERSION
|–in_use.lock

HDFS数据块存储在blk_为前缀名文件中,文件名包含了该文件存储的块的原始字节数。每个块有一个相关联的带有.meta后缀的元数据文件。元数据文件包括头部(含版本和类型信息)和该块各区段的一系列的校验和。

每个块属于一个数据块池,每个数据块池都有自己的存储目录,目录根据数据块池ID形成(和namenode的VERSION文件中的数据块池ID相同)。

当目录中数据块的数量增加到一定规模时,datanode会创建一个子目录来存放新的数据块及其元数据信息。如果当前目录已经存储了64个(通过dfs.datanode.numblocks属性设置)数据块时,就创建一个子目录。终极目标是设计一颗高扇出的目录树,即使文件系统中的快数量非常多,目录树的层数也不多。通过这种方式,datanode可以有效管理各个目录中的文件,避免大多数操作系统遇到的管理难题,即很多(成千上万个)文件放在同一个目录之中。

如果dfs.datanode.data.dir属性指定了不同磁盘上的多个目录,那么数据块会以轮转(round-robin)的方式写到各个目录中。注意,同一个datanode上的每个磁盘上的块不会重复,只有不同datanode之间的块才有可能重复。

完毕。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值