第十一章 HDFS 的读写详解

HDFS 的写操作

1)客户端通过 Distributed FileSystem 模块向 NameNode 请求上传文件,NameNode 检查目标文件是否已存在,父目录是否存在。

客户端怎么知道请求发给那个节点的哪个进程?

因为客户端会提供一些工具来解析出来你所指定的 HDFS 集群的主节点是谁,以及端口号等信息,主要是通过URI来确定,uri:hdfs://bigdata101:9000

当前请求会包含一个非常重要的信息: 上传的数据的总大小

2)NameNode返回是否可以上传。

1 管理元数据(抽象目录树结构)

用户上传的那个文件在对应的目录如果存在。那么HDFS集群应该作何处理,不会处理。

用户上传的那个文件要存储的目录不存在的话,如果不存在不会创建。

2、响应请求

真正的操作:做一系列的校验。

1、校验客户端的请求是否合理 2、校验客户端是否有权限进行上传

3)如果 namenode 返回给客户端的结果是 通过, 那就是允许上传,客户端请求第一个 Block上传到哪几个DataNode 服务器上。

4)NameNode 返回 3 个 DataNode 节点,分别为bigdata101、bigdata102、bigdata103。

5)对要上传的数据块进行逻辑切片

切片分成两个阶段:

1、规划怎么切 2、真正的切

物理切片: 1 和 2

逻辑切片: 1

file1_blk1 : file1:0:128 file1_blk2 : file1:128:256

  逻辑切片只是规划了怎么切

6)客户端通过 FSDataOutputStream 模块请求 bigdata101 上传数据,bigdata101 收到请求会继续调用bigdata102,然后bigdata102调用bigdata103,将这个通信管道建立完成。

7)bigdata101、bigdata102、bigdata103逐级应答客户端。

8)客户端开始往bigdata101上传第一个Block(先从磁盘读取数据放到一个本地内存缓存),以Packet为单位,bigdata101收到一个Packet就会传给bigdata102,bigdata102传给bigdata103;bigdata101每传一个packet会放入一个应答队列等待应答。

9)当一个传输完成之后,客户端再次请求上传第二个的服务器。(重复执行步)

10)客户端在意识到所有的数据块都写入成功之后,会给 namenode 发送一个反馈,就是告诉 namenode 当前客户端上传的数据已经成功。


备注

只要写入了 dfs.replication.min(最小写入成功的副本数)的复本数(默认为 1),写操作 就会成功,并且这个块可以在集群中异步复制,直到达到其目标复本数(dfs.replication 的默认值为 3),因为 namenode 已经知道文件由哪些块组成,所以它在返回成功前只需 要等待数据块进行最小量的复制。

1、block 是最大的一个单位,它是最终存储于 DataNode 上的数据粒度,由 dfs.block.size 参数决定,2.x版本默认是 128M;注:这个参数由客户端配置决定;如:System.out.println(conf.get("dfs.blocksize"));//结果是134217728

2、packet 是中等的一个单位,它是数据由 DFSClient 流向 DataNode 的粒度,以 dfs.write.packet.size 参数为参考值,默认是 64K;注:这个参数为参考值,是指真正在进行数据传输时,会以它为基准进行调整,调整的原因是一个 packet 有特定的结构,调整的目标是这个 packet 的大小刚好包含结构中的所有成员,同时也保证写到 DataNode 后当前 block 的大小不超过设定值;

如:System.out.println(conf.get("dfs.write.packet.size"));//结果是65536

3、chunk 是最小的一个单位,它是 DFSClient 到 DataNode 数据传输中进行数据校验的粒度,由io.bytes.per.checksum参数决定,默认是512B;注:事实上一个chunk还包含4B的校验值,因而chunk写入packet时是516B;数据与检验值的比值为128:1,所以对于一个128M的block会有一个1M的校验文件与之对应;

如:System.out.println(conf.get("io.bytes.per.checksum"));//结果是512


HDFS 的读操作

1)客户端通过 Distributed FileSystem 向 NameNode 请求下载文件,NameNode 通过查询元数据,找到文件块所在的 DataNode 地址。

2)挑选一台 DataNode(就近原则,然后随机)服务器,请求读取数据。

3)DataNode 开始传输数据给客户端(从磁盘里面读取数据输入流,以 Packet 为单位来做校验)。

4)客户端以Packet为单位接收,先在本地缓存,然后写入目标文件。

5)不断执行第 1 - 4 步直到数据全部读完。

6)客户端调用close ,关闭输入流DFS InputStream。



分享到:


相關文章: