Hadoop分布式文件系统(HDFS)是一种分布式文件系统,用于在商品硬件上运行。它与现有的分布式文件系统有很多相似之处。然而,与其他分布式文件系统的区别很大。HDFS具有高度的容错能力,旨在部署在低成本的硬件上。HDFS提供对应用程序数据的高吞吐量访问,适用于具有大数据集的应用程序。HDFS放宽了一些POSIX要求,以便对文件系统数据进行流式访问。HDFS最初是作为Apache Nutch网页搜索引擎项目的基础设施构建的。HDFS现在是一个Apache Hadoop子项目。项目URL为http://hadoop.apache.org/hdfs/

enter image description here
NameNodeDataNodes
HDFS具有主/从结构。HDFS集群由单个NameNode组成,一个主服务器,用于管理文件系统命名空间,并调节客户端对文件的访问。
此外,还有一些DataNodes,通常是集群中每个节点的一个,它们管理连接到运行的节点的存储。HDFS公开了文件系统命名空间,并允许将用户数据存储在文件中。
在内部,文件被分割成一个或多个块,这些块被存储在一组数据节点中。
NameNode执行文件系统命名空间操作,如打开,关闭和重命名文件和目录。它还确定块到DataNodes的映射。DataNodes负责从文件系统的客户端提供读取和写入请求。

fsimage (文件系统镜像):元数据镜像文件。存储某一时段NameNode内存 元数据信息。
edits: 操作日志文件。
fstime: 保存最近一次checkpoint的时间

NameNode

1、NameNode主要功能:接受客户的的读写服务
2、NameNode保存metadata信息包括:
1).文件owership和permissions
2).文件包含哪些块
3).block保存在哪个DataNode(由DataNode启动时上报给NameNode)
3、NameNode的metadata信息在启动时会加载到内存
1).metadata存储到磁盘文件名为fsimage
2).Block的位置信息不会保存到fsimage
3).edits记录对metadata的操作日志

在HDFS读操作

enter image description here

1客户端启动通过调用文件系统对象的 open() 方法读取请求
2此对象使用 RPC 连接到 namenode 并获取的元数据信息,如该文件的块的位置
3响应元数据请求,返回 DataNodes 地址
4接收到 DataNodes 的地址,FSDataInputStream对象被返回到客户端
5客户端多次调用read()
6一旦到模块的结尾,DFSInputStream 关闭连接,移动定位到下一个 DataNode 的下一个块
7读取完成调用 close()方法。

HDFS写操作

enter image description here

1、根namenode通信请求上传文件,namenode检查目标文件是否已存在,父目录是否存在
2、namenode返回是否可以上传
3、client会先对文件进行切分,比如一个blok块128m,文件有300m就会被切分成3个块,一个128M、一个128M、一个44M请求第一个 block该传输到哪些datanode服务器上
4、namenode返回datanode的服务器
5、client请求一台datanode上传数据(本质上是一个RPC调用,建立pipeline),第一个datanode收到请求会继续调用第二个datanode,然后第二个调用第三个datanode,将整个pipeline建立完成,逐级返回客户端
6、client开始往A上传第一个block(先从磁盘读取数据放到一个本地内存缓存),以packet为单位(一个packet为64kb),当然在写入的时候datanode会进行数据校验,它并不是通过一个packet进行一次校验而是以chunk为单位进行校验(512byte),第一台datanode收到一个packet就会传给第二台,第二台传给第三台;第一台每传一个packet会放入一个应答队列等待应答
7、当一个block传输完成之后,client再次请求namenode上传第二个block的服务器。

Secondary NameNode节点的工作流程:

enter image description here
1)、定期的通过远程方法获取NameNode节点上编辑日志(edits)的大小;
2)、如果NameNode节点上编辑日很小,就不需要合并NameNode上的fsimage文件和编辑日志;
3)、通过远程接口启动一次检查点过程,这时名字节点NameNode需要创建一个新的编辑日志文件edits.new,后续对文件系统的任何修改都记录到这个新编辑日志里;
4)、SecondNameNode点将Namenode上的fsimage文件和原编辑日志下载到本地,并在内存中合并,合并的结果输出为fsimage.ckpt;
5)、再次发起请求通知NameNode节点数据(fsimage.ckpt)已准备好,然后NameNode节点会下载fsimage.ckpt(并替换掉原来的fsimage);
6)、NameNode下载结束后,Secondary NameNode会通过远程调用(NameNodeProtocol.rollFsImage())完成这次检查点,NameNode在响应该远程调用时,会用fsimage.ckpt覆盖原来的fsimage文件,形成新的命名空间镜像,同时将新的编辑日志edits.new改名为edits。