HDFS读写流程

两个重要概念:

NameNode:领导级别。管理数据块映射;处理客户端的读写请求;配置副本策略;管理HDFS的名称空间;
 
DataNode:员工级别。负责存储客户端发来的数据块block;执行数据块的读写操作。

写流程

写详细步骤:
1、首先向namenode通信,请求上传文件,namenode检查目标文件是否已存在,父目录是否存在 ,还得看看是否有上传的权限,说白了,就是判断是否可以上传
2、namenode返回是否可以上传 ,如果可以,client会先对文件进行切分(逻辑切分)
3、客户端请求第一个 Block上传到哪几个DataNode服务器上。
4、NameNode返回3个DataNode节点,分别为dn1、dn2、dn3。
5、客户端通过FSDataOutputStream模块请求dn1上传数据,dn1收到请求会继续调用dn2,然后dn2调用dn3,将这个通信管道建立完成。
6、dn1、dn2、dn3逐级应答客户端。
7、客户端开始往dn1上传第一个Block(先从磁盘读取数据放到一个本地内存缓存),以Packet为单位,dn1收到一个Packet就会传给dn2,dn2传给dn3;dn1每传一个packet会放入一个应答队列等待应答。
8、当一个Block传输完成之后,客户端再次请求NameNode上传第二个Block的服务器。(重复执行3-7步)。
9、传输完毕之后,客户端关闭流资源,并且会告诉hdfs数据传输完毕,然后hdfs收到传输完毕就恢复元数据

具体概念介绍

Distributed FileSystem:进行抽象封装,FileSystem会利用JDK的反射机制创建一个DistributedFileSystem实例(对象),然后调用它的initialize()方法

逻辑切分:客户端并没有将文件真正切分,只是画了个标志线加以区分

写操作,上传文件,所以本地是输入流,hdfs是输出流

第三步有哪几个DataNode服务器上:这里指副本数,设置了几个副本,就返回几个DataNode(记住数据是存储在DataNode)我设置了三个副本,所以,返回三个;

同时,返回的DataNode也有一定规矩,首先第一个DataNode是距离客户端最近的,后两个是根据第一个选出,产生了两个问题,如何判断最近,以及如何根据第一个选,这个请看: 拓扑距离和机架感知.

第七步,packet为单位,每个64KB

传输Packet:dn1收到之后,一边往本地落盘,一边传给dn2,之后的dn2同理,当dn3落盘结束之后,它将成功信息发给dn2,之后dn2需要等自己成功并且收到dn3成功信息之后,将成功信息发给dn1,同理,dn1在接收到dn2成功信息并且自己落盘成功之后发给客户端,此时一个packet就成功了;注意packet不是逐个发的,是一个队列同时发的,成功了,在队列里删除掉,这样全部packet发完,第一块就传完了,接着传第二块,第二次选择的DataNode可能和第一次一样,也可能不一样

传输过程中几种失败可能:

1.在建立通道时失败,这样直接上传失败,直接抛异常
2.在传输数据过程中失败:
1).客户端传输Packet到第一个DataNode过程中失败就上传失败
2)dn1与dn2或者dn2与dn3之间的传输Packet失败,上传仍然进行,并且传出成功信号,因为即使这两个过程失败了,副本数就变成1了,hdfs有高容错性,副本丢失,第一个DataNode会触发自动备份,自动寻找两个DataNode

读流程

1)客户端通过Distributed FileSystem向NameNode请求下载文件,NameNode通过查询元数据,找到文件块所在的DataNode地址。
2)挑选一台DataNode(就近原则,然后随机)服务器,请求读取数据。
3)DataNode开始传输数据给客户端(从磁盘里面读取数据输入流,以Packet为单位来做校验)。
4)客户端以Packet为单位接收,先在本地缓存,然后写入目标文件。
5)下载完第一块,在重复上面2.3步下载

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

通过校验和。因为每个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

in_use.lock表示DataNode正在对文件夹进行操作
rbw是“replica being written”的意思,该目录用于存储用户当前正在写入的数据。
Block元数据文件(*.meta)由一个包含版本、类型信息的头文件和一系列校验值组成。校验和也正是存在其中。
posted @ 2021-12-13 10:38  魏阳晨  阅读(681)  评论(0)    收藏  举报
AmazingCounters.com