HDFS文件系统学习

1、HDFS简介:

HDFS(Hadoop Distributed File System )Hadoop分布式文件系统。是根据google发表的论文GFS(Google File System)Google 文件系统翻版的。是一个主/从(Master/Slave)架构的系统,它主要由NameNode、DataNode、SecondaryNameNode、事务日志、映像文件等构成。SecondaryNameNode是NameNode的备份。客户端联系NameNode后,取得文件的元数据,真正数据读写发生在客户端与DataNode之间

2、HDFS特点 :

  • 廉价且稳定: 运行在普通商用零件所搭建的集群上,采用数据块多副本机制。把数据分成64m的数据块,并制作3个备份,一份放在一个机架内的本地节点上,另一份放在同一机架的另一节点上,第三份放在另一机架的节点上。当数据块副本<3,系统的错误检测与自动恢复技术会自动把数据块的副本数恢复到正常水平。

  • 高吞吐量的文件系统: HDFS对文件采取流式读取批量处理的方式,而不是交互式的读写方式。Hadoop应用对文件实行一次写入,多次读取的访问方式。文件一经创建就不再进行修改。

  • 超大文件支持:采用数据块来存储数据。HDFS中的文件被划分为块大小的多个分块作为独立的存储单元。这样文件的大小可以大于网络中任意一个磁盘的容量。文件所有块并不需要存储在同一个磁盘上,因此可以用集群上任意一个磁盘进行存储。

  • 简单一致性的文件系统:Hadoop的HDFS文件系统采用一次写入多次读取的模式,文件内容一经写入就不再更改。这样就将数据一致性问题给解决了。

  • 流式数据访问方式: 数据以流式读取为主而不是交互地随机读取,提高了文件系统的吞吐量
    不适合使用HDFS的场景:
    1.低时间延迟的数据访问:HDFS是为 高数据吞吐量优化的,可能以高时间延迟为代价
    2.大量的小文件 :每个文件、目录和数据块的存储信息大约占150字节。大量小文件会占据很多的内存空间。
    3.多用户写入任意修改文件:HDFS文件只能有一个writter,且写操作总是将数据添加到文尾,因此不支持多个写者的写入操作。也不支持在文件任意位置进行修改

3、HDFS组成:

  • NameNode:管理节点,管理文件系统命名空间,记录每个数据块在DataNode上的位置和副本信息。协调客户端对文件的访问,记录命名空间内的改动和空间本身属性的波动

  • DataNode: 保存数据的节点,负责在物理节点的存储管理,一次写入多次读取。文件由数据块组成,默认块大小是64M,数据块与冗余备份的形式分布在不同机架的不同机器上,定期向NameNode提供其保存的数据块的列表,以便于客户端在读取文件元数据后直接在DataNode上读写

  • SecondaryNameNode: 运行在单独的计算机上,定期从NameNode节点获取数据,形成NameNode的备份,当NameNode出现问题,SeconderyNameNode便可以顶替NameNode  

  • 客户端:集群的使用者,通过HDFS的shell和api对系统中的文件进行操作

  • 机架:容纳组成集群的普通商用计算机(节点)的架子,各节点被分到不同的机架内。方便管理和施工,也为了防灾容错的需要。一般来说,一个机架内的节点之间数据传输效率要快,而不同机架内的节点间数据传输率要慢一点

  • 数据块:默认64m,数据块是Hadoop处理数据的最小单位,根据Hadoop数据管理的策略。数据块放置在不同数据节点(DataNode)中,当数据块的副本数小于规定的份数时,Hadoop系统的错误检测与自动恢复技术就会自动把数据块的副本数恢复到正常水平

4、元数据及其备份机制

  • 第一种机制:当namenode启动时,从磁盘中读取fsimage(保存文件块的映射和文件系统的配置信息)和EditsLog(事务日志)文件,将新的元数据刷新到磁盘上,生成新的fsimage文件,至此EditsLog文件中的事务日志已经被处理并持久化到fsimage中。这个过程叫检查点。发生在NameNode启动时

  • 第二种机制:SecondaryNameNode周期性从NameNode处获取EditsLog日志文件,并把日志合并到fsimage文件中,然后清空EditsLog文件。NameNode启动时就会加载新的fsimage文件,并创建一个新的EditsLog文件记录对HDFS的操作。
    过程如下:
    (1) SecondryNameNode通知NameNode生成新的日志文件,以后的日志都会被存放在新的日志文件
    (2) SecondryNameNode 用GET的方式从NameNode节点获得fsimage文件及旧的日志文件
    (3)SecondryNameNode将fsimage映像文件加载到内存中,并执行日志文件中的所有操作,然后生成新的fsimage文件
    (4)SecondryNameNode节点用POST方式把新的fsimage文件传回NameNode
    (5)NameNode中的fsimage保存了最新的checkPoint的元数据信息,日志文件也重新开始。周期性更换日志因此日志不会太大

5、数据块备份机制

  • 备份规则:每个数据块默认复制3份,第一份副本放在机架1的一个DataNode节点上,第二份副本放在同一个机架的另一个DataNode节点上,第三份副本放在机架2的另一个DataNode节点上。访问文件时优先在本地机架中找到该文件下的数据块,如果这个机架出现异常,则可以到另外的机架上找到这个数据块的副本,这样保证了数据的安全可靠。

  • 备份过程: 例如要将数据块2存入到3个DataNode,它们分别是D1,D2,D5. 过程如下:
    (1)、客户端会与DataNode1联系,将Block2存入D1,D1完成后向NameNode报告自己已经写入
    (2)、D1将数据块传给D2,D2完成数据写入向NameNode发送已写入的报告,并将数据传给D5
    (3)、D5将Block2保存,然后向NameNode报告自己已完成数据块写入工作

6、数据读取过程


- (1)客户端生成一个HDFS类库中的DistributedFileSystem对象实例,并使用此实例的open()方法打开一个文件
- (2)DistributedFileSystem通过RPC向NameNode发出一个请求,获得文件相关的数据块位置信息,NameNode将包含此文件相关数据快所在的DataNode地址,经过与客户端相关的距离进行排序后,返回给DistributedFileSystem
- (3) DistributedFileSystem获得信息后,生成一个FSDataInputStream 对象实例返回给客户端,此实例封装一个DFSInputStream对象,负责存储数据块信息和DataNode地址信息,并负责后续文件内容读取工作。
- (4)客户端向FsDataInputStream发出读取数据的read()调用。
- (5) 收到read()请求后,FsDataInputStream封装的DFSInputStream选择与第一个数据块最近的DataNode,并读取相应的数据信息返回给客户端,在数据块读取完成后,DFSInputStream负责关闭到相应DataNode的链接
- (6) DFSInputStream将继续选择后续数据快的最近DataNode节点。并读取数据返回给客户端,直到最后一个数据块读取完成
- (7) 客户端读取完所有的数据块之后,调用DFSInputStream的close()接口关闭这个文件。
在DFSInputStream从DataNode读取数据的过程中,如果遇到某个DataNode宕机情况下,DFSInputStream会选择下一个包含此数据最近的DataNode,以后读取也不会再连接这个宕机的DataNode

7、数据写入过程


- (1)使用HDFS提供的客户端开发库中的DistributedFileSystem对象的creat()方法创建一个文件
- (2)DistributedFileSystem通过RPC向NameNode发出创建文件的请求,NameNode会检查该文件是否存在及用户是否有权限进行操作。检查成功后则在命名空间中创建此文件的对应记录,否则会抛出IOException异常
- (3) DistributedFileSystem生成一个FSDataOutputStream 对象实例,此实例封装了一个DFSOutputStream对象,负责后续文件的写入操作。
- (4)客户端向FSDataInputStream发出写入数据的write()调用,写入数据。DFSOutPutStream在收到数据后将数据拆分成多个Block,放入 一个队列中
- (5) DataStreammer负责从数据队列中不断取出数据,准备写入DataNode中。在此之前,DataStreammer需要从NameNode请求分配一些存放数据的数据块信息及适合存储数据块的DataNode地址。
- (6) 对每个数据块。NameNode会分配若干个DataNode以复制存储数据块。这个写入过程是以管道的形式将数据块写入所有DataNode。例如,要把Block2写入三个DataNode,DataStreamer会将Block2写入到第一个DataNode,该DataNode把Block2存储后,再将其传递给下一个DataNode,直到最后一个DataNode。
- (7) 每个DataNode存储数据后,会向DataStreamer报告已经完成数据存储任务,同时向NameNode报告自己完成了一个数据块的写入操作。循环执行步骤6与步骤7直至写完所有数据块
- (8) 写完所有数据块后,客户端调用FSDataInputStream的close()方法结束写入操作
数据写入过程中,如果某个DataNode出现故障,DataStreamer将关闭到此节点的链接,故障节点将从DataNode链中删除,其他DataNode继续完成写入操作。NameNode如果发现没有某个DataNode没有完成写入任务,会分配另一个DataNode完成此写入操作。对某个数据块来说,只要有一个DataNode写入成功,就视为写入成功,后续将启动自动恢复机制,恢复到指定的副本数

猜你喜欢

转载自blog.csdn.net/phn_csdn/article/details/70902769