Программа сокращения карт Hadoop

Когда я пытался использовать пример программирования Map Reduce из книги Hadoop in Action на основе Hadoop 0.20 API, я получил сообщение об ошибке

java.io.IOException: несоответствие типов в значении из карты: ожидаемый org.apache.hadoop.io.IntWritable, полученный org.apache.hadoop.io.Text

Но, насколько я проверял, я передаю все правильно. Было бы очень полезно, если бы кто-нибудь помог мне с этим.

Вот код. Это тот же код, что и в книге.

@SuppressWarnings("unused")
public class CountPatents extends Configured implements Tool {
    @SuppressWarnings("deprecation")

    public static class MapClass extends MapReduceBase implements Mapper<Text, Text, Text, Text> {
        public void map(Text key, Text value,OutputCollector<Text, Text> output,Reporter reporter) throws IOException {
            output.collect(value, key);
        }
    }
public static class Reduce extends MapReduceBase implements Reducer<Text, Text, Text, IntWritable> {
    public void reduce(Text key, Iterator<Text> values, OutputCollector<Text, IntWritable> output, Reporter reporter) throws IOException {
        int count=0;
        while(values.hasNext()){
            count=count+1;

            values.next();

        }


        output.collect(key, new IntWritable(count));
    }
}


    public int run(String[] args) throws Exception {

    Configuration conf = getConf();
    JobConf job = new JobConf(conf, CountPatents.class);
    Path in = new Path(args[0]);
    Path out = new Path(args[1]);
    FileInputFormat.setInputPaths(job, in);
    FileOutputFormat.setOutputPath(job, out);
    job.setJobName("MyJob");
    job.setMapperClass(MapClass.class);
    job.setReducerClass(Reduce.class);
    job.setInputFormat(KeyValueTextInputFormat.class);
    job.setOutputFormat(TextOutputFormat.class);
    job.setOutputKeyClass(Text.class);
    job.setOutputValueClass(Text.class);
    job.set("key.value.separator.in.input.line", ",");
    JobClient.runJob(job);
    return 0;
    }
    public static void main(String[] args) throws Exception {
        int res = ToolRunner.run(new Configuration(), new CountPatents(), args);
        System.exit(res);


    }

    }

person Sri    schedule 23.03.2011    source источник


Ответы (5)


На первый взгляд (не выполняя код локально), похоже, что вы настраиваете вывод задания на тип Text, когда вы устанавливаете job.setOutputValueClass(Text.class);, но тип вывода на вашем редукторе установлен на IntWritable. Вероятно, это ошибка.

person tau-neutrino    schedule 23.03.2011
comment
Я согласен. Hadoop заставляет вас повторять типы для ваших ключей в трех местах — определение преобразователя, определение преобразователя и конфигурация задания. Все три должны совпадать для запуска задания. - person Mark Tozzi; 24.03.2011
comment
Я пытался это сделать, но это не сработало. Затем я преобразовал программу так, чтобы ввод и вывод были в основном только текстовыми. Это сработало!! - person Sri; 25.03.2011

Пропущенный вызов:

job.setMapOutputValueClass(IntWritable.class);

Та же проблема с использованием нового интерфейса 0.20 и нового объекта «Работа» вместо JobConf.

person Mojo    schedule 31.05.2011

Ошибка должна быть на выходе из редуктора:

Ваше определение класса восстановления выглядит следующим образом:

общедоступный статический класс Reduce расширяет MapReduceBase, реализует Reducer

поэтому выходное значение должно быть типа IntWritable.

Однако вы упомянули job.setOutputValueClass(Text.class);

Итак, в соответствии с конфигурацией вывод редуктора должен быть текстом.

Решение: в конфигурации добавьте следующие строки job.setMapOutputKeyClass(Text.class); job.setMapOutputValueClass(IntWritable.class);

и изменить: job.setOutputValueClass(IntWritable.class);

Затем попробуйте запустить

person Sourav Gulati    schedule 18.03.2013

Карта излучает ‹ Текст,Текст >

Итак, установите

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

setMapOutputKeyClass setMapOutputValueClass

person Arun A K    schedule 05.12.2013

В вашей функции редуктора вы используете OutputCollector, что означает, что класс выходного ключа будет иметь тип Text, а класс выходного значения будет иметь тип IntWritable. Однако в основной (выполняемой) функции вы установили job.setOutputKeyClass(Text.class); job.setOutputValueClass(Text.class);.

Измените job.setOutputValueClass(Text.class) на job.setOutputValueClass(IntWritable.class), и все готово!

Также всегда лучше установить MapperOutputKeyType и MapperOutputValueType, чтобы избежать каких-либо расхождений. Hadoop использует механизм, основанный на интерфейсе Writable, вместо собственного механизма сериализации Java. В отличие от механизма сериализации Java, этот метод не инкапсулирует имя класса в сериализованный объект. Следовательно, для создания экземпляров этих классов из преобразователя в редюсер требуется явное имя класса, поскольку невозможно десериализовать массивы байтов, представляющие экземпляры с возможностью записи, не зная, что класс десериализуется в (входной ключ редьюсера и экземпляр значения). Эта информация должна быть явно предоставлена ​​путем вызова setMapOutputKeyClass и setMapOutputValueClass в экземпляре задания.

person Coding beginner    schedule 20.07.2017