HDFS 读写流程概要

1、节点介绍

(1)、NameNode管理文件系统的命名空间,维护文件系统树及整棵树内所有的文件和目录,以两个文件形式永久保存在本地磁盘上:命名空间镜像文件fsimage 和 编辑日志文件edits。namenode也记录每个文件中各个块所在的数据节点信息。

(2)、DataNode是文件系统的工作节点,根据需要存储并检索数据块,并定期向namenode发送它们所存储的块的列表。

(3)、SecondaryNameNode定期通过编辑日志edits合并空间镜像文件 fsimage,防止edits过大。


2、客户端读取HDFS流程

(1)、打开分布式文件:调用 分布式文件DistributedFileSystem.open()方法
 
(2)、从 NameNode 获得 DataNode地址:DistributedFileSystem 使用 RPC 调用 NameNode,NameNode返回存有该副本的 DataNode 地址,DistributedFileSystem 返回一个输入流FSDataInputStream对象,该对象封存了输入流 DFSInputStream
 
(3)、链接到DataNode 调用 输入流FSDataInputStream 的 read()方法,从而 输入流 DFSInputStream 连接DataNode

(4)、读取DataNode:反复调用 read()方法,从而将数据从DataNode 传输到客户端

(5)、读取另外的DataNode直到完成:到达块的末端时候,输入流DFSInputStream 关闭与DataNode 连接,寻找下一个 DataNode

(6)、完成读取,关闭连接:即调用输入流 FSDataInputStream.close().

3、文件写入流程

(1)、发送创建文件请求:调用 分布式文件系统DistributedFileSystem.create()方法

(2)、NameNode中创建文件记录:分布式文件系统DistributedFileSystem 发送 RPC请求给namenode,namenode 检查权限后创建一条记录,返回输出流 FSDataOutputStream,封装了输出流DFSOutputDtream

(3)、客户端写入数据:输出流 DFSOutputDtream将数据分成一个个的数据包,并写入内部队列。DataStreamer 根据 DataNode 列表来要求namenode 分配适合的新块来存储数据备份。一组DataNode 构成管线(管线的DataNode 之间使用 Socket 流式通信)

(4)、使用管线传输数据:DataStreamer 将数据包流式传输到管线第一个DataNode,第一个DataNode再传到第二个DataNode ,直到完成。

(5)、确认队列:DataNode收到数据后发送确认,管线的DataNode所有的确认组成一个确认队列。所有DataNode 都确认,管线数据包删除。

(6)、关闭:客户端对数据量调用close()方法。将剩余所有数据写入DataNode管线,并联系NameNode且发送文件写入完成信息之前等待确认。

(7).NameNode确认。

(8)、故障处理:若过程中发生故障,则先关闭管线,把队列中所有数据包添加回去队列,确保数据包不漏。为另一个正常DataNode的当前数据块指定一个新的标识,并将该标识传送给NameNode,一遍故障DataNode在恢复后删除上面的不完整数据块. 从管线中删除故障DataNode并把余下的数据块写入余下正常的DataNode。NameNode发现复本两不足时,会在另一个节点创建一个新的复本。

4、SecondaryNameNode合并过程

(1). SecondaryNameNode 请求 NameNode 停止使用edits。
(2). SecondaryNameNode 通过 HTTP GET从 NameNode获取 fsimage 和 edits
(3). SecondaryNameNode将 fsimage和 edits 载入内存,合并成新的 fsimage 
(4). SecondaryNameNode 通过 HTTP POST发送 fsimage 
(5). Name使用新的 fsimage 替代旧的