2013-06-23 11 views
14

Próbuję uruchomić mapę/reduktor w java. Poniżej znajdują się moje plikiNiezgodność typu klucz z mapy: oczekiwany org.apache.hadoop.io.Text, recieved org.apache.hadoop.io.LongWritable

WordCount.java

package counter; 


public class WordCount extends Configured implements Tool { 

public int run(String[] arg0) throws Exception { 
    Configuration conf = new Configuration(); 

    Job job = new Job(conf, "wordcount"); 

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

    job.setMapperClass(WordCountMapper.class); 
    job.setReducerClass(WordCountReducer.class); 

    job.setInputFormatClass(TextInputFormat.class); 
    job.setOutputFormatClass(TextOutputFormat.class); 

    FileInputFormat.addInputPath(job, new Path("counterinput")); 
    // Erase previous run output (if any) 
    FileSystem.get(conf).delete(new Path("counteroutput"), true); 
    FileOutputFormat.setOutputPath(job, new Path("counteroutput")); 

    job.waitForCompletion(true); 
    return 0; 
} 

public static void main(String[] args) throws Exception { 
    int res = ToolRunner.run(new Configuration(), new WordCount(), args); 
    System.exit(res); 

    } 
} 

WordCountMapper.java

public class WordCountMapper extends 
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, InterruptedException { 
     System.out.println("hi"); 
    String line = value.toString(); 
    StringTokenizer tokenizer = new StringTokenizer(line); 
    while (tokenizer.hasMoreTokens()) { 
     word.set(tokenizer.nextToken()); 
     output.collect(word, one); 
     } 
    } 
} 

WordCountReducer.java

public class WordCountReducer extends Reducer<Text, IntWritable, Text, IntWritable> { 
    public void reduce(Text key, Iterator<IntWritable> values, 
     OutputCollector<Text,IntWritable> output, Reporter reporter) throws IOException, InterruptedException { 
     System.out.println("hello"); 
     int sum = 0; 
     while (values.hasNext()) { 
      sum += values.next().get(); 
     } 
     output.collect(key, new IntWritable(sum)); 
    } 
} 

otrzymuję następujący błąd

13/06/23 23:13:25 INFO jvm.JvmMetrics: Initializing JVM Metrics with 
processName=JobTracker, sessionId= 

13/06/23 23:13:25 WARN mapred.JobClient: Use GenericOptionsParser for parsing the 
arguments. Applications should implement Tool for the same. 
13/06/23 23:13:26 INFO input.FileInputFormat: Total input paths to process : 1 
13/06/23 23:13:26 INFO mapred.JobClient: Running job: job_local_0001 
13/06/23 23:13:26 INFO input.FileInputFormat: Total input paths to process : 1 
13/06/23 23:13:26 INFO mapred.MapTask: io.sort.mb = 100 
13/06/23 23:13:26 INFO mapred.MapTask: data buffer = 79691776/99614720 
13/06/23 23:13:26 INFO mapred.MapTask: record buffer = 262144/327680 
13/06/23 23:13:26 WARN mapred.LocalJobRunner: job_local_0001 
java.io.IOException: Type mismatch in key from map: expected org.apache.hadoop.io.Text, 
recieved org.apache.hadoop.io.LongWritable 
at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.collect(MapTask.java:845) 
at org.apache.hadoop.mapred.MapTask$NewOutputCollector.write(MapTask.java:541) 
at org. 
apache.hadoop.mapreduce.TaskInputOutputContext.write(TaskInputOutputContext.java:80) 
at org.apache.hadoop.mapreduce.Mapper.map(Mapper.java:124) 
at org.apache.hadoop.mapreduce.Mapper.run(Mapper.java:144) 
at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:621) 
at org.apache.hadoop.mapred.MapTask.run(MapTask.java:305) 
at org.apache.hadoop.mapred.LocalJobRunner$Job.run(LocalJobRunner.java:177) 
13/06/23 23:13:27 INFO mapred.JobClient: map 0% reduce 0% 
13/06/23 23:13:27 INFO mapred.JobClient: Job complete: job_local_0001 
13/06/23 23:13:27 INFO mapred.JobClient: Counters: 0 

Myślę, że nie jest w stanie znaleźć klasy Mapper i reduktor. Napisałem kod w głównej klasie, Otrzymuję domyślną Mapper i klasę reduktora.

Odpowiedz

32

Dodaj te 2 linie w kodzie:

job.setMapOutputKeyClass(Text.class); 
job.setMapOutputValueClass(IntWritable.class); 

Używasz TextOutputFormat który emituje klawisz LongWritable i wartości tekstowe domyślnie, ale emitują Tekst jako klucz i IntWritable jako wartości. Musisz powiedzieć to rodzinie.

HTH

+0

Mam te 2 linie w moim głównym pliku – Neil

+0

Nie widzę ich .. Jest ustawiony "Map" OutputKeyClass – Tariq

+0

Przepraszam. Mój błąd. Próbowałem to zrobić. Ale wciąż daje ten sam błąd. – Neil

6

To może nie być twój problem, ale raz miałem ten głupi problem. Upewnij się, że nie mieszałeś starych i nowych bibliotek, np. Mapred vs mapreduce. Adnotuj @Overide na mapie i ogranicz metody. Jeśli zauważysz błędy, nie zmieniasz prawidłowo metod.

+0

dziękuję za ten komentarz! W moim przypadku podpis metody map() został błędnie nazwany wielką literą: public void Map (..) Zamiast publicznej mapy void (...) - udało mi się ją odkryć za pomocą @ Override - Again, Tnx! – Li3ro

3

mam podobny ślad stosu wyjątku z powodu niewłaściwego Mapper klasy ustawionej w kodzie (typo :))

job.setMapperClass(Mapper.class) // Set to org.apache.hadoop.mapreduce.Mapper due to type 

Zauważ, że błędnie używałem klasy Mapper z pakietu mapreduce, zmieniłem go do mojego zwyczaju klasa mapper:

job.setMapperClass(LogProcMapperClass.class) // LogProcMapperClass is my custom mapper. 

Wyjątek został rozwiązany po poprawieniu klasy odwzorowującej.