Hadoop HDFS数据流解析

客户端和与之交互的HDFS,namenode,datanode之间的数据流。

1. 文件读取

1) 客户端调用FileSystem的open()方法打开文件,对于HDFS,是一个DistributedFileSystem的实例

2) DistributedFileSystem的实例通过RPC调用namenode,namenode根据映射关系返回存有文件块副本的datanode地址,datanode根据与客户端的距离排序(网络拓扑),如果本身也是datanode且存有文件块,则客户端从本地获取副本

3) DistributedFileSystem返回一个FSDataInputStream对象给客户端以便读取数据,FSDataInputStream封装了DFSInputStream,这个类管理者datanode和namenode的I/O,客户端对DFSInputStream反复调用read()方法,将数据从datanode传输到客户端

4) 块读取完毕后,DFSInputStream关闭与该datanode的连接,寻找下一个块所在的最佳datanode,重复读取,一直到读取完毕,调用FSDataInputStream的close()

5) 这些操作对客户端都是透明的,客户端认为是一个连续的流

DFSInputStream的作用

1) 管理namenode和datanode的I/O

2) 存储namenode告知的最佳块位置

3) 如果遇到与datanode通信错误,则连接另一个最近的有副本的datanode,并记录故障节点,不再与它通信

4) 校验datanode块的完整性,如果有问题,告诉namenode,并从其他节点读取副本

2. 文件写入

1) 客户端使用DistributedFileSystem对象调用create()创建一个新文件

2) 对namenode进行RPC调用在文件系统命名空间新建文件,namenode执行检查确认文件不存在且客户端有新建文件权限

(1) 可以新建,为创建新文件做一个记录

(2) 不能新建,向客户端抛出IOException

3) DistributedFileSystem向客户端返回一个FSDataOutputStream对象,FSDataOutputStream封装了一个DFSOutputStream对象与namenode和datanode通信

4) 写入数据时,DFSOutputStream将数据分为数据包,写入“数据队列”(data queue),DataStreamer通过挑选出适合存储副本的一组datanode,并向namenode请求分数据块,告诉namenode数据块是怎么划分的,这组datanode形成管线,DataStreamer将数据包流式传输到第一个datanode,并这个datanode通过管线将数据包传递给下一个datanode,依次到结束,使用确认队列(ack queue)收到所有datanode确认信息后,数据包才会从确认队列删除

5) 客户端完成数据写入后,调用FSDataOutputStream的close()方法,将剩余数据包全部写入datanode管线,并等待确认信息,最后告知namenode文件写入完成。

如果写入期间发生故障

datanode在写入时发生故障

1) 关闭管线,把队列中的所有数据包(共同组成一个块)添加回数据队列的最前端,确保下游的datenode不漏掉任何一个数据包。

2) 将存储了正确数据块信息的datanode添加标识,把标识传给namenode,故障节点在恢复后删除存储的部分数据块,从管线中删除故障datanode。

3) 在管线中添加一个新的datanode,替换故障datanode。

Leave A Comment