HDFS 读写流程与副本放置策略

HDFS写数据流程

HDFS 读写流程与副本放置策略

1)客户端调用Distributed FileSystem模块的create方法,与NameNode进行RPC通信,请求上传文件,NameNode 检查目标路径的文件是否已存在,以及有没有权限创建该文件。假如OK,直接先将操作写入edits文件(WAL),创建一个新文件,但是不关联任何的block。

2)NameNode返回是否可以上传。

3)  客户端请求第一个 block上传到哪几个datanode服务器上。

4)  NN通过副本放置策略,返回3个datanode节点,分别为dn1、dn2、dn3。

5)NN返回FSDataOutputStream对象。客户端通过DFSOutputStream模块的wirte方法开始写数据,请求dn1上传数据,dn1收到请求会继续调用dn2,然后dn2调用dn3,将这个通信管道pipline建立完成。dn3逐级应答客户端。DFSOutputStream会把数据切成一个个小的packet,然后排成队列。

6)客户端开始往dn1上传第一个block,以packet为单位,dn1收到一个packet就会传给dn2,dn2传给dn3;dn3写入成功后,返回给ack packet给dn2,然后dn2返回ack packet给dn1,dn1返回ack packet给FSDataOutputStream对象的ack quene,标识该packet已经3副本写完!

7)当一个block传输完成之后,客户端再次请求NameNode上传第二个block的服务器。(重复执行3-6步)。

8)所有block写完后,Client调用FSDataOutputStream.close()方法。关闭输出流,flush缓存区的数据包。再调用FileSystem.complete(),通知NN节点写入成功。

注: 1、若存活的节点数<副本数,写操作失败。

        2、若存活的节点数>副本数, 在写操作时,dn1挂了,客户端会进行retry,若真正认为dn1挂了,那么客户端会再向NN请求三个DN节点。

        3、若存活的节点数>副本数, 在写操作时,dn2挂了,那么dn2、dn3均无法写入,在dn1写操作完成后,NN会校验副本数,发现副本数不够,NN会进行异步复制,把dn1的数据复制到其他两个DN上。

        4、若存活的节点数>副本数, 在写操作时,dn3挂了,与上面同理,NN进行异步复制到其他一个DN上。

副本放置策略

          机架感知副本放置策略:

HDFS 读写流程与副本放置策略

第一个副本:放在Client所处的节点上。如果客户端在集群外,则放在随机调选的一台不太忙的DN上。

第二个副本:放置在和第一个副本不相同的机架的随机节点上。

第三个副本:放置在和第二个副本位于相同机架的不同节点上。

假如还有更多副本:随机放。

生产上进行读写,尽量自己选取DN节点。(减少网络IO)

                

HDFS读数据流程

HDFS 读写流程与副本放置策略

1)Client通过Distributed FileSystem模块的open方法去与NN进行RPC通信,请求下载文件,NameNode通过查询元数据,找到文件块所在的DataNode地址,返回该文件的部分或全部的block列表。

2)NN会返回一个FSDataInputStream对象,Client调用FSDataInputStream对象的read()方法,就近挑选一台DN,请求读取数据。

3)DataNode开始传输数据给客户端(从磁盘里面读取数据输入流,以packet为单位来做校验)。如果第一块的数据读完了,就会关闭指向第一块的datanode连接,接着读取下一块。这些操作对客户端来说是透明的,客户端的角度看来只是读一个持续不断的流。

4)如果第一批block都读完了, 文件还没结束,那么FileSystem会从NN获取下一批的block列表,然后继续读,如果所有的块都读完,Client就会调用FSDataInputStream.close() 关闭输入流。

注:1、如果在读数据的时候失败,就会尝试正在读的block的排序第二近的datanode,并且会记录哪个 datanode发生错误,剩余的blocks读的时候就会直接跳过该datanode。

       2、DFSInputStream也会检查block数据校验和,如果发现一个坏的block,就会先报告到NN节点,然后 客户端再在其他的DN上读该block的镜像。