Hadoop-day07 HDFS的读写流程
作者:互联网
HDFS的读写流程(重点!)
写数据
写数据就是将客户端上的数据上传到HDFS
2.6.1 宏观过程
每一个block块都需要进行机架感知,得到block块以及副本的存储DN的节点,然后DN节点之间组成pipeline,然后客户端将block块拆分成多个packet,每个packet大小为64K,然后进行传输,先传输到pipeline第一个节点,然后在节点上留下ack状态,等待确认,当pipeline最后一个节点收到packet的时候反向反馈ack的true状态进行确认。按照这样的方式,将所有的block块存储到节点上去。直到最后一个block块中的最后一个packet传输的完毕的时候,客户端收到确认,关闭FSDataOutputStream通道,结束写流程。
1.客户端向HDFS发送写数据请求
hdfs dfs -put students.txt /shujia/
2. Filesystem通过rpc调用namenode的put方法
a. NN首先检查是否有足够的空间权限等条件创建这个文件,或者这个路径是否已经存在,权限
b. 有:NN会针对这个文件创建一个空的Entry对象,并返回成功状态给DFS
c. 没有:直接抛出对应的异常,给予客户端错误提示信息
3.如果DFS接收到成功的状态,会创建一个FSDataOutputStream的对象给客户端使用
4.客户端要向NN询问第一个Block存放的位置
NN通过机架感知策略 (node1 node 2 node3)
5.需要将客户端和DN节点创建连接
pipeline(管道) 客户端 和 node1 创建连接 socket node1 和 node2 创建连接 socket node2 和 Node3 创建连接 socket
6.客户端按照文件块切分数据,但是按照packet发送数据
默认一个packet大小为64K,Block128M为2048个packet7.客户端通过pipeline管道开始使用FDSOutputStream对象将数据输出
1. 客户端首先将一个 packet 发送给 node1, 同时给予 node1 一个 ack 状态 2. node1接受数据后会将数据继续传递给 node2, 同时给予 node2 一个 ack 状态 3. node2接受数据后会将数据继续传递给 node3, 同时给予 node3 一个 ack 状态 4. node3将这个 packet 接受完成后,会响应这个 ack 给 node2 为 true 5. node2会响应给 node1 , 同理 node1 响应给客户端
8.客户端接收到成功的状态 , 就认为某个 packet 发送成功了,直到当前块所有的 packet 都发送完成
1. 如果客户端接收到最后一个 pakcet 的成功状态 , 说明当前 block 传输完成,管道就会被撤销
2. 客户端会将这个消息传递给 NN , NN 确认传输完成
1. NN会将 block 的信息记录到 Entry, 客户端会继续向 NN 询问第二个块的存储位置 , 依次类推
block1 (node1 node2 node3)
block2 (node1 node3 node6)
....
blockn(node1 node4 node6)
- 当所有的 block 传输完成后, NN 在 Entry 中存储所有的 File 与 Block 与 DN 的映射关系关闭
FsDataOutPutStream
2.6.2 微观过程(如何保证package发送的时候不出错呢?)
1.客户端首先从自己的硬盘中以流的形式将自己的数据读取到缓存中
2.然后将缓存中的数据以chunk(512B)和checksum(4B)的方式放入到packet(64k)1. chunk:checksum=128:1 2. checksum:在数据处理和数据通信领域中,用于校验目的的一组数据项的和 3. Packet中的数据分为两类,一类是实际数据包,另一类是 header 包。 4. 一个 Packet 数据包的组成结构(分两类,一类是实际的数据包,另一类是header包。)
一个数据包的组成结构:
参数理解:
3.(默认生成的快,发送的慢)当packet满的时候添加到dataqueue
4.datastreamer开始从dataqueue队列上读取一个packet,通过FDSDataOPS发送到Poepleline
在取出的时候,也会将 packet 加入到 ackQueue, 典型的生产者消费者模式 客户端发送一个 Packet 数据包以后开始接收 ack ,会有一个用来接收 ack 的 ResponseProcessor 进
程,如果收到成功的 ack1. 如果某一个 packet 的 ack 为 true, 那么就从 ackqueue 删除掉这个 packet 2. 如果某一个 packet 的 ack 为 false, 将 ackqueue 中所有的 packet 重新挂载到 发送队列 , 重新发送
hadoop2.7.6中HDFS写数据流程(从微观角度出发)(面试题)
1、客户端通过Distributed FileSystem 模块的create()方法向NameNode请求上传文件,并告诉namenode上传文件的文件名、文件大小、文件拥有者,NameNode检查目标文件是否已存在,父目录是否存在;
2、NameNode 返回是否可以上传;
3、客户端请求我的第一个 Block 上传到哪几个 DataNode 服务器上;
4、NameNode 返回 3 个 DataNode 节点,分别为 dn1、dn2、dn3(每个文件块默认存储在三个DN副本上,分别是本地结点、同一个机架上的不同结点以及不同机架的任意一个结点);
5、客户端通过 FSDataOutputStream 模块的write()方法请求 dn1 上传数据,dn1 收到请求会继续调用 dn2,然后 dn2 调用 dn3,将这个通信管道建立完成。(注意:并不是由客户端分别往3个datanode上写3份,而是dn1开启额外线程去调用dn2,dn2去调用dn3);
6、dn1、dn2、dn3 逐级应答客户端;
7、客户端以 Packet 为单位,以chunk为检验,开始往 dn1 上传第一个 Block(先从磁盘读取数据放到一个本地内存缓存),dn1 收到一个 Packet 就会传给 dn2,dn2 传给 dn3;dn1 每传一个 packet 会放入一个应答队列等待应答;
8、当一个 Block 传输完成之后,客户端再次请求 NameNode 上传第二个 Block 的服务器。(重复执行 3-7 步)。
读数据
1.首先客户端发送请求到 DFS ,申请读取某一个文件
2.DFS 去 NN 查找这个文件的信息 ( 权限 , 文件是否存在 )
如果文件不存在,抛出指定的错误
如果文件存在,返回成功状态
3.DFS 创建 FSDataInputStream 对象,客户端通过这个对象读取数据
4.客户端获取文件第一个 Block 信息 , 返回 DN1 DN2 DN8
5.客户端直接就近原则选择 DN1 对应的数据即可
6.依次类推读取其他块的信息,直到最后一个块 , 将 Block 合并成一个文件
7.关闭 FSDataInputStream
标签:HDFS,NN,ack,day07,Hadoop,packet,dn2,node1,客户端 来源: https://www.cnblogs.com/f-1000/p/16413768.html