客户端及与之交互的HDFS、namenode和datanode之间的数据流

HDFS文件读取

chatgpt 流式markdown 流式读取_读取数据

1.客户端调用FileSyste对象的open()方法在分布式文件系统中打开要读取的文件,对于HDFS来说,这个对象是DistributedFileSystem的一个实例

2.DistributedFileSystem通过使用远程过程调用(RPC)来调用namenode,确定文件起始块的位置。对于每一个块,namenode返回存有该块副本的datanode地址。此外,这些datanode根据它们与客户端的距离来排序(根据集群的网络拓扑)。如果该客户端本身就是一个datanode,那么该客户端将会从保存有相应数据块复本的本地datanode读取数据。

3.DistributedFileSystem类返回一个支持文件定位的输入流FSDataInputStream对象。FSDataInputStream对象接着封装DFSInputStream对象(该对象管理着datanode和namenode的I/O,存储着文件起始几个块的datanode地址),客户端对这个输入流调用read()方法。

4.DFSInputStream连接距离最近的文件中第一个块所在的datanode,通过反复调用read方法,将数据从datanode传输到客户端。

5.到达块的末端时,DFSInputStream关闭与该datanode的连接,寻找下一个块的最佳datanode。所有这些对于客户端都是透明的,在客户看来它一直在读取一个连续的流。

6.客户端完成读取,对FSDataInputStream调用close()方法关闭连接。

在读取数据的时候,如果DFSInputStream在与datanode通信时遇到错误,会尝试从这个块的另一个最邻近的datanode读取数据。它也会记住那个故障datanode,以保证以后不会反复读取该节点上后续的块。DFSInputStream也会通过校验和确认从datanode发来的数据是否完整。如果发现有损坏的块,DFSInputStream会试图从其他datanode读取其复本,也会将被损坏的块通知给namenode。

这个设计的一个重点是,客户端可以直接连接到datanode检索数据,且namenode告知客户端每个块所在的最佳datanode。读取的数据流分散在集群中的所有datanode,因此这种设计能使HDFS扩展到大量的并发客户端。namenode只需要响应块位置的请求(这些信息存储在内存中,因而非常高效),无需响应数据请求。