Hadoop的倒没有索引文件名的复发(hadoop inverted-index without r

2019-07-29 03:34发布

我有什么输出是:

总之,文件----- ------ wordx文档2,文档1,文档1,文档1,文档1,文档1,文档1,文档1

我想要的是:

总之,文件----- ------ wordx文档2,文档1

public static class LineIndexMapper extends MapReduceBase
        implements Mapper<LongWritable, Text, Text, Text> {

    private final static Text word = new Text();
    private final static Text location = new Text();

    public void map(LongWritable key, Text val,
            OutputCollector<Text, Text> output, Reporter reporter)
            throws IOException {
        FileSplit fileSplit = (FileSplit) reporter.getInputSplit();
        String fileName = fileSplit.getPath().getName();
        location.set(fileName);

        String line = val.toString();
        StringTokenizer itr = new StringTokenizer(line.toLowerCase());
        while (itr.hasMoreTokens()) {
            word.set(itr.nextToken());
            output.collect(word, location);
        }
    }
}

public static class LineIndexReducer extends MapReduceBase
        implements Reducer<Text, Text, Text, Text> {

    public void reduce(Text key, Iterator<Text> values,
            OutputCollector<Text, Text> output, Reporter reporter)
            throws IOException {

        boolean first = true;
        StringBuilder toReturn = new StringBuilder();
        while (values.hasNext()) {
            if (!first) {
                toReturn.append(", ");
            }
            first = false;
            toReturn.append(values.next().toString());
        }

        output.collect(key, new Text(toReturn.toString()));
    }
}

为了获得最佳性能 - 我在哪里应该跳过重复的文件名? 地图,减少或两者兼而有之? PS:我现在正在准备写MR任务,并试图找出程序逻辑与我的问题是初学者。

Answer 1:

您将只能够消除在减速重复。 要做到这一点,你可以使用一组,不允许重复。

public void reduce(Text key, Iterator<Text> values,
        OutputCollector<Text, Text> output, Reporter reporter)
        throws IOException {

    // Text's equals() method should be overloaded to make this work
    Set<Text> outputValues = new HashSet<Text>();

    while (values.hasNext()) {
      // make a new Object because Hadoop may mess with original
      Text value = new Text(values.next());

      // takes care of removing duplicates
      outputValues.add(value);
    }

    boolean first = true;
    StringBuilder toReturn = new StringBuilder();
    Iterator<Text> outputIter = outputValues.iter();
    while (outputIter.hasNext()) {
        if (!first) {
            toReturn.append(", ");
        }
        first = false;
        toReturn.append(outputIter.next().toString());
    }

    output.collect(key, new Text(toReturn.toString()));
}

编辑:添加的值复制到设置为每克里斯的评论。



Answer 2:

您可以通过执行本地地图聚集和引进合并提高性能 - 基本上你想减少数据量的映射器和减速器之间传送

当地地图聚集在这里通过你保持LRU像图(或设置)输出对的概念。 根据你的情况为当前映射文件一组字(假设你有地图每一个单一的文件)。 这样,您就可以在该组查找单词,只输出K,V对如果一套没有包含这个词(表示你有没有为它已经输出的条目)。 如果设置不包含单词,输出的字,docID的对,并更新组字。

如果设置得太大(比如5000或10000项),然后将其清除出去,并重新开始。 这样一来,你会看到显着从映射值输出的数量(如果您的域值或一组值的小,也就是说是一个很好的例子)。

您也可以在合成阶段介绍你减速的逻辑太

一旦预警的最后一句话 - 要改变小心添加键/值对象成组(像马特D的答案),Hadoop的重新使用引擎盖下的对象,因此,如果您如果添加在得到意想不到的结果并不感到惊讶引用 - 总是创建对象的副本。

有当地地图聚集了一篇文章(对于字数的例子),你可能会发现有用:

  • http://wikidoop.com/wiki/Hadoop/MapReduce/Mapper#Map_Aggregation


文章来源: hadoop inverted-index without recurrence of file names