it-swarm.com.de

ausgabedateien nach der Reduzierungsphase zusammenführen

In mapreduce schreibt jede Reduktionsaufgabe ihre Ausgabe in eine Datei mit dem Namen part-r-nnnnn , wobei nnnnn eine der Reduktionsaufgabe zugeordnete Partitions-ID ist. Kann map/verkleinern diese Dateien zusammenführen? Wenn ja, wie?

73
Shahryar

Anstatt die Datei selbst zusammenzuführen, können Sie die gesamte Zusammenführung der reduzierten Ausgabedateien delegieren.

hadoop fs -getmerge /output/dir/on/hdfs/ /desired/local/output/file.txt

Hinweis Dies kombiniert die HDFS-Dateien lokal. Stellen Sie vor dem Ausführen sicher, dass Sie über ausreichend Speicherplatz verfügen 

117
diliop

Nein, diese Dateien werden von Hadoop nicht zusammengeführt. Die Anzahl der Dateien entspricht der Anzahl der reduzierten Aufgaben. 

Wenn Sie dies als Eingabe für einen nächsten Auftrag benötigen, machen Sie sich keine Sorgen, separate Dateien zu haben. Geben Sie einfach das gesamte Verzeichnis als Eingabe für den nächsten Job an.

Wenn Sie die Daten außerhalb des Clusters benötigen, füge ich sie normalerweise auf der Empfangsseite zusammen, wenn Sie die Daten aus dem Cluster ziehen.

Das heißt etwas wie das:

hadoop fs -cat /some/where/on/hdfs/job-output/part-r-* > TheCombinedResultOfTheJob.txt
27
Niels Basjes

Mit dieser Funktion können Sie Dateien in HDFS zusammenführen 

public boolean getMergeInHdfs(String src, String dest) throws IllegalArgumentException, IOException {
    FileSystem fs = FileSystem.get(config);
    Path srcPath = new Path(src);
    Path dstPath = new Path(dest);

    // Check if the path already exists
    if (!(fs.exists(srcPath))) {
        logger.info("Path " + src + " does not exists!");
        return false;
    }

    if (!(fs.exists(dstPath))) {
        logger.info("Path " + dest + " does not exists!");
        return false;
    }
    return FileUtil.copyMerge(fs, srcPath, fs, dstPath, false, config, null);
}
8
Mervyn

Verwenden Sie für Textdateien und HDFS als Quelle und Ziel den folgenden Befehl:

hadoop fs -cat /input_hdfs_dir/* | hadoop fs -put - /output_hdfs_file

Dadurch werden alle Dateien in input_hdfs_dir verkettet und die Ausgabe wird unter output_hdfs_file in HDFS geschrieben. Beachten Sie, dass alle Daten in das lokale System zurückgegeben und erneut in HDFS hochgeladen werden. Es werden jedoch keine temporären Dateien erstellt, und dies geschieht unter Verwendung von UNIX pe.

Dies funktioniert auch nicht mit Nicht-Textdateien wie Avro, ORC usw.

Bei Binärdateien können Sie Folgendes tun (wenn Sie den Verzeichnissen Verzeichnisse zugeordnet haben):

insert overwrite table tbl select * from tbl

Abhängig von Ihrer Konfiguration können dadurch auch mehr als nur Dateien erstellt werden. Um eine einzelne Datei zu erstellen, legen Sie entweder die Anzahl der Reduzierungen explizit mit mapreduce.job.reduces=1 auf 1 fest, oder setzen Sie die Hive-Eigenschaft auf Hive.merge.mapredfiles=true.

7
Gaurav Kumar

Die part-r-nnnnn-Dateien werden nach der mit 'r' bezeichneten Reduzierungsphase generiert. Tatsache ist, dass, wenn Sie einen Reduzierer ausführen, eine Ausgabedatei wie Teil-r-00000 vorhanden ist. Wenn die Anzahl der Reduzierstücke 2 beträgt, haben Sie Teil-r-00000 und Teil-r-00001 und so weiter. Wenn die Ausgabedatei zu groß ist, um in den Maschinenspeicher zu passen, da das hadoop-Framework auf Commodity Machines ausgeführt werden soll, wird die Datei aufgeteilt. Laut MRv1 haben Sie ein Limit von 20 Reduzierern, um an Ihrer Logik zu arbeiten. Möglicherweise haben Sie mehr, aber dasselbe muss in den Konfigurationsdateien angepasst werden: mapred-site.xml . Sprechen über Ihre Frage; Sie können entweder getmerge verwenden oder die Anzahl der Reduzierer auf 1 setzen, indem Sie die folgende Anweisung in den Treibercode einbetten

job.setNumReduceTasks(1);

Hoffe, das beantwortet deine Frage.

4
Aniruddha Sinha

Sie können eine zusätzliche Map/Reduction-Aufgabe ausführen, bei der Map und Reduce die Daten nicht ändern, und der Partitionierer alle Daten einem einzelnen Reduzierer zuordnet.

3
adamax

Neben meiner vorherigen Antwort habe ich noch eine Antwort, die ich vor wenigen Minuten ausprobiert habe. Sie könnenCustomOutputFormatverwenden, das dem unten angegebenen Code entspricht

public class VictorOutputFormat extends FileOutputFormat<StudentKey,PassValue> {

    @Override
    public RecordWriter<StudentKey,PassValue> getRecordWriter(
            TaskAttemptContext tac) throws IOException, InterruptedException {
        //step 1: GET THE CURRENT PATH
        Path currPath=FileOutputFormat.getOutputPath(tac);

        //Create the full path
        Path fullPath=new Path(currPath,"Aniruddha.txt");

        //create the file in the file system
        FileSystem fs=currPath.getFileSystem(tac.getConfiguration());
        FSDataOutputStream fileOut=fs.create(fullPath,tac);
        return new VictorRecordWriter(fileOut);
    }

}

Schauen Sie sich einfach die vierte Zeile der letzten Zeile an. Ich habe meinen eigenen Namen als Ausgabedateiname verwendet und das Programm mit 15 Reduzierern getestet. Trotzdem bleibt die Datei gleich. Es ist also möglich, eine einzige Ausgabedatei anstelle von zwei oder mehr zu erhalten, aber um ganz klar zu sein, darf die Größe der Ausgabedatei nicht die Größe des Primärspeichers überschreiten, dh die Ausgabedatei muss in den Speicher des Commodity-Computers passen ein Problem mit der Ausgabedatei-Teilung . Danke !!

1
Aniruddha Sinha

Wenn die Dateien über einen Header verfügen, können Sie ihn folgendermaßen entfernen:

hadoop fs -cat /path/to/hdfs/job-output/part-* | grep -v "header" > output.csv

fügen Sie dann manuell den Header für output.csv hinzu

0
Masih

Verwenden Sie ein Schweineskript wie dieses, um Partitionsdateien zusammenzuführen:

stuff = load "/path/to/dir/*"

store stuff into "/path/to/mergedir"
0
Ian

. Mappen/Reduzieren Sie diese Dateien? 

Nein, es verschmilzt nicht. 

Sie können IdentityReducer verwenden, um Ihr Ziel zu erreichen. 

Führt keine Reduzierung durch und schreibt alle Eingangswerte direkt in die Ausgabe.

public void reduce(K key,
                   Iterator<V> values,
                   OutputCollector<K,V> output,
                   Reporter reporter)
            throws IOException

Schreibt alle Schlüssel und Werte direkt in die Ausgabe.

Schauen Sie sich verwandte SE-Beiträge an:

hadoop: unterschied zwischen 0 und identitätsreduzierer?

0
Ravindra babu