HDFS结构解释

HDFS是一个典型的Client/Server架构,主要是由一个NameNode,一个secondaryNameNode,一个或多个DataNode组成。NameNode是整个文件系统的控制中枢,它管理并维护着整个文件系统树以及整个系统树中所有的文件和目录,同时负责接收处理客户端的请求及管理和分配具体的存储任务。Namenode管理的这些元数据信息以两个文件的形式持久化的保存在本地磁盘上:命名空间镜像文件FsImage和编辑日志文件EditLog. Namenode每次启动都会首先加载FsImage文件,然后重做EditLog中记录的操作,最后将FsImage重新持久化到本地磁盘,并清空EditLog文件。Namenode会周期性的做checkpoint,周期性的合并FsImage文件和EditLog文件,FsImage中总是记录最后一次checkpoint之后文件系统的元数据,EditLog记录上次checkpoint到下次checkpoint之间的操作。Namenode还记录着每个文件所对应的各个块所在的Datanode信息,但是不同的是,这些信息是不会被持久化保存的,这些信息都是在系统启动时由Datanode节点汇报后在Namenode内存中构建的。SecondaryNamenode作为Namenode的备份节点,它会周期性的从Namenode中获取FsImage文件和EditLog文件,然后在内存中对这两个文件进行合并,合并之后的新的FsImage文件被传回并代替旧的FsImage文件,而新的EditLog则是在SecondaryNamenode获取FsImage和EditLog之后新建的空EditLog文件,这样一方面保证了EditLog文件不会太大,减少了系统重新启动时间,另一方面SecondaryNamenode对Namenode中的命名空间镜像文件做了备份,增强了Namenode的容错能力。Datanode是文件系统中真正存储数据的地方,它负责数据块的存储和检索,并周期性的以心跳包的形式向Namenode汇报它持有的块的列表。文件以数据块的形式存储在Datanode之上,通常数据块都会以冗余的方式备份到其他Datanode上,默认的备份数是3份,此参数可以根据集群的大小进行设置。HDFS的读写原理与单一磁盘上的文件系统相似,HDFS采用数据块作为文件存储的基本单位,但是数据块大的多,默认的块大小是64MB,HDFS上的文件如果超过一个快的大小会被划分成多个分块,如果文件大小没有超过一个快的大小,该文件也不会占据整个快的空间。HDFS采用流式数据访问方式存取数据,每次都是针对一个完整快的读或写操作。读文件流程客户端在对数据进行读写时,先与Namenode进行通信,获取要读写数据块所在的Datanode位置,然后客户端直接与Datanode进行交互,完成数据块的读写。客户端在读取文件时,首先通过FileSystem的open函数发出打开文件请求,Distributed FilesSystem通过RPC协议将该请求发送给Namenode,获得存放文件的数据块信息,对于每一个数据块,Namenode都会返回所有保存数据块的Datanode的地址,客户端会从网络拓扑最近的那个Datanode中读取数据块。 Distributed FileSystem会将从选出的最近的Datanode上打开一个FSDataInputStream并返回给客户端,用来读取数据。客户端通过调用FSDataInputStream的read函数开始读取数据,档次数据读取完毕后,关闭此流与Datanode的连接,然后连接此文件下一个数据块的最近Datanode,然后进行读取。当客户端读取完毕数据后,调用FSDataInputStream的close函数,关闭该流。写文件流程客户端在写文件时,首先通过FileSystem的create函数发出创建文件请求,Distributed FileSystem通过RPC协议将该请求发送给Namenode,在文件系统的命名空间中创建一个新的文件,Distributed FileSystem返回DFSOutputStream给客户端,用于写数据,DFSOutputStream将数据分成块,写入Data Queue,之后由Data Streamer读取,然后通知Namenode节点分配Datanode,用来存储数据块,每块默认备份3块,被分配的Datanode放到一个pipeline里面。Data Streamer将数据块写入pipeline中的第一个数据节点,第一个Datanode将数据块发送到第二个Datanode,第二个Datanode将数据块发送给第三个Datanode。DFSOutputStream将已经发送出去的数据块保存在ack queue,等待pipeline中的Datanode告知数据是否写入成功。如果数据在写入Datanode的过程中失败,则首先关闭pipeline,将ack queue中的数据块放入data queue的开始,当前正在写入的Datanode被Namenode标示,失效的Datanode在重启后能察觉到该数据块是过时的,会删除该数据块,而失效的Datanode会从pipeline中移除,data queue中剩余的数据块会写入pipeline中的另外两个Datanode中。在写入完毕后close FSDataInputStream,并通知Namenode写入完毕。

原文地址:https://www.cnblogs.com/dyllove98/p/3132865.html