【好文转载】比我写的还牛批的HDFS读写操作流程

文件读取流程

在这里插入图片描述

  1. 客户端首先要调用FileSystem对象的静态方法open()方法来打开一个希望读取文件的路径,在HDFS中文件的对象为Path对象(与Java中的File相对应)。

  2. FileSystem对象就是一个DistributedFileSystem对象,通过利用RPC来调用NameNode节点,(NameNode节点存储着整个文件系统目录、文件以及文件所在块的位置信息),来确定我们需要打开的文件所有数据块的存储位置。文件在被存入HDFS中,会被划分为多个数据块存储的,对于每一个数据块,namenode都会返回存有该数据块副本的datanode地址。数据块副本的datanode地址会根据与客户端的距离来排序。DistributedFileSystem返回一个FSDataInputStream对象给client用来读取数据。FSDataInputStream封装了DFSInputStream对象,该对象用于管理NameNode和DataNode的I/O

  3. 客户端利用该FSDataInputStream对象的输入流调用read()方法。输入流会首先读取距离客户端最近的datanode,反复读取,直到将该datanode数据读取完后,然后就会FSDataInputStream关闭与该datanode的连接,然后继续寻找下一个datanode节点。

  4. 客户端读取文件,数据块都是按照DFSInputStream与datanode连接的距离顺序读取,也会询问namenode下一批数据块的datanode位置,整个文件读取完后,就会马上调用FSDataInputStream的close()方法。

读取中的失败错误处理:当读取数据时,DFSInputStream与datanode通信失败,则会读取这个块的最接近该datanode的节点来读取数据,并且以后不会反复读取该失败节点。

namenode仅仅提供给客户端检索文件的作用,告知客户端每个块最佳datanode(利用排序),它仅仅响应数据块位置的请求,而无需响应数据请求。具体的数据流都是由客户端与datanode直接通信的。

文件写入流程

在这里插入图片描述

  1. client通过调用DistributedFileSystem的create()方法来创建文件。

  2. DistributedFileSystem通过RPC调用NameNode在文件系统的名字空间里创建一个新文件,名称节点首先确定文件原来不存在,并且客户端有创建文件的权限,然后创建新文件,这个时候还没有任何块的信息。DistributedFileSystem返回FSDataOutputStream给client。FSDataOutputStream封装了一个DFSOutputStream对象,该对象负责处理datanode和namenode之间的通讯。

  3. 当Client开始写数据的时候,DFSOutputStream把文件的数据分成一个个数据包,并写入内部对列DataQueue。DataQueue是由DataStreamer负责读取,DataStreamer通知NameNode分配DataNode,用来存储数据块(每块默认复制3块),分配的DataNode列表形成一个管道(pipeline)。在上图中管道由三个datanode组成,这三个datanode的选择有一定的副本放置策略。

  4. DataStreamer将数据块流式传输到pipeline中的第一个DataNode,第一个DataNode存储数据块并将数据块发送给pipeline中的第二个DataNode,同样的,第二个DataNode存储数据块并将数据块发送给pipeline中的第三个DataNode。

  5. 同时,DFSOutputStream也管理ackqueue(确认队列),ackqueue里存储着等待datanode识别的数据块,只有当管道里所有datanode都返回写入成功,这个数据块才算写成功,才会从ackqueue中删除,开始写下一个数据块。
    如果某个datanode发生故障,写失败了,则会执行如下步骤,但是这些对client是透明的。


  1. 管道关闭。

  2. 正常的datanode上的当前block会有一个新ID,并将该ID传送给namenode,以便失败的datanode在恢复后可以删除那个不完整的block。

  3. 失败的datanode会被移出管道,余下的数据块继续写入管道的其他两个正常的datanode。

  4. namenode会标记这个block的副本个数少于指定值。block的副本会稍后在另一个datanode创建。

  5. 有些时候多个datanode会失败,但非常少见。只要dfs.replication.min(缺省是1)个datanode成功了,整个写入过程就算成功。缺少的副本会在集群中异步的复制,直到达到正常的副本数。

  6. 当client完成了所有block的写入后,调用FSDataOutputStream的close()方法关闭文件。

  7. FSDataOutputStream通知namenode写文件结束。

文件写入中的副本策略:

  1. Hadoop默认副本策略是将第一个复本放在运行客户端的节点上,即上传文件或者写入文件所在的datanode节点上。如果客户端不在集群中,则就随机选择一个节点。

  2. 第二个复本放在与第一个复本不同且随机的另外的机架上。

  3. 第三个复本与第二个复本放在相同的机架上。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值