2011-03-23 75 views
1

當我試圖地圖從Hadoop的行動本書基於Hadoop的0.20 API我得到了錯誤的Hadoop的Map Reduce程序

java.io.IOException的減少編程例如:預計組織:從地圖中值類型不匹配。 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); 


    } 

    } 

回答

7

從快看(不運行本地代碼),它看起來像您正在設置作業的輸出是Text類型,當你設置job.setOutputValueClass(Text.class);,但對你的減速機的輸出類型設置爲IntWritable。這可能是錯誤。

+1

上同時調用setMapOutputKeyClass和setMapOutputValueClass來顯式提供。 Hadoop強制您在三個地方重複鍵的類型 - 映射器定義,還原器定義和作業配置。所有三個人必須匹配才能運行。 – 2011-03-24 00:40:09

+0

我試過這樣做,但沒有奏效。然後我轉換程序,使輸入和輸出基本上只是文本。這工作! – Sri 2011-03-25 04:46:18

0

未接呼叫:

job.setMapOutputValueClass(IntWritable.class);

使用新的0.20接口和新的「Job」對象代替JobConf時出現同樣的問題。

0

誤差應在輸出減速機:

你毒害的耐受類認定中的如下:

公共靜態類減少擴展MapReduceBase實現減速

所以輸出值應IntWritable類型。

但是,您已經提到了 job.setOutputValueClass(Text.class);

所以根據配置,減速器的輸出應該是文本。

解決方案: 在配置中,添加以下行 job.setMapOutputKeyClass(Text.class); job.setMapOutputValueClass(IntWritable.class);

和修改: job.setOutputValueClass(IntWritable.class);

然後嘗試運行

0

在你的減速功能,您使用的OutputCollector這意味着輸出鍵類將是Text和輸出值類將是IntWritable類型。 但是在main(run)函數中,你已經設置了job.setOutputKeyClass(Text.class); job.setOutputValueClass(Text.class);.

變化job.setOutputValueClass(Text.class)到job.setOutputValueClass(IntWritable.class),你是好去!

此外,最好設置MapperOutputKeyType和MapperOutputValueType以避免任何差異。 Hadoop使用基於Writable接口的機制,而不是原生的Java序列化機制。與Java序列化機制不同,此方法不會將類名封裝在序列化實體中。因此,需要顯式的類名來將這些類從Mapper實例化爲Reducer,因爲在不知道類被反序列化爲(Reducer輸入鍵和值實例)的情況下,不可能反序列化表示Writable實例的字節數組。這些信息需要通過在Job實例