hdfs 中chunk_hdfs写入流程解析

流程

df8bbadf89586fb6937c89935007b26d.png

写入本地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中断,需要重建。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值