本文章主题:
- 写流程
- 读流程
HDFS遵循一次写入多次读取的原则,因此已经写入文件系统的文件是无法修改的,只能进行删除,添加,读取操作。
-
写流程
- 客户端调用DistributedFileSystem的Create()方法来创建一个新文件,DistributedFileSystem通过RPC向NameNode申请写入新文件;
-
NameNode通过对文件的权限以及文件是否已存在进行校验,校验通过则返回具体blockId以及DataNode列表给DistributedFileSystem,并在日志文件中追加记录。否则返回失败信息;
-
DistributedFileSystem返回给客户端一个FSDataOutputStream对象,供客户端进行写操作。FSDataOutputStream对象中封装了一个
DFSOutputStream
对象,管理着NameNode与DataNode之间的通信; -
客户端调用FSDataOutputStream对象的write()方法开始写入数据,
DFSOutputStream
对象将数据分成一个个数据包(package)并写入“数据队列”(data queue) ; -
DataStreamer根据DataNode列表要求NameNode分配合适的新块来处理数据复本;
-
这组DataNode组成一条管线,假如复本数为3,则这条管线就拥有3个复本。-- DataStreamer将数据包流式传输到管线中的第1个DataNode中,DataNode存储数据并将数据包传输给第2个,以此类推直至传输到管线中的最后一个节点;
-
DFSOutputStream
同时维护着一个“确认队列”(ack queue) 来等待DataNode存储成功的确认回执,数据包从最后一个节点依次往前传递,DFSOutputStream
收到所有确认信息之后,则删除数据包; -
客户端完成数据的写入之后,调用close()方法,关闭FSDataOutputStream;
-
DistributedFileSystem通知NameNode文件写入成功,NameNode同时将元数据写入内存;
-
写过程故障处理:
- 关闭管线,将数据包添加回数据队列的最前端,以确保下游的DataNode不会漏掉任何一个数据包;
- 找到一个存储着当前数据块的DataNode(正常的),为它加上一个新的标识,并且将该标识传送给NameNode,便于在故障DataNode在恢复之后可以删除存储的部分数据块;
- 从管线中删除故障节点,并且将数据块写入另外两个正常节点;
- 当NameNode发现block复本数不足的时候,会在另外一个节点上创建一个新复本。
-
读流程
- 客户端调用DistributedFileSystem的open()方法,告诉分布式文件系统对象(DistributedFileSystem)希望打开某个文件;
- DistributedFileSystem通过RPC来调用NameNode节点,并从中获取block文件块的在datanode地址;
- DistributedFileSystem将位置信息封装成FSDataInputStream对象返回给客户端,FSDataInputStream对象中封装了一个
DFSInputStream
对象,它管理着DataNode与NameNode之间的I/O; - 客户端调用FSDataInputStream对象的read()方法,
DFSInputStream
对象随即连接最近的DataNode,通过反复调用read()方法,将数据从DataNode传输给客户端; - 当客户端将所有的数据块读取完成,调用FSDataInputStream的close()方法,关闭数据流;
- 在读取过程中出错,
DFSInputStream
会尝试读取临近DataNode中的block; - 在每读完一个block,
DFSInputStream
都会检验数据的完整性,如果有损坏,会试图在从其它DataNode读取复本之前通知NameNode。
网友评论