如何在 Mapreduce 中为 1 个文本文件设计 1 个映射器

how to design 1 mapper for 1 text file in Mapreduce

我是 运行 Hadoop 2.9.0 上的 Mapreduce。

我的问题:

我有很多文本文件(大约 10-100 个文本文件)。每个文件的大小都非常小,但由于我的逻辑问题,我需要 1 个映射器来处理 1 个文本文件。这些映射器的结果将由我的缩减器聚合。

我需要进行设计,使映射器的数量始终等于文件的数量。如何在 Java 代码中做到这一点?我需要扩展什么样的功能?

非常感谢。

我不得不做一些非常相似的事情,并且遇到了与您相似的问题。 我实现这一点的方法是输入一个包含每个文件路径的文本文件,例如文本文件将包含这种信息:

/path/to/filea
/path/to/fileb
/a/different/path/to/filec
/a/different/path/to/another/called/filed

我不确定您究竟希望您的映射器做什么,但是在创建作业时,您希望执行以下操作:

public static void main( String args[] ) {
    Job job = Job.getInstance(new Configuration(), 'My Map reduce application');
    job.setJarByClass(Main.class);
    job.setMapperClass(CustomMapper.class);
    job.setInputFormatClass(NLineInputFormat.class);
    ...
}

您的 CustomMapper.class 将像这样扩展 Mapper:

public class CustomMapper extends Mapper<LongWritable, Text, <Reducer Key>, <Reducer Value> {

    public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        Configuration configuration = context.getConfiguration();
        ObjectTool tool = new ObjectTool(configuration, new Path(value.toString()));

        context.write(<reducer key>, <reducer value>);
    }

}

其中 ObjectTool 是另一个 class,它处理您实际想要对文件执行的操作。

所以让我大致解释一下这是做什么的,这里的魔法是 job.setInputFormatClass(NLineInputFormat.class),但它到底在做什么?

它本质上是获取您的输入并按每一行拆分数据,然后将每一行发送到映射器。通过让一个包含每个文件的文本文件换行,您可以在映射器和文件之间创建 1:1 关系。此设置的一个重要补充是它允许您为要处理的文件创建高级工具。

我用它在 HDFS 中创建了一个压缩工具,当我研究这个方法时,很多人基本上是将文件读取到 stdout 并以这种方式压缩它,然而,当涉及到做一个对原始文件和被压缩和解压的文件进行校验,结果是不同的。这是由于这些文件中的数据类型,并且没有简单的方法来实现字节可写。 (可以看到文件的cat'ing信息到std out here).

link 还引用了以下内容:

org.apache.hadoop.mapred.lib.NLineInputFormat is the magic here. It basically tells the job to feed one file per maptask

希望对您有所帮助!