Hdfs 客户端读文件方式
Hdfs 客户端支持多种读取方式,其中包括 readFully 和基于 pread 的读取,后者还引入了 hedgedRead 策略以优化读取性能。
1. readFully
- 功能:直接定位到指定的数据块(block),并尝试读取该数据块中的所有内容。
- 适用场景:适用于需要连续读取整个数据块的场景。
2. pread
- 功能:基于特定的位置(position)来读取数据,允许指定从哪个字节开始读取以及需要读取多少个字节。
- 子策略:
- pread(基于位置的读取):提供灵活的读取方式,适合随机访问文件内容的场景。
- hedgedRead(对冲读取):一种优化读取性能的策略。
Hdfs hedgedRead
hedgedRead 通过同时启动多个读取线程来尝试从不同的数据节点(DN)或路径读取相同的数据块,以提高读取速度。具体流程如下:
-
第一次读取:
- 启动第一个线程进行读取操作。
- 使用
poll(500ms)判断该线程对应的Future是否成功完成。 - 如果成功,则返回读取结果;如果失败,则在忽略列表中添加本次读取的数据节点,以便后续不再尝试从该节点读取。
-
第二次读取(若第一次失败或未达到性能要求):
- 启动第二个线程:
- 选取另一个数据节点(DN)。
- 构造
Callable任务并提交至hedgedService。 - 通过
hedgedService.take()等待并获取第一个成功的结果。 - 一旦获取到成功的结果,立即调用
cancelAll取消其他所有正在进行的读取操作。 - 如果所有尝试都失败,则忽略本次读取的数据节点。
- 线程池拒绝情况:
- 如果线程池已满导致无法立即启动新线程,则当前线程会直接选取一个数据节点进行读取。
- 后续处理流程与启动第二个线程相同。
- 启动第二个线程:
-
重试机制:
- 如果所有尝试均未能成功读取数据(即
futures.isEmpty()或捕获到ExecutionException、CancellationException),则根据重试策略进行重试。
- 如果所有尝试均未能成功读取数据(即
通过这种方式,hedgedRead 能够在网络条件不稳定或数据分布不均的情况下,通过并行读取来减少总体读取时间,提高读取性能。