5 Stimmen

Wie erhält man Dateinamen/Dateiinhalte als Schlüssel/Wert-Eingabe für MAP, wenn ein Hadoop MapReduce Job ausgeführt wird?

Ich erstelle ein Programm zur Analyse von PDF-, DOC- und DOCX-Dateien. Diese Dateien sind im HDFS gespeichert.

Wenn ich meinen MapReduce-Auftrag starte, soll die Map-Funktion den Dateinamen als Schlüssel und den Binärinhalt als Wert haben. Dann möchte ich einen Stream-Reader erstellen, den ich an die PDF-Parser-Bibliothek übergeben kann. Wie kann ich erreichen, dass das Schlüssel/Wert-Paar für die Map-Phase Dateiname/Dateiinhalt lautet?

Ich verwende Hadoop 0.20.2

Dies ist ein älterer Code, der einen Auftrag startet:

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

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

 conf.setMapperClass(Map.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(args[1]));

 JobClient.runJob(conf);
}

Ich weiß, dass es andere Eingabeformate gibt. Aber gibt es einen, der genau das tut, was ich will? Ich finde die Dokumentation ziemlich vage. Wenn es einen gibt, wie sollten dann die Eingabetypen der Map-Funktion aussehen?

Vielen Dank im Voraus!

8voto

Niels Basjes Punkte 10158

Die Lösung hierfür ist, eine eigene FileInputFormat-Klasse zu erstellen, die diese Aufgabe übernimmt. Sie haben Zugriff auf den Namen der Eingabedatei über den FileSplit, den dieses FileInputFormat erhält (getPath). Vergewissern Sie sich, dass isSplitable in Ihrem FileInputFormat immer false zurückgibt.

Sie benötigen außerdem einen benutzerdefinierten RecordReader, der die gesamte Datei als einen einzigen "Record"-Wert zurückgibt.

Seien Sie vorsichtig im Umgang mit zu großen Dateien. Sie werden die gesamte Datei in den Arbeitsspeicher laden, und die Standardeinstellung für einen Task Tracker ist, dass nur 200 MB Arbeitsspeicher zur Verfügung stehen.

1voto

Brent Worden Punkte 10099

Als Alternative zu Ihrem Ansatz könnten Sie die Binärdateien direkt zu hdfs hinzufügen. Dann erstellen Sie eine Eingabedatei, die die dfs-Pfade für alle Binärdateien enthält. Dies könnte dynamisch geschehen mit Das FileSystem von Hadoop Klasse. Schließlich erstellen Sie einen Mapper, der die Eingabe durch Öffnen von Eingabeströmen verarbeitet, wiederum mit FileSystem.

1voto

Markovich Punkte 11

Sie können WholeFileInputFormat ( https://code.google.com/p/hadoop-course/source/browse/HadoopSamples/src/main/java/mr/wholeFile/?r=3 )

In mapper Name der Datei u kann durch diesen Befehl erhalten:

public void map(NullWritable key, BytesWritable value, Context context) throws 
IOException, InterruptedException 
{       

Path filePath= ((FileSplit)context.getInputSplit()).getPath();
String fileNameString = filePath.getName();

byte[] fileContent = value.getBytes();

}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X