HDFS的写流程
Posted 阿木公的阳小山
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDFS的写流程相关的知识,希望对你有一定的参考价值。
写过程与读过程类似。示意图如下:
客户端首先需要获取到FileSystem的一个实例,这里就是HDFS对应的实例。
客户端首先会调用create方法创建文件。当该方法被调用后,NameNode会进行一些检查,检查要写入文件是否存在(同名文件);客户端是否拥有创建权限等。检查完成之后,需要在NameNode上创建文件信息,但是此时并没有进行实际的写入,因此,此时HDFS中并没有实际的数据,同理,NameNode上也没有数据块信息。create完成之后,会返回一个输出流DFSOutputStream给客户端。
客户端会调用输出流的write方法向HDFS中写入数据。注意,此时数据并没有真正写入,数据首先会被分包,分包完成之后,这些数据会被写入输出流DFSOutputStream的一个内部Data队列中,数据分包接收完成之后,DFSOutputStream会向NameNode申请保存文件和副本数据块的若干个DataNode,这若干个DataNode会形成一个数据传输管道。
DFSOutputStream会依据网络拓扑结构排序,将数据传输给最近的DataNode,这个DataNode接收到数据包之后,将数据包传输给下一个DataNode。数据在各个DataNode上通过管道流动,而不是全部由输出流分发,这样可以减少传输开销。
并且,因为DataNode位于不同的机器上,数据需要通过网络(socket)发送。为了保证数据的准确性,接收到数据的DataNode需要向发送者发送确认包(ACK)。对于某个数据块,只有当DFSOutputStream接收到所有DataNode的正确ACK,才能确认传输结束。DFSOutputStream内专门维护了一个等待ACK队列,这个队列保存已经进入管道传输数据、但是并未完全确认的数据包。
DFSOutputStream会不断传输数据包,直到所有的数据包传输都完成。
客户端调用close方法,关闭传输通道。
另外,在数据传输的过程中,如果发现某个DataNode失效了(未联通,ACK超时),那么HDFS会进行如下操作:
关闭数据传输管道
将等待ACK队列中的数据放到Data队列的头部
更新DataNode中所有数据块的版本,当失效的DataNode重启后,之前的数据块会因为版本不对而被清楚
在传输管道中删除失效的DataNode,重新建立管道并发送数据包
HDFS的写过程复杂了很多。首先获取文件系统的实例这个无可厚非,拿到了实例才能进行交互。过程的难点:
(1)需要维护一个Data队列,Data队列做了两件事:1)接受分包,并传输到DataNode;2)传输出错后,需要将ACK队列中的数据放入Data队列中。
(2)每个接收到分包需要传输给发送方ACK。
(3)数据在DataNode之间是通过管道水平传输的。
以上是关于HDFS的写流程的主要内容,如果未能解决你的问题,请参考以下文章