2013-04-23 90 views
1

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

为了这样做,一个InputStream对象必须被从FileSplit创建的,通过这样的代码:

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存在于像HadoopMapReduceLineRecordReader类的一些场景。然而,FSDataInputStreamseek()方法的文档明确指出,在寻找位置之后,下一次读取将来自该位置,这意味着(?)上面的代码将是1字节关闭(?)。

所以,问题是,所有InputSplit阅读案例都需要“-1”调整吗?

顺便说一句,如果有人想正确读取FileSplit,寻求其启动是不够的,因为每个拆分也有一个结束可能不是实际的HDFS文件的结尾相同。所以,相应的InputStream应“界定”,即具有最大的长度,如下所示:

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

在这种情况下,“本地” fsin蒸汽上面已经创建之后,org.apache.commons.io.input.BoundedInputStream类用于,实施“界限”。

UPDATE

显然,调整是必要只用例一线LineRecordReader类,超过分割的界限,以确保它读取完整的最后一行的一个。

关于此问题的更多详细信息,请参阅earlier questionMAPREDUCE-772的评论。

回答

2

寻求位置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声明最有可能处理的是避免在换行符上开始拆分并将空行作为第一条记录返回。您可以看到,如果发生搜索,则会跳过第一行以确保文件拆分不会返回重叠记录

+0

上面的代码不会搜索到-1,而是以-1开头,即前一个字节第一场之后每场比赛开始。当然,TextInputFormat使用的LineRecordReader正如你所说的那样工作,因为它总是读取至少多出一个字节,并且一直延续到行尾。也许-1是为了解决这个问题。 – PNS 2013-04-24 00:09:13

+0

你能指点我的源/展示此-1寻求行为的示例 – 2013-04-24 00:25:13

+0

第59行http://javasourcecode.org/html/open-source/hadoop/hadoop-1.0.3/org/apache/hadoop/mapreduce/ lib/input/LineRecordReader.java.html并不寻求开始 - 1 ... – 2013-04-24 00:27:30