2011-12-16 15 views
6

Bu aptal bir soru gibi görünse IntWritable değil, ama söz konusu belirtildiği gibi ben HadoopYanlış anahtar sınıfı: problem olmasıdır Metin

benim mapreduce kodunda benim türlerinde sorunu görmek için başarısız Intwritable bekleniyor ama redüktörün collector.collect içindeki bir Text nesnesini geçiriyorum.

Mesleğim yapılandırması aşağıdaki mapper çıkış sınıfları vardır:

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

Ve aşağıdaki redüktör çıkış sınıfları:

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

:

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

Benim haritalama sınıfı aşağıdaki tanıma sahip Gerekli işlevle:

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

Ve sonra dediğim zaman başarısız:

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

Ben azaltmak harita için oldukça yeni ama her türlü, bu derler ama sonra söyleyerek satırda başarısız maç gibi onun bir IntWritable bekliyor küçültme sınıfının anahtarı olarak. ben burada

Hadoop'un

0.21 sürümünü kullanıyorum konularda ise benim haritası sınıftır:

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); 
     } 
    } 
} 

ve benim azaltmak sınıfı:

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); 
    } 
} 

ve işim yapılandırma:

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

iyi görünüyor ok olmalıdır (sizin durumunuzda IntWriteable, IntWritable) aynı anahtar/değer türü yayarlar gerekir. Postayı postalayabilir, haritalayabilir ve sınıfları azaltabilir misiniz? –

+0

Soruları harita ile güncelledim ve sınıfları azaltabilirim, ancak yeni bir veritabanı oluşturuyor ve posta sınıfının ne olduğunu bilmiyor muyum? Bunu, bu sınıfı içermediğini düşündüğüm WordCount örneğini değiştirerek yaptım. – user1084563

cevap

19

Sorununuz, Sınıfı birleştiriciyi

olarak ayarlamanızdır.
conf.setCombinerClass(Reduce.class); 

Birleştiricileri haritası aşamasında çalışacak ve bu satırı kaldırmak ve

+0

hmm, Bir an bunu deneyeceğim ve çalışıp çalışmadığını göreceğim, sadece bu satır WordCount örneğindeyim ve başka bir harita kullandığım işleri azalttım ve bir sorunum olmadı. – user1084563

+0

Henüz bitmedi, ancak sahip olduğum problemi kesinlikle aştı. Cevap kabul edildi. Yine de tek bir şey, neden hadoop web sitesinde WordCount örneğinde kullanılıyor? – user1084563

+1

Mappers ve Combiners'ın o/p'si Reducers'a beslenir. Kodda, birleştiricinin o/p'si Metin/IntWritable'dır ve redüktörün girdisi, eşleşmeyen IntWritable/IntWritable'dır, yani hata. Bu [makale] konusuna bakın (http://philippeadjiman.com/blog/2010/01/14/hadoop-tutorial-series-issue-4-to-use-or-not-to-use-a-combiner/) neden birleştiriciler. Özetle, harita görevlerinin yerel olarak mevcut olan veriler üzerinde daha fazla çalışma yapmasını sağlayarak ve daha az verinin redüktörlere aktarılmasını sağlayarak iş yöneticisini daha hızlı yapmak için kullanılırlar. –