2013-10-27 12 views
11

Normalerweise schreiben wir die Mapper in der Form:Mapper Eingang Schlüsselwertpaar in Hadoop

public static class Map extends Mapper<**LongWritable**, Text, Text, IntWritable> 

Hier wird der Eingang Schlüssel-Wert-Paar für den Mapper ist <LongWritable, Text> - soweit ich weiß, wenn der Mapper bekommt die Eingabedaten werden zeilenweise durchlaufen - also der Key für den Mapper bedeutet die Zeilennummer - bitte korrigieren Sie mich wenn ich falsch liege.

Meine Frage ist: Wenn ich geben den Eingangs Schlüssel-Wert-Paar für Mapper als <Text, Text> dann wird es den Fehler geben

java.lang.ClassCastException: org.apache.hadoop.io.LongWritable cannot be cast to org.apache.hadoop.io.Text 

Ist es zwingend die Eingabe Schlüssel-Wert-Paar-Mapper als <LongWritable, Text> zu geben - Wenn ja, warum? wenn nein dann was ist der Grund des Fehlers? Können Sie mir bitte helfen, die richtige Begründung des Fehlers zu verstehen?

Vielen Dank im Voraus.

+0

Es ist nicht obligatorisch, 'LongWritable' als Schlüssel zu verwenden . Was machst du, um diese Ausnahme zu generieren? Wo kommt es in Ihrem Code vor? – Vidya

+0

Ich mache nichts explizit, um diese Ausnahme zu generieren - IT zeigt :: java.lang.ClassCastException: org.apache.hadoop.io.LongWritable kann nicht in org.apache.hadoop.io.Text bei ExamTest $ umgewandelt werden Map.map (ExamTest.java:1) bei org.apache.hadoop.mapreduce.Mapper.run (Mapper.java:144) bei org.apache.hadoop.mapred.MapTask.runNewMapper (MapTask.java:764) bei org.apache.hadoop.mapred.MapTask.run (MapTask.java:370) bei org.apache.hadoop.mapred.Child $ 4.run (Child.java:255) – Ronin

+0

Können Sie bitte die Situation erklären? Vielen Dank. – Ronin

Antwort

30

Die Eingabe für den Mapper hängt davon ab, welches InputFormat verwendet wird. Das InputFormat ist dafür verantwortlich, die eingehenden Daten zu lesen und in ein beliebiges Format zu bringen, das der Mapper erwartet. Das Standard-InputFormat ist TextInputFormat, das sich um FileInputFormat<LongWritable, Text> erweitert.

Wenn Sie das InputFormat nicht ändern, verursacht die Verwendung eines Mappers mit einer anderen Signatur vom Typ "Schlüsselwert" als diesen Fehler. Wenn Sie die Eingabe <Text, Text> erwarten, müssen Sie ein geeignetes InputFormat auswählen. Sie können das Inputformat in Job-Setup einstellen:

job.setInputFormatClass(MyInputFormat.class); 

Und wie gesagt, immer standardmäßig auf TextInputFormat gesetzt.

Nun lassen Sie uns sagen, dass Ihre Eingabedaten ein Bündel von Newline getrennte Datensätze durch Komma begrenzt ist:

  • "A, Wert1"
  • "B, Wert2"

Wenn Wenn der Eingabeschlüssel für den Mapper sein soll ("A", "Wert1"), ("B", "Wert2"), müssen Sie ein benutzerdefiniertes InputFormat und RecordReader mit der Signatur <Text, Text> implementieren. Zum Glück, das ist ziemlich einfach. Es gibt an example here und wahrscheinlich auch ein paar Beispiele, die sich um StackOverflow herum bewegen.

Kurz gesagt, fügen Sie eine Klasse, die FileInputFormat<Text, Text> erweitert und eine Klasse, die RecordReader<Text, Text> erweitert. Überschreiben Sie die FileInputFormat#getRecordReader-Methode und lassen Sie eine Instanz Ihres benutzerdefinierten RecordReaders zurückgeben.

Dann müssen Sie die erforderliche RecordReader-Logik implementieren. Der einfachste Weg dazu besteht darin, in Ihrem benutzerdefinierten RecordReader eine Instanz von LineRecordReader zu erstellen und alle grundlegenden Verantwortlichkeiten an diese Instanz zu delegieren. In den Methoden getCurrentKey und getCurrentValue implementieren Sie die Logik zum Extrahieren der durch Komma getrennten Textinhalte, indem Sie LineRecordReader#getCurrentValue aufrufen und auf Komma trennen.

Schließlich legen Sie Ihr neues InputFormat als Job InputFormat wie nach dem zweiten Absatz oben gezeigt.

+0

Vielen Dank. Es war schön. Kannst du mir auch erzählen, wie du davon weißt? Jeder wichtige Link, den Sie teilen möchten? – Ronin

+0

Hauptsächlich nehmen Sie diese Informationen Schritt für Schritt durch Googeln und so, den gleichen Weg, auf dem Sie jetzt sind. :) Aber das Lesen von Teilen des Buches Hadoop: Ein Definitive Guide war sehr hilfreich. Es gibt eine ziemlich umfassende Einführung Hadoop. –

+1

Verwenden Sie 'job.setInputFormatClass (MyTextInputFormat.class)' in den neuen Hadoop-Paketen – pedromateo

1

In dem Buch "Hadoop: The Diffinitive Guide" von Tom White denke ich, dass er eine angemessene Antwort darauf hat (pg.197):

„ Schlüssel des TextInputFormat, wird einfach die in der Datei-Offset, sind normalerweise nicht sehr nützlich es ist, für jede Zeile in einer Datei gemeinsam einen Schlüssel-Wert-Paar, durch ein Trennzeichen getrennt werden solche. als Tabulatorzeichen. Zum Beispiel ist dies die Ausgabe von TextOutputFormat erzeugt, default Output des Hadoop. Um solche Dateien richtig zu interpretieren, KeyValueTextInputFormat geeignet ist.

Sie den Separator über die key.value angeben. separator.in.input.line Eigentum t ist standardmäßig ein Tab-Zeichen. "

+0

Vielen Dank! Ich lese dieses Buch zum ersten Mal und ich konnte nicht herausfinden, woher der Key LongWritable-Input für den Mapper kam! Ihr Kommentar hier hat mir geholfen, die Antwort zu finden, die ich brauchte, und Ihre Antwort hier hat dies für mich weiter verdeutlicht. –

+0

Wie bekomme ich den Hash-Wert Trennzeichen zwischen Schlüssel und Wert in Java Map Programm zu reduzieren? –

-3

Der Schlüssel für die Mapper-Eingabe ist immer ein Ganzzahl-Typ .... Die Mapper-Eingabe-Taste zeigt die Offset-Nummer der Linie an. und der Wert zeigt die ganze Zeile an ...... Datensatzleser liest eine einzelne Zeile im ersten Zyklus. Und o/p des Mappers kann sein, was immer Sie wollen (es kann sein (Text, Text) oder (Text, IntWritable) oder ......)

+0

Es ist ein Long, kein Int –

Verwandte Themen