栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 前沿技术 > 大数据 > 大数据系统

HDFS读写流程(全面深入理解)

HDFS读写流程(全面深入理解)

1、HDFS写流程

  (1)客户端通过对FileSystem.create() 对象创建建文件,DistributedFileSystem会创建输出流FSDataOutputStream。

  (2)DistributedFileSystem 通过RPC远程调用名称节点,在文件系统的命名空间中创建一个新的文件,此时该文件中还没有相应的数据块。

  (3)名称节会执行一些检查,比如文件是否已经存在、客户端是都有权限创建文件等。检查通过后,名称节点会构造一个新文件,并添加文件信息。如果检查不通过,文件创建失败会向客户端抛一个 IOException 异常。

  (4)DistributedFileSystem利用DFSOutputStream来实例化FSDataOutputStream,返回给客户端,客户端使用这个输出流写入数据(new DFSDataOutputStream)。

  了解:DFSOutputStream负责处理 DataNode 和 NameNode 之间的通信

  (5)客户端向输出流FSDataOutputStream中写入的数据会被分成一个个的分包,这些分包被放入DFSOutputStream对象的内部队列“dataQueue”

了解:
1)启动线程DataStreamer,它存储dataQueue.wait队列阻塞等待接收读取到的数据。
数据:packet(64k)= chunk(512byte)+ chunksum (4byte)。chunk:数据校验的基本单位。
每个chunk需要带有4Byte的校验位,127个形成一个packet 。(队列有了数据之后,要往外写数据)
因此,DataStreamer [ 获取block(机架感知)],去处理数据队列,挑选出适合存储数据副本的一
组 DataNode ,并要求 NameNode 分配新的数据块。
2)DataStreamer获取到数据节点 后,使用Socket请求发送packet

助记:FSDataOutputStream里有DFSOutputStream里有DataStreamer

  (6)输出流FSDataOutputStream会向名称节点申请保存文件和副本数据块的若干个数据节点,这些数据节点(DataNode)形成一个数据流管道(Pipeline)。队列中的分包最后被打包成数据包,发往数据流管道的第一个数据节点, 第一个数据节点将数据包发送给第二个节点,第二个数据节点发送给第三个数据节点,数据包流经管道上个各个数据节点(即流水线复制策略)

了解:流水线(PipeLine),简单地理解就是客户端向DataNode传输数据(Packet)和接收DataNode
回复(ACK)的数据通路。整条流水线由若干个DataNode串联而成,数据由客户端流向PipeLine,
在流水线上,假如DataNode A 比 DataNode B 更接近流水线

流水线复制策略(扩充)
每个块都向HDFS集群中的名称节点发起写请求,名称节点会根据系统的各个数据节点的使用情况,
选择一个数据节点列表返回给客户端,然后客户端就把数据首先写入列表中的第一个数据节点,同
时把列表传给第一个数据节点,,当第一个数据节点接收到4KB数据的时候,写入本地,并且向第
二个数据节点发起连接请求,把自己已经接受到4KB数据和列表传给第二个数据节点,当第二个数
据节点接收到4KB数据的时候,写入本地,并且向列表中的第三个数据节点发起连接情节,以此类
推,列表中的多个数据节点形成一条数据复制的流水线。最后,当文件写完的时候,数据复制也同
时完成。

   (7)【因为各个数据节点位于不同的机器,数据需要通过网络发送。为了保证所有数据节点的数据都是准确的,接收到数据的数据节点要向发送这发送"确认包"(ACK Packet)。】
   确认包沿着数据流管道逆流而上,从数据流管道一次经过各个数据节点并最终发往客户端(DataStreamer),客户端收到应答时,它将u四月那个的分包从内部队列移除。不断执行(4)~(7)步,直到数据全部写完。

   (8)客户端调用close()方法关闭输出流。
   了解:此时,客户端不会再向输出流中写入数据,所有,当DFSOutputStream对象内部队列中的分包都收到应答后,就可以使用ClientProtocal.complete()方法通知名称节点关闭文件,完成一次正常的写文件的过程。

1、HDFS读流程
   (1)客户端通过FileSystem.open()打开文件,相应地,在HDFS文件系统DistributedFileSystem具体实现了FileSystem。调用open()后,DistributedFileSystem会创建输出流FSDataInputStream。对于HDFS而言,具体输入流是DFSInputStream.

   (2)在DFSInputStream的构造函数中,输入流是通过ClientProtocal.getBlockLocations()远程调用名称节点,获取文件开始部分数据块的保存位置。
   对于该数据块,名称节点返回保存该数据块的所有数据节点的名称,同时根据客户端的远近对数据节点进行排序,
   然后,DistributedFileSystem利用DFSOutputStream来实例化FSDataOutputStream,返回给客户端,同时返回给数据块的数据节点的地址。

   (3)获得输入流FSDataOutputStream后,客户端调用read()函数开始读取数据。输入流根据前面排序结果,选择距离客户端最近的数据节点建立连接并读取数据。

   (4)数据从数据节点读到客户端,当该数据块读取完毕时,FSDataOutputStream关闭和该数据节点的连接。

   (5)输入流通过getBlockLocations()方法查找下一个数据块(如果客户端缓存中已经包含了该数据块的位置信息,就不需要调用该方法)。

   (6)找到该数据块的最佳数据节点,读取数据。

   (7)当客户端读取完毕数据的时候,调用FSDataOutputStream的close()函数,关闭输入流。

注意:在读取数据的过程中,如果客户端与数据节点通信时出现错误,就会尝试连接包含此数据块的下一个数据节点

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/355050.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号