一、写数据流程:
- 客户端(Client通过java虚拟机)向NameNode请求上传文件(内部过程:客户端通过对 DistributedFileSystem 对象调用create()函数来创建文件),参数:路径/a.txt,块规格,副本数。
- NameNode检查目标文件是否已存在,父目录是否存在。做出响应返回是否可以上传。过程:1、namenode 执行各种不同的检查以确保这个文件不存在,并且客户端有创建该文件的权限。2、检查通过后, namenode就会为创建新文件记录一条记录并向客户端返回一个FSDataOutputStream 对象;否则,文件创建失败并向客户端抛出一个 IOException 异常。
- 客户端(Client)请求第一个 Block上传到哪几个DataNode服务器上。过程: FSDataOutputStream 封装一个 DFSoutPutstream 对象,该对象负责处理 datanode 和 namenode 之间的通信,将它分成一个个的数据包,并写入dataqueue。
- NameNode返回3个DataNode节点,分别为dn1、dn2、dn3。
- 客户端(Client)通过FSDataOutputStream模块请求dn1上传数据,dn1收到请求会继续调用dn2,然后dn2调用dn3,将这个通信管道建立完成。过程:DataStreamer 处理数据队列,它的责任是根据datanode 列表来要求 NameNode 分配适合的新块来存储数据备份。这一组DataNode 构成一个管线一一假设复本数为 3,所以管线中有 3 个节点。
- dn1、dn2、dn3逐级应答客户端。dn3响应dn2建立连接, dn2响应dn1建立连接,dn1响应客户端(Client)建立连接。
- 客户端(Client)开始往dn1上传第一个Block(先从磁盘读取数据放到一个本地内存缓存),以Packet为单位,dn1收到一个Packet就会传给dn2,dn2传给dn3;dn1每传一个packet会放入一个应答队列等待应答。过程:DataStreamer 将数据包流式传输到管线中第 1 个DataNode(dn1),该 DataNode(dn1) 存储数据包并将它发送到管线中的第 2 个 DataNode(dn2)。同样地,第 2 个 DataNode(dn2) 存储该数据包并且发送给管线中的第3个DataNode(dn3)DFSOutputStream 也维护着一个内部数据包队列来等待 DataNode 的收到确认回执,称为“确认队列”(ack queue)。当收到管道中所有 DataNode 确认信息后,该数据包才会从确认队列删除。
- 当一个Block传输完成之后,客户端(Client)再次请求NameNode上传第二个Block的服务器,直到文件写完。(重复执行3-7步)。
- 整个过程中,NameNode一直都在记录元数据(内存中、记操作日志到edits日志文件中)。
二、读数据流程:
- 客户端(Client)通过DistributedFileSystem向NameNode请求下载文件,NameNode通过查询元数据(包含块id、块大小、块偏移量,块存储位置dn1,2,3),找到文件块所在的DataNode地址。
- 挑选一台DataNode(就近原则,然后随机)服务器,请求读取数据。
- DataNode开始传输数据给客户端(Client)(从磁盘里面读取数据输入流,以Packet为单位来做校验)。
- 客户端(Client)以Packet为单位接收,先在本地缓存,然后写入目标文件。
- 第一块读取完毕,如果还需要读,客户端(Client)重复2-4步骤。
本文转载自: https://blog.csdn.net/weixin_47201365/article/details/128018892
版权归原作者 陈的打怪升级之道 所有, 如有侵权,请联系我们删除。
版权归原作者 陈的打怪升级之道 所有, 如有侵权,请联系我们删除。