读取流程
流程图:
1.客户端向NameNode发送读的请求
2.NameNode根据客户端的请求,根据内存索引查找客户端要查的文件对应的文件块,如果没有那么告诉客户端。如果有那么将文件块在那些服务器上以及具体的位置在哪儿告诉客户端。客户端根据namenode返回的信息,读取最近的服务器的文件。
1) 客户端调用 DistributedFileSystem 的 Open() 方法打开文件。
2) DistributedFileSystem 用 RPC 连接到 NameNode,请求获取文件的数据块的信息;NameNode 返回文件的部分或者全部数据块列表;对于每个数据块,NameNode 都会返回该数据块副本的
3) 客户端调用 FSDataInputStream 的 Read() 方法开始读取数据。
4) FSInputStream 连接保存此文件第一个数据块的最近的 DataNode,并以数据流的形式读取数据;客户端多次调用 Read(),直到到达数据块结束位置。
5) FSInputStream连接保存此文件下一个数据块的最近的 DataNode,并读取数据。
6) 当客户端读取完所有数据块的数据后,调用 FSDataInputStream 的 Close() 方法。
在读取数据的过程中,如果客户端在与数据结点通信时出现错误,则尝试连接包含此数据块的下一个数据结点。失败的数据结点将被记录,并且以后不再连接。
写入流程
流程图:
1.客户端向namenode请求写入操作,namenode首先确认权限,以及文件是否存在
2.确定完之后datanode返回数据块的信息,根据数据块的信息告诉客户端写到哪儿。
3.客户端根据namenode的信息将数据写到namenode返回信息的datanode上
4.datanode复制块数据
5.复制完成各个节点向namenode报告最新的块信息
6.datanode通知客户端写完成
1) 客户端调用 DistribuedFileSystem 的 Create() 方法来创建文件。
2) DistributedFileSystem 用 RPC 连接 NameNode,请求在文件系统的命名空间中创建一个新的文件;NameNode 首先确定文件原来不存在,并且客户端有创建文件的权限,然后创建新文件;DistributedFileSystem 返回 FSOutputStream 给客户端用于写数据。
3) 客户端调用 FSOutputStream 的 Write() 函数,向对应的文件写入数据。
4) 当客户端开始写入文件时,FSOutputStream 会将文件切分成多个分包(Packet),并写入其內部的数据队列。FSOutputStream 向 NameNode 申请用来保存文件和副本数据块的若干个 DataNode,这些 DataNode 形成一个数据流管道。
队列中的分包被打包成数据包,发往数据流管道中的第一个 DataNode。第一个 DataNode 将数据包发送给第二个 DataNode,第二个 DataNode 将数据包发送到第三个 DataNode。这样,数据包会流经管道上的各个 DataNode。
5) 为了保证所有 DataNode 的数据都是准确的,接收到数据的 DataNode 要向发送者发送确认包(ACK Packet)。确认包沿着数据流管道反向而上,从数据流管道依次经过各个 DataNode,并最终发往客户端。当客户端收到应答时,它将对应的分包从内部队列中移除。
6) 不断执行第 (3)~(5)步,直到数据全部写完。
7) 调用 FSOutputStream 的 Close() 方法,将所有的数据块写入数据流管道中的数据结点,并等待确认返回成功。最后通过 NameNode 完成写入。
来源:CSDN
作者:爱吃芝麻
链接:https://blog.csdn.net/weixin_43006131/article/details/104147072