如何删除合成器输出并仅在mapreduce最终输出中保留reducer输出

时间:2017-03-31 10:30:33

标签: hadoop mapreduce hadoop2

您好我正在运行一个从HBase读取记录并写入文本文件的应用程序。

我在我的应用程序和自定义分区程序中也使用了combiner。我在我的应用程序中使用了41 reducer,因为我需要创建40个reducer输出文件,以满足我在自定义分区器中的条件。

一切正常,但是当我在我的应用程序中使用合并器时,它会为每个区域或每个映射器创建地图输出文件。

敌人示例我的应用程序中有40个区域,因此启动了40个映射器,然后创建了40个映射输出文件。但是reducer无法组合所有map-output并生成最终的reducer输出文件,这将是40个reducer输出文件。

文件中的数据是正确的,但没有文件增加。

任何想法我怎么才能得到reducer输出文件。

import java.io.IOException;
import org.apache.log4j.Logger;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.output.MultipleOutputs;

public class CommonCombiner extends Reducer<NullWritable, Text, NullWritable, Text> {

    private Logger logger = Logger.getLogger(CommonCombiner.class);
    private MultipleOutputs<NullWritable, Text> multipleOutputs;
    String strName = "";
    private static final String DATA_SEPERATOR = "\\|\\!\\|";

    public void setup(Context context) {
        logger.info("Inside Combiner.");
        multipleOutputs = new MultipleOutputs<NullWritable, Text>(context);
    }

    @Override
    public void reduce(NullWritable Key, Iterable<Text> values, Context context)
            throws IOException, InterruptedException {

        for (Text value : values) {
            final String valueStr = value.toString();
            StringBuilder sb = new StringBuilder();
            if ("".equals(strName) && strName.length() == 0) {
                String[] strArrFileName = valueStr.split(DATA_SEPERATOR);
                String strFullFileName[] = strArrFileName[1].split("\\|\\^\\|");

                strName = strFullFileName[strFullFileName.length - 1];


                String strArrvalueStr[] = valueStr.split(DATA_SEPERATOR);
                if (!strArrvalueStr[0].contains(HbaseBulkLoadMapperConstants.FF_ACTION)) {
                    sb.append(strArrvalueStr[0] + "|!|");
                }
                multipleOutputs.write(NullWritable.get(), new Text(sb.toString()), strName);
                context.getCounter(Counters.FILE_DATA_COUNTER).increment(1);


            }

        }
    }


    public void cleanup(Context context) throws IOException, InterruptedException {
        multipleOutputs.close();
    }
}

2 个答案:

答案 0 :(得分:0)

让我们清楚地了解基础知识

  1. Combiner是一种优化,可以在mapper和reduce中运行(reduce的合并阶段)(获取合并减少阶段)。

  2. 找出数据中键的分布,如果是的话,给定的映射器是否访问了大量相同的键,然后组合器正在帮助它,否则它没有任何效果。

  3. 1 K区域没有保证它们被平等分配。你有一些热门地区

  4. 找到热门区域并拆分。

  5. 请关注:http://bytepadding.com/big-data/map-reduce/understanding-map-reduce-the-missing-guide/

答案 1 :(得分:0)

您没有从合成器输出任何数据,以便减速器可以使用。在您使用的组合器中:

multipleOutputs.write(NullWritable.get(), new Text(sb.toString()), strName);

这不是你如何在阶段之间写出数据的方式,即从映射器或组合器到减少阶段。你应该使用:

context.write()

MultipleOutputs只是一种将额外文件写入磁盘的方法,您需要多个文件。我从来没有见过它在合成器中使用过。