HDFS从敲门到入门
01、解决的问题
当数据量多到一台机器无法存储时,我们就需要多台机器一起存储或者在一台机器上增加磁盘。而多台机器存储,可以提供并行读写,相比于在单台机器上加磁盘的方式更有效率。
02、定义
HDFS,全称Hadoop Distributed File System,是一种分布式文件系统。
除了能够提供大量数据的存储,提高大数据读写效率外,HDFS还解决了由于分布式带来的相关问题,如节点故障的处理、保证数据的一致性等。
03、存储方式
HDFS中的存储单位为数据块,默认大小为128MB,存储的文件可以分为多个数据块。
HDFS通过NameNode和DataNode(管理节点-运行节点)的模式完成文件系统的管理和运行。
3.1 NameNode
NameNode作为管理节点,负责管理整个文件系统的命名空间,记录整个HDFS的文件目录树及其目录和文件。这些信息以文件的形式存储于磁盘上。他包括两个文件:
Fsimage:保存了最新的元数据检查点;
editLog:保存了自最新的元数据检查点之后的命名空间变化记录。
为了防止editLog文件过大,HDFS会定期合并Fsimage和editLog形成新的Fsimage文件,然后重新记录editLog。
1)Fsimage 镜像文件
Fsimage是一个二进制文件,他记录了HDFS中所有目录和文件的元数据信息,他的结构如下:
其中,
第一行是HDFS的文件元数据信息;
第二行是目录元数据信息;
第三行是文件元数据信息;
字段含义如下:
imgVersion:当前Fsimage文件的版本号;
nameSpaceID:当前命名空间的ID,在NameNode的生命周期内保持不变,DataNode注册时,返回该ID作为其注册ID,每次和NameNode通信时都要检查,不认识的nameSpaceID拒绝链接;
numFiles:文件系统中的文件数;
genStamp:生成该Fsimage的时间戳;
第二行与第三行的部分字段重复,这里将重复的部分一并说明;
Path:目录(第二行)或文件(第三行)的路径;
replicas:文件的副本数,目录的replicas为0;
mtime:修改时间;
atime:访问时间;(访问是啥?最后一次的访问时间么?)
blocksiz:文件块size,目录的size为0;
numBlock:文件包含的数据块数量,目录的为-1;
nsQuota:目录的命名空间大小配额,默认为-1;?
dsQuota:目录的磁盘大小配额,默认为-1;
username:目录或文件所属的用户名;
group:用户所属的组名;
prem:即permission,访问权限;
blockid:文件块id;
numBytes:该文件块的bytes,即文件块的大小;
genStamp:该文件块的时间戳。
那么怎么在fsimage中保存根目录呢?path的length为0,即表示这个目录为根目录。
NameNode将这些信息读入内存之后,构造一个文件目录结构树,将表示文件或目录的节点填入到结构中。
2)BlocksMap
从Fsiamge的数据字段中可以看出,Fsiamge中并没有存储Block文件块与DataNode之间的对应关系。而NameNode要管理整个文件系统,则需要知道目录下的文件块实际上存储在哪里,这个就需要通过BlocksMap来实现。
文件块与DataNode之间的映射关系并不是固定存储于磁盘之上,而是DataNode在启动或运行过程中,将本DataNode上保存的文件块信息通过BlockReport汇报给NameNode,NameNode会将接收到的映射信息保存在内存中一个叫做BlocksMap的数据结构中。
BlocksMap数据结构
BlocksMap是Block对象对BlockInfo对象的一个Map表,其中Block对象只记录了BlockID、大小和时间戳信息,这些在Fsimage中都有。BlockInfo是从Block对象继承而来,除了Block对象的信息之外,还包括代表该Block所属的HDFS文件的INodeFile对象引用和该Block所属的DataNode列表信息,列表保存在一个Object[]数组中。
上图表示一个Block包括三个副本,分别放置在DN1,DN2和DN3三个DataNode上,每个DataNode对应一个三元组,该三元组中第二个元素Prev(Prev Block)指的是该Block在DataNode上的前一个BlockInfo引用。第三个元素Next(Next Block)指的是该Block在DataNode上的下一个BlockInfo引用。每个Block有多少个副本,其对应的BlockInfo对象中就有多少个这样的三元素。
但在NameNode加载Fsimage之后,BlocksMap中文件块与DataNode的映射关系还未建立,这需要DataNode节点进行BlockReport。当所有的DataNode上报处理完毕后,BlocksMap构建完成,这时候NameNode才构建起完整的命名空间。
3)editLog 编辑日志
editLog记录检查点CheckPoint之后发生的用户对HDFS的操作行为。这样就可以保证,不是每次对HDFS作出操作后,都要修改Fsiamge文件。
当NameNode节点发生故障,需要重新启动备份的NameNode节点时,我们就可以根据在检查点CheckPoint合并保存生成的Fsimage文件和之后记录的editLog文件来重新启动一个新的NameNode节点。
当然了,由于从零开始重新冷启动一个NameNode节点需要读取Fsimage文件、editLog文件,并且还要等待DataNode节点进行BlockReport,在数据量较大的时候这是十分费时的,因此大家一般通过双机热备份来保证系统的高可用性。
3.2 DataNode
DataNode是HDFS中实际数据的存储位置。
04、特性
4.1 块缓存
高频率使用的数据,可以存放在快缓存中,以支持频繁的读取和运算;
4.2 联邦HDFS
随着分布式文件系统的扩大,针对所有数据块的读写都需要依赖NameNode的处理能力,这使得NameNode处理能力和内存(NameNode内存中保存着所有Block与DataNode的映射关系)可能成为HDFS的瓶颈。HDFS支持多NameNode负责管理命名空间下不同的文件目录,以提高NameNode的处理能力。
4.3 高可用性
由于NameNode存储了文件系统的所有元数据信息,如果他出现故障或者数据丢失,会导致整个文件系统无法使用,因此,一般会通过NameNode备份的方式避免单点故障。
但由于冷启动NameNode节点时间较长,为了保证用户使用的连续性和体验,一般会通过双机热备份的方式保证系统稳定。
双机热备份,即同时运行两个NameNode,DataNode在运行过程中,同时向两个NameNode汇报数据,当一个出现问题时,可无缝切换,让用户没有感知。
05、延伸内容
5.1 文件系统
文件系统是操作系统提供的磁盘空间管理服务,作为一个文件系统,主要的操作就是:读取文件、新建目录、移动文件、删除数据、列出目录。
5.2 HDFS元数据
1)HDFS元数据
如上面所述,HDFS的NameNode节点中存储着HDFS这个分布式文件系统的目录结构树,以及其中的目录和文件,是整个文件系统的元数据管理者,这些元数据包括:
文件、目录自身的属性信息,例如文件名、目录名、修改信息等;
文件记录的信息的存储相关信息,例如存储块信息、副本个数等;
记录HDFS中DataNode的信息,用户DataNode的管理;
他们在NameNode的内存中有一个树形结构来存储,同时也通过硬盘中Fsiamge和editLog两个文件进行存储、备份,以防机器挂掉后,内存数据丢失。
2)文件元数据 FileStatus
任何文件系统都需要提供目录浏览和文件、目录的检索相关功能,HDFS作为一个分布式文件存储系统也不例外。
HDFS中的FileStatus对象封装了文件系统中文件和目录的元数据,包括文件的长度、块大小、备份数、修改时间、所有者以及权限等信息。
FileStatus对象由FileSystem的getFileStatus()方法获得,调用该办法的时候要把文件的Path传进去。
例如:
文件路径:
hdfs://master:9000/user/hadoop/aa.mp4
块的大小:67108864
文件所有者:hadoop:supergroup
文件权限:rw-r--r--
文件长度:76805248
备份数:3
修改时间:1371484526483
5.3 读写流程:文件输入流与文件输出流
输入流,是指硬盘上的文件内容流入到程序中可以存储数据的东西中,比方说数组,用Read方法;
输出流,是指程序中的数组或者其他可以存储数据的东西中的内容输出到硬盘文件中,用Write方法。
按照传输的数据可以划分为字节流和字符流:
字节流:二进制,可以是一切文件,包括纯文本、音频、视频等;
字符流:文本文件,只能处理纯文本。