【问题标题】:How to create splits from a sequence file in Hadoop?如何从 Hadoop 中的序列文件创建拆分?
【发布时间】:2017-09-08 06:19:57
【问题描述】:

在 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。

那么有没有办法从序列文件中拆分文件?

【问题讨论】:

  • 你需要知道文件的块位置吗? (如果是这样,您可以使用“hdfs fsck -files -blocks -locations”来获取位置并发送到 8 个不同的地图,以便它们可以并行处理。
  • @DeepanRam 块与拆分不同。我想从序列文件中拆分文件以用于 map reduce 编程。
  • 现在我得到了您的要求,您可以使用 hadoop 的 SequenceFileInputFormat 并让它自己完成所有计算。我共享的命令将显示文件的总拆分(仅供参考),对于每个拆分,将生成一个地图任务。这也有助于我们计算将针对此输入文件生成多少地图。
  • @DeepanRam 感谢您提供信息,但我之前尝试过 SequenceFileInputFormat,我认为您无法使用它设置映射或拆分的数量。无论如何,我在下面发布了答案。请接受它作为答案,以帮助其他人看到解决方案。

标签: hadoop hadoop2 sequencefile filesplitting recordreader


【解决方案1】:

嗯,这个想法是 SequenceFile.Readerstartlength 参数不是用于指定序列文件的一部分,而是用于在序列文件上指定 真正的开始span(例如,如果您有一个包含五个序列文件的容器文件,并且您想使用其中一个,那么在该容器文件中指定序列文件的开始和长度。如果您想从序列文件的开头读取到特定长度;但是不能将开始设置为在序列文件的中间,因为你会跳过序列文件的头部,你会得到“不是序列文件错误”,因此你必须将开始参数设置为序列文件的开头。

因此,解决方案是像往常一样在 InputFormat 中创建文件拆分:

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

然后像往常一样在 RecordReader 中创建序列读取器(无需指定开始或长度):

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

这里的想法是“同步”,它跳过了拆分的“开始”指定的字节数。


对于 RecordReadernextKeyValue

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-14
    • 2012-08-27
    • 2015-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-21
    相关资源
    最近更新 更多