HDFS的读写流程及多线程写问题

1、HDFS之block package chunk

了解hdfs的读写流程,首先要了解block、package、chunk的概念。

  • 1、block
    这个大家应该知道,文件上传前需要分块,这个块就是block,一般为128MB,当然你可以去改,不顾不推荐。因为块太小:寻址时间占比过高。块太大:Map任务数太少,作业执行速度变慢。它是最大的一个单位。
  • 2、package
    packet是第二大的单位,它是client端向DataNode,或DataNode的PipLine之间传数据的基本单位,默认64KB
  • 3、chunk
    chunk是最小的单位,它是client向DataNode,或DataNode的PipLine之间进行数据校验的基本单位,默认512Byte,因为用作校验,故每个chunk需要带有4Byte的校验位。所以实际每个chunk写入packet的大小为516Byte

2、HDFS的写流程

在这里插入图片描述

  • 1、使用HDFS提供的客户端Client,向远程的Namenode发起RPC请求
  • 2、Namenode会检查要创建的文件是否已经存在,创建者是否有权限进行操作,成功则会文件创建一个记录,否则会让客户端抛出异常。
  • 3、当客户端开始写入文件的时候,客户端会将文件切分成多个packets,并在内部以数据队列“data queue"形式管理这些packets, 然后向Namenode申请blocks,获取用来存储replications的合适的datanode列表,列表的大小根据Namenode中的replication值而定。
  • 4、开始以pipeline的形式将packet写入所有的replications中,客户端把packet以流的方式写入第一个datanode,该datanode把该packet存储之后,再将其传递给在此pipeline的下一个datanode,直到最后一个datanode,这种写数据的方式呈流水线形式。
  • 5、最后一个datanode成功存储之后会返回一个ack packet(确认package),在pipeline里传递给客户端,在客户端的开发库内部维护着“ack queue”,成功收到datanode返回的ack packet后会从“ack queue”移除相应的 packet。
  • 6、如果传输过程中, 有某个datanode出现了故障, 那么当前的pipeline会被关闭, 出现故障的datanode会从当前的pipeline中移除, 剩余的block会继续在剩下的datanode中继续以pipeline的形式传输, 同时Namenode会分配一个新的datanode, 保持replications设定的数量
  • 7、当一个block传输完成时,client再次请求NN上传第二个block的服务器。
  • 8、客户端完成数据的写入后,会对数据流调用close(),关闭数据流。
  • 9、发送完成信号给NameNode。
    (注:发送完成信号给NameNode的时机取决于集群是强一致性还是最终一致性,强一致性则需要所有DataNode写完后才向NameNode汇报。最终一致性则其中任意一个DataNode写完后就能单独向NameNode汇报,HDFS一般情况下都是强调强一致性

3、HDFS的读流程

在这里插入图片描述

  • 1、跟NN通信查询元数据(block所在的DN的节点),找到文件块所在的DN的服务器。
  • 2、挑选一台DN(就近原则,然后随机)服务器,请求建立输入流。
  • 3、DN开始发送数据(从磁盘里读取数据放入流,一packet为单位做校验)。
  • 4、当此数据块读取完毕时,关闭和此数据节点的连接,然后连接此文件下一个数据块的最近的数据节点。
  • 5、当客户端读取完毕数据的时候,调用FSDataInputStream的close函数。

在读取过程中,如果FSDataInputStream在和一个datanode进行交流时出现了一个错误,它就去试一试下一个最接近的块,同时也会记住刚才发生错误的datanode,之后便不会再在这个datanode上进行没必要的尝试

DFSInputStream 也会在 datanode 上传输出的数据上核查检查数(checknums),如果损坏的块被发现了,DFSInputStream 就试图从另一个拥有备份的 datanode 中去读取备份块中的数据

4、HDFS写数据过程中DataNode出错

如果向DataNode写入数据失败了,那么会执行以下操作:

  • 1、Pipeline数据流管道会被关闭,ACK queue中的packets会被添加到data queue的前面以确保不会发生packets数据包的丢失
  • 2、在正常的DataNode节点上的以保存好的block的ID版本会升级——这样发生故障的DataNode节点上的block数据会在节点恢复正常后被删除,失效节点也会被从Pipeline中删除
  • 3、剩下的数据会被写入到Pipeline数据流管道中的其他两个节点中

5、HDFS能否多线程写?

答案是:不能
hdfs的不能并发写指的是同位置同名文件只能有一个writer,否则会使得所有的上传请求失败
不同位置或者不同名的文件可以同时上传

读写过程,数据完整性如何保持?

通过校验和。因为每个chunk中都有一个校验位,一个个chunk构成packet,一个个packet最终形成block,故可在block上求校验和。

HDFS 的client端即实现了对 HDFS 文件内容的校验和 (checksum) 检查。当客户端创建一个新的HDFS文件时候,分块后会计算这个文件每个数据块的校验和,此校验和会以一个隐藏文件形式保存在同一个 HDFS 命名空间下。当client端从HDFS中读取文件内容后,它会检查分块时候计算出的校验和(隐藏文件里)和读取到的文件块中校验和是否匹配,如果不匹配,客户端可以选择从其他 Datanode 获取该数据块的副本。

HDFS中文件块目录结构具体格式如下:

${dfs.datanode.data.dir}/
├── current
│ ├── BP-526805057-127.0.0.1-1411980876842
│ │ └── current
│ │ ├── VERSION
│ │ ├── finalized
│ │ │ ├── blk_1073741825
│ │ │ ├── blk_1073741825_1001.meta
│ │ │ ├── blk_1073741826
│ │ │ └── blk_1073741826_1002.meta
│ │ └── rbw
│ └── VERSION
└── in_use.lock

扫描二维码关注公众号,回复: 10900940 查看本文章

in_use.lock表示DataNode正在对文件夹进行操作
rbw是“replica being written”的意思,该目录用于存储用户当前正在写入的数据。
Block元数据文件(*.meta)由一个包含版本、类型信息的头文件和一系列校验值组成。校验和也正是存在其中。

发布了9 篇原创文章 · 获赞 0 · 访问量 62

猜你喜欢

转载自blog.csdn.net/yangbllove/article/details/105567892