При первом использовании Hadoop задание MapReduce не запускает фазу сокращения - PullRequest
5 голосов
/ 23 ноября 2010

Я написал простую задачу сокращения карт, которая будет считывать данные из DFS и запускать простой алгоритм на нем. При попытке отладки я решил просто заставить мапперы выводить один набор ключей и значений, а редукторы выводить совершенно другой набор. Я выполняю эту работу на кластере Hadoop 20.2 с одним узлом. Когда работа завершена, выходные данные содержат просто значения, которые были выведены преобразователями, что наводит меня на мысль, что редуктор не запускается. Я был бы очень признателен, если бы кто-нибудь дал понять, почему мой код производит такой вывод. Я попытался установить outputKeyClass и outputValueClass для разных вещей, а также setMapOutputKeyClass и setMapOutputValueClass для разных вещей. В настоящее время комментируемые разделы кода являются алгоритмом, который я запускаю, но я изменил карту и сократил методы для простого вывода определенных значений. Еще раз, выходные данные из задания содержат только те значения, которые были выведены картографом. Вот класс, который я использовал для выполнения задания:

import java.io.IOException; импорт java.util. *;

import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Job; import org.apache.hadoop.mapreduce.Mapper; import org.apache.hadoop.mapreduce.Reducer; import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; import org.apache.hadoop.util.GenericOptionsParser;

/ ** * * @author redbeard * / открытый класс CalculateHistogram {

public static class HistogramMap extends Mapper<LongWritable, Text, LongWritable, Text> {

    private static final int R = 100;
    private int n = 0;

    @Override
    public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        if (n == 0) {
            StringTokenizer tokens = new StringTokenizer(value.toString(), ",");
            int counter = 0;
            while (tokens.hasMoreTokens()) {
                String token = tokens.nextToken();
                if (tokens.hasMoreTokens()) {
                    context.write(new LongWritable(-2), new Text("HI"));
                    //context.write(new LongWritable(counter), new Text(token));
                }
                counter++;
                n++;
            }
        } else {
            n++;
            if (n == R) {
                n = 0;
            }

        }
    }
}

public static class HistogramReduce extends Reducer<LongWritable, Text, LongWritable, HistogramBucket> {

    private final static int R = 10;

    public void reduce(LongWritable key, Iterator<Text> values, Context context)
                                        throws IOException, InterruptedException {
        if (key.toString().equals("-1")) {
            //context.write(key, new HistogramBucket(key));
        }
        Text t = values.next();
        for (char c : t.toString().toCharArray()) {
            if (!Character.isDigit(c) && c != '.') {
                //context.write(key, new HistogramBucket(key));//if this isnt a numerical attribute we ignore it
            }
        }
        context.setStatus("Building Histogram");
        HistogramBucket i = new HistogramBucket(key);
        i.add(new DoubleWritable(Double.parseDouble(t.toString())));
        while (values.hasNext()) {
            for (int j = 0; j < R; j++) {
                t = values.next();
            }
            if (!i.contains(Double.parseDouble(t.toString()))) {
                context.setStatus("Writing a value to the Histogram");
                i.add(new DoubleWritable(Double.parseDouble(t.toString())));
            }
        }

        context.write(new LongWritable(55555555), new HistogramBucket(new LongWritable(55555555)));
    }
}

public static void main(String[] args) throws Exception {
    Configuration conf = new Configuration();
    String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();
    if (otherArgs.length != 2) {
        System.err.println("Usage: wordcount <in> <out>");
        System.exit(2);
    }

    Job job = new Job(conf, "MRDT - Generate Histogram");
    job.setJarByClass(CalculateHistogram.class);
    job.setMapperClass(HistogramMap.class);
    job.setReducerClass(HistogramReduce.class);

    //job.setOutputValueClass(HistogramBucket.class);

    //job.setMapOutputKeyClass(LongWritable.class);
    //job.setMapOutputValueClass(Text.class);

    FileInputFormat.addInputPath(job, new Path(otherArgs[0]));
    FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));

    System.exit(job.waitForCompletion(true) ? 0 : 1);
}

}

1 Ответ

11 голосов
/ 24 ноября 2010

неверна подпись вашего метода приведения.Подпись вашего метода содержит "Iterator ".Вы должны передать «Iterable ».

Ваш код не переопределяет метод Reduce базового класса Reducer.Из-за этого используется реализация по умолчанию, предоставляемая базовым классом Reducer.Эта реализация является функцией идентификации.

Используйте аннотацию @Override, чтобы предвидеть ошибки, подобные этой.

...