HDFS_09_HDFS写入数据流程

HDFS_09_HDFS写入数据流程

持续更新大数据文章…

1. HDFS写入数据流程 ⭐️

HDFS写入数据流程是指:用户存储数据到 HDFS 上

1.1 宏观流程

在这里插入图片描述

客户端有一个文件:

  • 名称为:user.log
  • 大小为 :258MB

现在需要把文件 user.log 上传到 HDFS

具体宏观步骤是:

  1. 发送上传文件请求给 HDFS (上传命令:hdfs dfs -put user.log /huoborn),HDFS 接收到客户端的请求,并且判断上传命令的准确性。
  2. RPC 远程调用 NameNode 的 create() 方法。
  3. 调用 NameNode 的 create() 方法之后,NameNode 会检查请求用户是否有权限进行上传操作。
  4. NameNode 的 create() 方法开始验证请求是否可以通过
    • 如果请求不通过,抛出异常
    • 如果请求通过,返回成功,并且会创建该文件的映射(entry对象)对象到 NameNode 的本地磁盘上
  5. 请求结果返回给客户端
    • 如果结果为 false ,请求不通过,禁止上传。
    • 如果结果为 true,请求通过,给客户端创建一个输出流FSDataOutPutStream
  6. 客户端把文件拆分成数据块,开始上传,先询问 NameNode, Block1 应该存放在哪个 DataNode 上
  7. 返回 Block1 与 DataNode 的映射信息给客户端,告诉客户端 Block1 存放在哪个 DataNode 上
  8. 根据返回的信息,存储 Block1 到对应 DataNode,并且让 HDFS 创建 DataNode 管道(通过Socket连接管道)
    • 把 Block1 拆分为更小的存储单元 Packet(64K)
    • Packet 像水流一样经过管道传输到 DataNode 上
    • 直到 Block1 拆分成的 Packet 全部传输到 DataNode 上,并且 DataNode 上对应的 Packet 又重新组成 Block1
    • 关闭为 Block1 创建的管道,开始准备传输 Block2
  9. 客户端询问 NameNode, Block2 应该存放在哪个 DataNode 上
  10. 返回 Block2 与 NameNode 的映射信息给客户端,告诉客户端 Block1 存放在哪个 DataNode 上
  11. 根据返回的信息,存储 Block2 到对应 DataNode,并且让 HDFS 创建 DataNode 管道(通过Socket连接管道)
    • 把 Block2 拆分为更小的存储单元 Packet(64K)
    • Packet 像水流一样经过管道传输到 DataNode 上
    • 直到 Block2 拆分成的 Packet 全部传输到 DataNode 上,并且 DataNode 上对应的 Packet 又重新组成 Block2
    • 关闭为 Block2 创建的管道,开始准备传输 Block3
  12. 依次重复,知道全部的数据块都存储到对应的 DataNode 上
  13. 集群启动之后,NameNode 的文件映射(entry对象)对象删除 数据块与 DataNode 的信息,该消息不保存到 NameNode 的本地磁盘上,而是根据心跳机制动态变换。

1.2 微观流程

在这里插入图片描述

客户端有一个文件:

  • 名称为:user.log
  • 大小为 :258MB

现在需要把文件 user.log 上传到 HDFS

具体微观步骤是:

  1. 文件user.log 被 IO 读取到内存

  2. user.log 被读成更小的单元 chunk(512 bytes)checksum(4 bytes)

  3. 一个chunk(512 bytes)和一个checksum(4 bytes)组合和在一起
    在这里插入图片描述

  4. 127个==chunk(512 bytes)checksum(4 bytes)==对被封装成 Packet(64KB)

在这里插入图片描述

  1. Packet 是要被发到对应的 DataNode上,但是生产 Packet 速度与发送给 DataNode 速度不对等,为了防止 Packet堵塞,把 Packet 放到队列上,队列的特性是先进先出。这里是类似于生产者-消费者模式。
    在这里插入图片描述

  2. 为了防止 Packet传输出错,HDFS 有一个 DataStreamer

  3. Packet 开始发送到对应的 DataNode 上

  4. DataStreamer 开始工作

    • DataStreamer 从 DataQueue队列 拿出一个 Packet

    • DataStreamer 把拿到的 Packet 会备份一份,然后把其中一份发给输出流,这个 Packet 会发到 DataNode1 上

    • DataStreamer 把另一份 Packet 挂载到 AckQueue队列 上

    在这里插入图片描述

  5. 当 DataNode(第n个)接收到Packet,之后,DataNode(第n个)会给DataNode(第n-1个)一个ACk应答,然后这个应答会一直往前面的 DataNode 传送直到被ResponseProcess接收,ResponseProcess接收之后就会删除挂载到AckQueue队列上面与这个应答相对应的Packet。同样的,当DataNode(第3个)接收到Packet4之后,DataNode(第3个)会给DataNode(第2个)一个ACK应答,DataNode(第2个)会给DataNode(第1个)一个ACK应答,DataNode(第1个)会告诉ResponseProcess,Packet4已经被接受,这个时候ResponseProcess就会被挂载到 AckQueue队列上面的Packet4删除

在这里插入图片描述

  1. 如果 Packet5 传输错误,那么挂载到 AckQueue队列 上的 Packet5 就会被 DataStreamer 转移到 DataQueue队列 的头部,然后DataStreamer 继续备份一份 Packet5 ,一份发送给输出流重新再一次给 DataNode 传输 Packet5 ,一份暂时挂载到 AckQueue队列 上

  2. 直到对应的 DataNode 上积累了 128MB 的Packet(数据块大小默认是128MB),这样就完成了一个数据块的传输,接着传输下一波数据块

  3. 重复以上步骤,chunk+checksum组成Packet发送给对应的DataNode ,直到对应的每个 DataNode 又积累了 128MB 的Packet(数据块大小默认是128MB),这样就又完成了一个数据块的传输。

  4. 重复,直到数据块全部传输完成

补充:

如果传输过程当中,有一个DataNode出现故障,那么其他的DataNode就会代替出现故障的DataNode继续接收Packte,接收完毕之后,剩余的DataNode与NameNode进行心跳,NN知道哪个DataNode出现故障之后就会做出对应的措施



下期讲解 HDFS_10_Packet......

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值