如何从hadoop中的序列文件创建拆分?

p5fdfcr1  于 2021-05-29  发布在  Hadoop
关注(0)|答案(1)|浏览(400)

在hadoop中,我有一个3gb大小的序列文件。我想并行处理。因此,我将创建8个maptasks和8个filesplits。
filesplit类的构造函数需要:

Path of the file
Start position
Length

例如,第一次拆分可以从0开始,长度为3gb/8,下一次拆分可以从3gb/8开始,长度为3gb/8,依此类推。
现在sequencefile.reader有一个构造函数,它采用相同的方法:

Path of the file
Start position
Length

对于第一次拆分(从0开始,长度为3gb/8),序列文件能够读取它,因为它包含文件头、压缩类型以及有关键和值类的信息。
但是,对于其他拆分,sequencefile.reader无法读取拆分,因为,我认为,文件的该部分不包含序列文件的头(因为文件拆分不是从0开始的),因此在我尝试使用序列文件时,它会引发nullpointerexception。
那么有没有一种方法可以从序列文件中进行文件分割呢?

jdzmm42g

jdzmm42g1#

好吧,这个想法是sequencefile.reader的start和length参数不是用来指定序列文件的一部分,而是用来指定序列文件的真正开始和跨度(例如,如果您有一个容器文件,其中包含五个序列文件,您希望使用其中的一个,以便在容器文件中指定序列文件的开始和长度。或者如果你想从一个序列文件的开头读到一个特定的长度;但是,不可能将start设置为序列文件的中间,因为您将跳过序列文件的头,并且您将得到“not a sequence file error”,因此您必须将start参数设置为序列文件的开头)。
因此,解决方案是像往常一样以inputformat创建文件拆分:

new FileSplit(path, start, span, hosts);

您可以像往常一样在recordreader中创建序列读取器(无需指定开始或长度):

reader = new SequenceFile.Reader(fs, path, conf);// As usual
start = Split.getStart();
reader.sync(start);

这里的想法是“sync”,它跳过分割的“start”指定的字节数。
对于recordreader的nextkeyvalue:

if ((reader.getPosition() >= (start + span)) || !reader.next(key, value)) {
        return false;
    } else {
        return true;
    }

相关问题