2011-12-16 8 views
6

Może to wydawać się głupie pytanie, ale nie widzę problemu w moich typów w moim kodu mapreduce dla HadoopNiewłaściwy klasa klucz: Tekst nie jest IntWritable

Jak wskazano w pytaniu problem jest to, że oczekując IntWritable, ale przekazuję mu obiekt Text w kolektorze.kolorze reduktora.

Moja konfiguracja pracy ma następujące klasy wyjściowych Mapper:

conf.setMapOutputKeyClass(IntWritable.class); 
conf.setMapOutputValueClass(IntWritable.class); 

I następujących klas wyjściowe Reduktor

conf.setOutputKeyClass(Text.class); 
conf.setOutputValueClass(IntWritable.class); 

Moja klasa mapowanie ma następującą definicję:

public static class Reduce extends MapReduceBase implements Reducer<IntWritable, IntWritable, Text, IntWritable> 

z wymaganą funkcją:

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

A potem to się nie powiedzie, kiedy zadzwonić:

output.collect(new Text(),new IntWritable()); 

Jestem dość nowy map zmniejszyć ale wszystkie typy wydają się zgodne, kompiluje ale nie na tej linii mówiąc jej oczekiwał IntWritable jako klucz do klasy redukcji. Jeśli to ma znaczenie Używam 0,21 wersję Hadoop

Oto moja klasa mapa:

public static class Map extends MapReduceBase implements Mapper<LongWritable, Text, IntWritable, IntWritable> { 
    private IntWritable node = new IntWritable(); 
    private IntWritable edge = new IntWritable(); 

    public void map(LongWritable key, Text value, OutputCollector<IntWritable, IntWritable> output, Reporter reporter) throws IOException { 
     String line = value.toString(); 
     StringTokenizer tokenizer = new StringTokenizer(line); 

     while (tokenizer.hasMoreTokens()) { 
      node.set(Integer.parseInt(tokenizer.nextToken())); 
      edge.set(Integer.parseInt(tokenizer.nextToken())); 
      if(node.get() < edge.get()) 
       output.collect(node, edge); 
     } 
    } 
} 

i mój zmniejszyć klasa:

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

    IntWritable $ = new IntWritable(Integer.MAX_VALUE); 
    Text keyText = new Text(); 

    public void reduce(IntWritable key, Iterator<IntWritable> values, OutputCollector<Text, IntWritable> output, Reporter reporter) throws IOException { 
     ArrayList<IntWritable> valueList = new ArrayList<IntWritable>(); 

     //outputs original edge pair as key and $ for value 
     while (values.hasNext()) { 
      IntWritable value = values.next(); 
      valueList.add(value); 
      keyText.set(key.get() + ", " + value.get()); 
      output.collect(keyText, $); 
     } 

     //outputs all the 2 length pairs 
     for(int i = 0; i < valueList.size(); i++) 
      for(int j = i+1; i < valueList.size(); j++) 
       output.collect(new Text(valueList.get(i).get() + ", " + valueList.get(j).get()), key); 
    } 
} 

i moja konfiguracja pracy:

JobConf conf = new JobConf(Triangles.class); 
conf.setJobName("mapred1"); 

conf.setMapOutputKeyClass(IntWritable.class); 
conf.setMapOutputValueClass(IntWritable.class); 

conf.setOutputKeyClass(Text.class); 
conf.setOutputValueClass(IntWritable.class); 

conf.setMapperClass(Map.class); 
conf.setCombinerClass(Reduce.class); 
conf.setReducerClass(Reduce.class); 

conf.setInputFormat(TextInputFormat.class); 
conf.setOutputFormat(TextOutputFormat.class); 

FileInputFormat.setInputPaths(conf, new Path(args[0])); 
FileOutputFormat.setOutputPath(conf, new Path("mapred1")); 

JobClient.runJob(conf); 
+0

To wygląda dobrze. Czy mógłbyś opublikować pocztę, mapować i redukować klasy? –

+0

Właśnie zaktualizowałem pytanie o mapę i zmniejszyłem liczbę lekcji, chociaż jestem nowy w hadoop i nie wiem, co to jest klasa mail? Zrobiłem to, modyfikując przykład WordCount, który moim zdaniem nie obejmuje tej klasy. – user1084563

Odpowiedz

19

Twoim problemem jest ustawienie klasy Reduce jako sumatora

conf.setCombinerClass(Reduce.class); 

Combiners prowadzony w fazie mapy i muszą emitować tego samego typu klucz/wartość (IntWriteable, IntWritable w danym przypadku) usunąć tę linię i powinno być ok

+0

hmm, spróbuję to za chwilę i zobaczę czy to działa, zrobiłem to tylko dlatego, że ta linia jest w przykładzie WordCount i mam inną mapę redukującą zadania, które ją wykorzystały i nie miałem problemu. – user1084563

+0

To jeszcze nie koniec, ale zdecydowanie minął problem, który miałem. Odpowiedź została zaakceptowana. Tylko jedno, dlaczego jest użyty w przykładzie WordCount na witrynie hadoop? – user1084563

+1

O/p maperów i kombinatorów jest podawana Reduktorom. W kodzie o/p kombajnu znajduje się Text/IntWritable, a wejście do reduktora to IntWritable/IntWritable, które nie pasują, więc błąd. Zobacz ten [artykuł] (http://philippeadjiman.com/blog/2010/01/14/hadoop-tutorial-series-issue-4-to-use-or-not-to-use-a-combiner/) na dlaczego kombinatory. Podsumowując, są one wykorzystywane do przyspieszenia pracy, dzięki temu, że zadania mapowe wykonują więcej pracy nad danymi dostępnymi lokalnie i tym samym przenoszą mniej danych do reduktorów. –

Powiązane problemy