gpt4 book ai didi

java - Hadoop FileSplit 阅读

转载 作者:可可西里 更新时间:2023-11-01 15:17:43 25 4
gpt4 key购买 nike

假设一个客户端应用程序使用 FileSplit 对象来从相应文件中读取实际字节。

为此,必须通过如下代码从 FileSplit 创建一个 InputStream 对象:

    FileSplit split = ... // The FileSplit reference
FileSystem fs = ... // The HDFS reference

FSDataInputStream fsin = fs.open(split.getPath());

long start = split.getStart()-1; // Byte before the first

if (start >= 0)
{
fsin.seek(start);
}

流-1的调整存在于一些场景,如Hadoop MapReduce LineRecordReader类。但是,FSDataInputStream seek() 方法的文档明确指出,在搜索到某个位置后,下一次读取将从该位置开始,这意味着(?)上面的代码将关闭 1 个字节(?)。

那么,问题是,“-1”调整对于所有 InputSplit 读取情况是否都是必要的?

顺便说一下,如果想正确读取一个FileSplit,仅仅寻找它的开始是不够的,因为每个分割的结束点可能与实际HDFS的结束点不同文件。因此,相应的 InputStream 应该是“有界的”,即具有最大长度,如下所示:

    InputStream is = new BoundedInputStream(fsin, split.getLength());

在这种情况下,在上面创建了“本地”fsin steam 之后,将使用 org.apache.commons.io.input.BoundedInputStream 类,以实现“边界”。

更新

显然,只有 LineRecordReader 类中的用例行需要调整,它超出了拆分的边界以确保它读取完整的最后一行。

可以在 earlier question 中找到有关此问题的详细讨论。并在 MAPREDUCE-772 的评论中.

最佳答案

寻找位置 0 意味着下一次调用 InputStream.read() 将读取字节 0。寻找位置 -1 很可能会引发异常。

当您在示例和源代码中谈论标准模式时,您具体指的是哪里?

如您所见,拆分不一定有界 - 以 TextInputFormat 为例,文件可以拆分。处理拆分的记录读取器将:

  • 查找起始索引,然后找到下一个换行符
  • 找到下一个换行符(或 EOF)并将该“行”作为下一条记录返回

重复此过程,直到找到的下一个换行符超过拆分末尾,或者找到 EOF。所以你看到,在这种情况下,拆分的实际边界可能会从输入拆分给出的边界右移

更新

从 LineRecordReader 引用此代码块:

if (codec != null) {
in = new LineReader(codec.createInputStream(fileIn), job);
end = Long.MAX_VALUE;
} else {
if (start != 0) {
skipFirstLine = true;
--start;
fileIn.seek(start);
}
in = new LineReader(fileIn, job);
}
if (skipFirstLine) { // skip first line and re-establish "start".
start += in.readLine(new Text(), 0,
(int)Math.min((long)Integer.MAX_VALUE, end - start));
}

--start 语句很可能是为了避免拆分从换行符开始并返回一个空行作为第一条记录。您可以看到,如果发生查找,则会跳过第一行以确保文件拆分不会返回重叠记录

关于java - Hadoop FileSplit 阅读,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16180130/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com