HDFS之读写流程

HDFS写流程

假设写入本地file文件,假设文件200M,则共有2个块,block1为128M(hdfs默认块大小为128M),block2为72M。默认三个副本。

  1. ClientNode向HDFS写入数据,先调用DistributedFileSystem的 create 方法获取FSDataOutputStream。

  2. DistributedFileSystem调用NameNode的 create 方法,发出文件创建请求。NameNode对待上传文件名称和路径做检验,如上传文件是否已存在同名目录,文件是否已经存在,递归创建文件的父目录(如不存在)等。并将操作记录在edits文件中。

  3. ClientNode调用FSDataOutputStream向输出流输出数据(假设先写block1)。

  4. FSDataOutputStream调用NameNode的 addBlock 方法申请block1的blockId和block要存储在哪几个DataNode(假设DataNode1,DataNode2和DataNode3)。若pipeline还没有建立,则根据位置信息建立pipeline。

  5. 同返回的第一个DataNode节点DataNode1建立socket连接,向其发送package。同时,此package会保存一份到ackqueue确认队列中。写数据时先将数据写到一个校验块chunk中,写满512字节,对chunk计算校验和checksum值(4字节)。以带校验和的checksum为单位向本地缓存输出数据(本地缓存占9个chunk),本地缓存满了向package输入数据,一个package占64kb。当package写满后,将package写入dataqueue数据队列中。将package从dataqueue数据对列中取出,沿pipeline发送到DataNode1,DataNode1保存,然后将package发送到DataNode2,DataNode2保存,再向DataNode3发送package。DataNode3接收到package,然后保存。

  6. package到达DataNode3后做校验,将校验结果逆着pipeline回传给ClientNode。DataNode3将校验结果传给DataNode2,DataNode2做校验后将校验结果传给DataNode1,DataNode1做校验后将校验结果传给ClientNode。ClientNode根据校验结果判断,如果”成功“,则将ackqueue确认队列中的package删除;如果”失败“,则将ackqueue确认队列中的package取出,重新放入到dataqueue数据队列末尾,等待重新沿pipeline发送。

  7. 当block1的所有package发送完毕。即DataNode1、DataNode2和DataNode3都存在block1的完整副本,则三个DataNode分别调用NameNode的 blockReceivedAndDeleted方法。NameNode会更新内存中DataNode和block的关系。ClientNode关闭同DataNode建立的pipeline。文件仍存在未发送的block2,则继续执行4。直到文件所有数据传输完成。

  8. 全部数据输出完成,调用FSDataOutputStream的 close 方法。

  9. ClientNode调用NameNode的 complete 方法,通知NameNode全部数据输出完成。

容错

假设当前构建的pipeline是DataNode1、DataNode2和DataNode3。当数据传输过程中,DataNode2中断无法响应,则当前pipeline中断,需要重建。

  • 先将ackqueue中的所有package取出放回到dataqueue末尾。
  • ClientNode调用NameNode的 updateBlockForPipeline 方法,为当前block生成新的版本,如ts1(本质是时间戳),然后将故障DataNode2从pipeline中删除。
  • FSDataOutputStream调用NameNode的 getAdditionalDataNode 方法,由NameNode分配新的DataNode,假设是DataNode4。FSDataOutputStream把DataNode1、DataNode3和DataNode4建立新的pipeline,DataNode1和DataNode3上的block版本设置为ts1,通知DataNode1或DataNode3将block拷贝到DataNode4。
  • 新的pipeline创建好后,FSDataOutputStream调用NameNode的 updataPipeline 方法更新NameNode元数据。之后,按照正常的写入流程完成数据输出。
  • 后续,当DataNode2从故障中恢复。DataNode2向NameNode报送所有block信息,NameNode发现block为旧版本(非ts1),则通过DataNode2的心跳返回通知DataNode2将此旧版本的block删除。

HDFS读流程

  1. 客户端向NameNode申请要读取的文件,先调用DistributedFileSystem的 open方法获取FSDataInputStream
  2. NameNode根据情况向客户端返回全部或者一部分block块所在DateNode的信息列表,根据机架感知原理,通过就近原则,随机的挑选一台服务器,然后Client通过FSDataInputStream链接到此DateNode所在的服务器,然后通过调用read方法读取数据,若此过程中出现错误,则向NameNode报告,NameNode会返回另一个包含改block块的服务器用于读取数据。
  3. DataNode向Client端传输数据,Client端会按每个packet来校验数据,Client把packet写入本地缓存,然后写入到指定的文件中。
  4. 释放连接资源
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值