【学习历程】07 Hadoop之HDFS读写流程

一、HDFS的写入流程

1.1、文件上传流程如下:

在这里插入图片描述
创建文件:

  1. HDFS client向HDFS写入数据,先调用DistributedFileSystem. create()
  2. RPC调用namenodecreate(),会在HDFS目录树中指定的路径,添加新文件,并将操作记录在edits.log中。namenode.create()方法执行完后,返回一个FSDataOutputStream,它是DFSOutputStream的包装类。

建立数据流管道pipeline:

  1. client调用DFSOutputStream.write()写数据 (先写第一个块的数据, 暂时叫blk1)
  2. DFSOutputStream通过RPC调用namenodeaddBlock,向namenode申请一 个空的数据块block
  3. addBlock返回LocatedBlock对象;此对象中包含了当前blk要存储在哪三个datanode的信息,比如dn1、dn2、dn3
  4. 客户端,根据位置信息,建立数据流管道(图中蓝色线条)

向数据流管道写当前块的数据:

  1. 写数据时,先将数据写入一个检验块chunk中,写满512字节后,对此chunk计算校验和checksum值(4字节)
  2. 然后将chunk及对应校验和写入packet中,一个packet64KB
  3. 随着源源不断的带校验和的chunk写入packet,当packet写满后,将packet写 入dataqueue数据队列中
  4. packet从队列中取出,沿pipeline发送到dn1,再从dn1发送到dn2,再从dn2发送到dn3
  5. 同时,此packet会保存一份到一 个确认队列ack queue
  6. packet到达最后一个datanodedn3后,做校验,将校验结果逆着pipeline方向回传到客户端,具体是校验结果从dn3传到dn2dn2也会做校验,校验结果再传到dn1dn1也做校验,结果再传回客户端
  7. 客户端根据校验结果,如果“成功”,则将保存在ack queue中的packet删除;如果失败,则将packet取出,重新放回到data queue末尾,等待再次沿pipeline发送
  8. 如此,将block中的一个数据一个个packet发送出去;当此block发送完毕,即dn1、dn2、dn3都接受了blk1的完整的副本,那么三个dn分别RPC调用namenodeblockReceivedAndDeleted()namenode会更新内存中blockdatanode的对应关系(比如dn1上多了一个blk1副本)

关闭dn1. dn2. dn3构建的pipeline,文件还有下一个块时,再从4开始,直到文件全部数据写完:

  1. 最终,调用DFSOutputStream的close0

  2. 客户端调用namenodecomplete(),告知namende文件传输完成

1.2、容错机制

问题描述:
        假设说当前构建的pipelinedn1、dn2、 dn3构成的,当传输数据的过程中,dn2挂了或通信不畅,则当前pipeline中断,HDFS会如何做?

解决:

  1. 先将ack queue中的所有packet全部放回到data queue

  2. 客户端RPC调用namenodeupdateBlockForPipeline(),为当前block(假设是blk1)生成新的版本比如ts1 (本质是时间戳)

  3. 故障dn2会从pipeline中删除

  4. DFSOutputStreamRPC调用namenodegetAdditionalDatanode(),让namenode分配新的datanode,比如是dn4

  5. 输出流将原dn1、dn3与新的dn4组成新的管道,他们上边的blk1版本设置为新版本ts1

  6. 由于新添加的dn4上没有blk1的数据,客户端告知dn1dn3,将其上的blk1的数据拷贝到dn4

  7. 新的数据管道建立好后,DFSOutputStream调用updatePipeline()更新namenode元数据

  8. 至此,pipeline恢复, 客户端按正常的写入流程,完成文件的上传

  9. 故障datanode重启后,namenode发现它上边的blockblk1的时间戳是老的,会让datanodeblk1删除掉

参考文献:HDFS容错机制详解

二、HDFS的读取流程

文件读取流程如下:
在这里插入图片描述

  1. 客户端通过DistributedFileSystemNameNode请求下载文件,NameNode通过查询元数据,找到文件块所在的DataNode地址。

  2. 挑选一台DataNode(就近原则,然后随机)服务器,请求读取数据。

  3. DataNode开始传输数据给客户端(从磁盘里面读取数据输入流,以Packet为单位来做校验)。

  4. 客户端以Packet为单位接收,先在本地缓存,然后写入目标文件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值