Hadoop文件写入(详细剖析)

版权声明:本文为博主原创文章,欢迎诸位分享交流 https://blog.csdn.net/xiaoshunzi111/article/details/48198105


步骤详情:


文件是如何写入 HDFS 的。尽管比较详细,但对于理解数据流还是很有用的,因为它清楚地说明了 HDFS 的一致模型。要考虑的情况是如何创建一个新文件,并把数据写入该文件,最后关闭该文件。参见上图客户端通过对 DistributedFileSystem 对象调用 create()函数来创建文件(图步骤1)。 DistributedFileSystem 对 namenode 创建一个 RPC 调用,在文件系统的命名空间中创建一个新文件,此时该文件中还没有相应的数据块(步骤 2)。 namenode 执行各种不同的检查以确保这个文件不存在,并且客户端有创建该文件的权限。如果这些检查翊通过, namenode就会为创建新文件记录一条记录;否则,文件创建失败并向客户端抛出一个 IOException 异常 DistributedFileSystem 想客户端返回一个 FSDataOutputStream 对象,由此客户端可以开始写入数据。就像读取事件一样, FSDataOutputStream 封装一个 DFSoutPutstream 对象,该对象负责处理 datanode 和 namenode 之间的通信。在客户端写入数据时(步骤 3), DFSOutputStream 将它分成一个个的数据包,并写入内部队列,称为“数据队列” (data queue)。 DataStreamer 处理数据队列,它的责任是根据datanode 列表来要求 namenode 分配适合的新块来存储数据备份。这一组 datanode 构成一个管线一一假设复本数为 3,所以管线中有 3 个节点。 DataStreamer 将数据包流式传输到管线中第 1 个datanode,该 datanode 存储数据包并将它发送到管线中的第 2 个 datanode。同样地,第 2 个 datanode 存储该数据包并且发送给管线中的第3 DFSOutputStream 也维护着一个内部数据包队列来等待 datanode 的收到确认回执,称为“确认队列” (ack queue)。当收到管道中所有 datanode 确认信息后,该数据包才会从确认队列删除(步骤 5)。如果在数据写入期间, datanode 发生故障,则执行以下操作,这对与写入数据的客户端是透明的。首先关闭管线,确认把队列中的任何数据包都添加回数据队列的最前端,以确保故障节点下游的 datanode 不会漏掉任何一个数据包。为存储在另一正常 datanode 的当前数据块指定一个新的标识,并将该标识传送给 namenode,以便故障 datanode 在恢复后可以删除存储的部分数据块。从管线中删除故障数据节点并且把余下的数据块写入管线中的两个正常的的 datanode。 namenode 注意到块复本量不足时,会在另一个节点上创建一个新的复本。后续的数据块继续正常接受处理。在一个块被写入期间可能会有多个 datanode 同时发生故障,但非常少见。只要写入了dfs. replication. min 的复本数(默认为 1),写操作就会成功,并且这个块可以在集群中异步复制,直到达到其目标复本数( dfs. replication 的默认值为 3)。客户端完成数据的写入后,会对数据流调用 close()方法(步骤 6)。该操作将剩余的所有数据包写入 datanode 管线中,并在联系 namenode 且发送文件写入完成信号之前,等待确认(步骤 7)


步骤总结:

由上图可知;写入文件分为三个角色,分别是clientnode  namenode  和datanode

cliennode本质为java虚拟机.namenode 和datanode则是Hadoop数据集群存储块

第一步:create实际是客户端创建DistributedFileSystem实例化对象

第二步 create通过实例化对象录取调用对象中create()方法,此方法访问namenode,那么弄得收到命令,首先判断datanode中所写的文件是否有重复,然后在检查namenode是否有可写入空余的空间.当二者同时满足是,namenode写将datanode路径信息,文件数等记录,并确认信息返回DistributedFileSystem,否则返回异常,DistributedFileSystem收到确认信息后向客户端返回一个FSDataOutputStream FSDataOutputStream对象

第三步:实例化实例化FSDataOutputStreamFSDataOutputStream对象(该对象负责处理 datanode 和 namenode 之间的通信 ),调用该对象的write()方法,  即是图中write实现过程该对象负责处理 datanode 和 namenode 之间的通信

第四步:方法将数据分成多个数据包,并写入内部队列. DFDataOutStream 将写入的数据分成多个数据包,并写入内部队列中,同时开启datanode中DataStreamer处理数据队列,它负责根据datanode列来要求namenode分配合适的新块存储数据备份开启管道机制依次执行步骤4,同时即是write packet完整过程

第五步:每执行一次4就有一次步骤5返回确认信息.

4和5属于分别在DataQueue队列和ACKQueue队列,当每执行一次4就将此步确认信息放到ACKQueue队列中


如图:


第六步:当FSDataOutputStream收到确认信息后,执行close()方法关闭输出流,

第七步:DistributeFileStream 返回给namenode确认信息.

注释:第4-5部分实现在后台完成步不一定在第七步之前,

当执行第四步就就收第5步确认信息,告诉namenode 数据写入成功,即是第七步.


如有不明之处私信与我,相互交流经验.,恳请多多指正.谢谢!


展开阅读全文

没有更多推荐了,返回首页