2011-12-16 4 views
6

問題は、それがあるということですこれは愚かな質問のように見えるかもしれませんが、私はHadoopの間違ったキークラス:質問で述べたようにテキストがIntWritableない

のための私のMapReduceコードで私のタイプの問題を見ることができませんIntWritableを期待していますが、私はそれを減算器のcollector.collectのTextオブジェクトに渡しています。

マイジョブ構成は、以下のマッパー出力クラスがあります。

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

そして、次の減速機出力クラス:

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

は私のマッピングクラスの定義は、次のとおりです

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

必要な機能:

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

そして、私が呼ぶとき、それは失敗します。

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

私が軽減マッピングすることはかなり新しいですが、すべての型が一致するように見える、それはコンパイルしたが、その期待IntWritableを言って、その行に失敗します削減クラスの鍵としてそれが重要な場合は、私はここでのHadoop

の0.21バージョンを使用しています私のマップクラスである:

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

と私のクラス減らす:

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

と私の仕事の設定:

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

OKである必要があります。あなたはメールを投稿し、クラスをマップし、減らすことができます –

+0

私はhadoopを初めて使い、メールクラスが何であるか分かりませんが、マップで質問を更新してクラスを減らしましたか?私は、このクラスを含むとは思わないWordCountの例を変更しました。 – user1084563

答えて

19

あなたの問題は、コンバイナとしてReduceクラスを設定することです。

彼らは同じキー/値の型を放出する必要が3210
conf.setCombinerClass(Reduce.class); 

mapフェーズで実行コンバイナと(IntWriteable、あなたのケースでIntWritable) この行を削除し、それはよさそうだ

+0

ええと、私はそれを試してみて、それがうまくいくかどうかを見てみましょう。その行はWordCountの例であり、それを使った他のマップ削減ジョブがあり、問題はありませんでした。 – user1084563

+0

まだ走り終わっていませんが、私が持っていた問題をはっきりと過ぎました。回答が受け入れられました。しかし、ちょうど1つのこと、それはなぜhadoopウェブサイト上のWordCountの例で使用されていますか? – user1084563

+1

マッパーとコンビナのo/pは、Reducersに供給されます。コードでは、コンバイナのo/pはText/IntWritableであり、減速機への入力はIntWritable/IntWritableで一致しないので、エラーです。この[記事](http://philippeadjiman.com/blog/2010/01/14/hadoop-tutorial-series-issue-4-to-use-or-not-to-use-a-combiner/)を参照してくださいなぜコンバイナー。要約すると、地図タスクがローカルで利用可能なデータに対してより多くの作業を行うことによって、ジョブランナーをより速くするために使用され、それによってデータをより少ないレシピュータに転送します。 –

関連する問題