Hadoop 之 数据流——客户端与HDFS,namenode和datanode 之间的数据流

时间:2023-01-19 08:33:14

1.文件读取

Hadoop 之 数据流——客户端与HDFS,namenode和datanode 之间的数据流

  • 客户端通过调用 FileSystem 对象的 open() 方法来打开想读取的文件,对于 HDFS 来说,这个对象是分布式文件系统(DistributedFileSystem)的一个实例,如上图步骤1。
  • DistributedFileSystem 通过使用 RPC 来调用 namenode ,获取文件的存储位置,以确定文件起始块的位置,如上图步骤2。namenode 返回文件所有组成块的副本的 datanode 地址。并且这些 datanode 地址信息是已经排过序的。
  • DistributedFileSystem 的 open() 方法返回一个 FSDataInputStream 对象给客户端读取数据。FSDataInputStream 类封装了DFSInputStream 对象,该对象管理着 datanode 和 namenode 的 I/O。
  • 接着,客户端对 FSDataInputStream 对象调用 read() 方法。

2.文件写入

Hadoop 之 数据流——客户端与HDFS,namenode和datanode 之间的数据流

  • 客户端通过对 DistributedFileSystem 对象调用 create() 函数来新建文件。如图步骤1;
  • DistributedFileSystem 对 namenode 创建一个 RPC 调用,在文件系统的命名空间中新建一个文件,此时还没有对应的数据块,如图步骤2;
    namenode 执行各种不同的检查以确保这个文件不存在以及客户端有新建该文件的权限。如果检查通过,namenode 就会为创建新文件记录一条记录;否则,文件创建失败并向客户端抛出一个 IOException 异常。
    DistributedFileSystem 向客户端返回一个 FSDataOutputStream 对象,由此客户端可以开始写数据。
  • DFSOutputStream 将它分成一个个数据包,并写入到内部队列,称为“数据队列”(data queue)。DataStreamer 处理数据队列,它的责任是根据 datanode 队列表来要求 namenode 分配适合的新块来存储数据复本。这一组 datanode 构成一个管线–假设复本数为3。DataStreamer 将数据包流式传送到管线中第1个 datanode ,该 datanode 存储数据并发送到管线中的第 2 个 datanode ,第 2 个 datanode 存储数据包并发送到管线中的第 3 个datanode。
    DFSOutputStream 也维护一个内部数据包队列来等待 datanode 的收到确认回执,称为“确认队列”。
  • 客户端完成数据写入后,对数据流调用 close() 方法。