Hdfs 客户端读文件方式

256 阅读2分钟

Hdfs 客户端读文件方式

Hdfs 客户端支持多种读取方式,其中包括 readFully 和基于 pread 的读取,后者还引入了 hedgedRead 策略以优化读取性能。

1. readFully

  • 功能:直接定位到指定的数据块(block),并尝试读取该数据块中的所有内容。
  • 适用场景:适用于需要连续读取整个数据块的场景。

2. pread

  • 功能:基于特定的位置(position)来读取数据,允许指定从哪个字节开始读取以及需要读取多少个字节。
  • 子策略
    • pread(基于位置的读取):提供灵活的读取方式,适合随机访问文件内容的场景。
    • hedgedRead(对冲读取):一种优化读取性能的策略。
Hdfs hedgedRead

hedgedRead 通过同时启动多个读取线程来尝试从不同的数据节点(DN)或路径读取相同的数据块,以提高读取速度。具体流程如下:

  1. 第一次读取

    • 启动第一个线程进行读取操作。
    • 使用 poll(500ms) 判断该线程对应的 Future 是否成功完成。
    • 如果成功,则返回读取结果;如果失败,则在忽略列表中添加本次读取的数据节点,以便后续不再尝试从该节点读取。
  2. 第二次读取(若第一次失败或未达到性能要求)

    • 启动第二个线程
      • 选取另一个数据节点(DN)。
      • 构造 Callable 任务并提交至 hedgedService
      • 通过 hedgedService.take() 等待并获取第一个成功的结果。
      • 一旦获取到成功的结果,立即调用 cancelAll 取消其他所有正在进行的读取操作。
      • 如果所有尝试都失败,则忽略本次读取的数据节点。
    • 线程池拒绝情况
      • 如果线程池已满导致无法立即启动新线程,则当前线程会直接选取一个数据节点进行读取。
      • 后续处理流程与启动第二个线程相同。
  3. 重试机制

    • 如果所有尝试均未能成功读取数据(即 futures.isEmpty() 或捕获到 ExecutionExceptionCancellationException),则根据重试策略进行重试。

通过这种方式,hedgedRead 能够在网络条件不稳定或数据分布不均的情况下,通过并行读取来减少总体读取时间,提高读取性能。