2013-01-07 1 views
1

J'ai écrit un partitionnement personnalisé mais je ne parviens pas à le définir sur l'objet JobConf dans la classe principale.Impossible de définir partitoner à l'objet JobConf

import org.apache.hadoop.io.Text; 
import org.apache.hadoop.mapreduce.Partitioner; 

public class FirstCharTextPartitioner extends Partitioner<Text, Text> { 

    @Override 
    public int getPartition(Text key, Text value, int numReduceTasks) { 
     return (key.toString().charAt(0)) % numReduceTasks; 
    }  
} 

Mais lorsque je tente de la mettre à l'objet JobConf, je reçois l'erreur suivante.
La méthode setPartitionerClass (classe) dans le JobConf type n'est pas applicable pour les arguments (classe)

public class WordCount { 

    public static class Map extends MapReduceBase implements Mapper<LongWritable, Text, Text, IntWritable> { 
     private final static IntWritable one = new IntWritable(1); 
     private Text word = new Text(); 

     public void map(LongWritable key, Text value, OutputCollector<Text, IntWritable> output, Reporter reporter) throws IOException { 
      String line = value.toString(); 
      String[] tokens = line.split("\\s"); 
      for (String token : tokens) { 
       word.set(token); 
       output.collect(word, one); 
      } 
     } 
    } 

    public static class Reduce extends MapReduceBase implements Reducer<Text, IntWritable, Text, IntWritable> { 
     public void reduce(Text key, Iterator<IntWritable> values, OutputCollector<Text, IntWritable> output, Reporter reporter) throws IOException { 
      int sum = 0; 
      while (values.hasNext()) { 
       sum += values.next().get(); 
      } 
      output.collect(key, new IntWritable(sum)); 
     } 
    } 

    public static void main(String[] args) throws Exception { 
     JobConf conf = new JobConf(WordCount.class); 
     conf.setJobName("wordcount"); 

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

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

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

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

     JobClient.runJob(conf); 
    } 
} 

Quelqu'un peut-il s'il vous plaît me dire ce que je fais mal?

Répondre

2

Vous importez le nouveauorg.apache.hadoop.mapreduce.Partitioner.

Vous devez mettre en œuvre l'ancienne interface org.apache.hadoop.mapred.Partitioner, comme ceci:

import org.apache.hadoop.io.Text; 
import org.apache.hadoop.mapred.Partitioner; 

public class FirstCharTextPartitioner implements Partitioner<Text, Text> { 

    @Override 
    public int getPartition(Text key, Text value, int numReduceTasks) { 
     return (key.toString().charAt(0)) % numReduceTasks; 
    }  
} 
+0

Merci, qui a fait l'affaire. Mais pouvez-vous s'il vous plaît expliquer à quoi sert le nouveau Partitioner? – aa8y

+0

@Expressions_Galore C'est la même chose, mais la classe abstraite est basée sur la "nouvelle" API mapreduce. L'ancien est basé sur des interfaces alors que le nouveau est basé sur des classes abstraites pour être plus facilement extensible pour une utilisation future. –

+0

Donc, si je veux utiliser le nouveau Partitioner, comment puis-je modifier le code? – aa8y

Questions connexes