fusionner les fichiers de sortie après réduire la phase

Dans mapreduce chaque réduire la tâche de rédiger sa sortie vers un fichier nommé partie-r-nnnnn nnnnn est un IDENTIFIANT de partition associée à la réduction de la tâche. Est-ce que map/reduce fusionne ces fichiers? Si oui, comment?

72
demandé sur David Ongaro 2011-04-18 12:01:55

10 réponses

au lieu de faire la fusion de fichiers par vous-même, vous pouvez déléguer la fusion entière des fichiers de sortie reduce en appelant:

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

Note cela combine les fichiers HDFS localement. Assurez-vous d'avoir assez d'espace disque avant d'exécuter

116
répondu diliop 2018-03-01 06:28:59

Non, ces fichiers ne sont pas fusionnés par Hadoop. Le nombre de fichiers que vous obtenez est le même que le numéro de réduire les tâches.

si vous avez besoin de cela comme entrée pour une prochaine tâche alors ne vous inquiétez pas d'avoir des fichiers séparés. Spécifiez simplement le répertoire entier comme entrée pour la prochaine tâche.

si vous avez besoin des données à l'extérieur du cluster, alors je les fusionne habituellement à l'extrémité de réception en tirant les données du cluster.

i. e. quelque chose comme ceci:

hadoop fs -cat /some/where/on/hdfs/job-output/part-r-* > TheCombinedResultOfTheJob.txt
26
répondu Niels Basjes 2011-04-18 10:06:33

C'est la fonction que vous pouvez utiliser pour fusionner des fichiers dans HDFS

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
répondu Mervyn 2015-07-02 15:29:21

pour les fichiers texte seulement et HDFS comme source et destination, utilisez la commande suivante:

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

cela concaténera tous les fichiers dans input_hdfs_dir et écrira la sortie à HDFS à output_hdfs_file . Gardez à l'esprit que toutes les données seront ramenées dans le système local et ensuite téléchargées vers hdfs, bien qu'aucun fichier temporaire ne soit créé et cela se produit à la volée en utilisant UNIX pe.

De plus, cela ne fonctionnera pas avec les fichiers non textuels comme Avro, ORC, etc.

pour les fichiers binaires, vous pouvez faire quelque chose comme ceci (si vous avez des tables ruches mappées sur les répertoires):

insert overwrite table tbl select * from tbl

selon votre configuration, cela pourrait aussi créer plus que des fichiers. Pour créer un fichier unique, définissez le nombre de réducteurs à 1 explicitement en utilisant mapreduce.job.reduces=1 ou définissez la propriété de la ruche comme hive.merge.mapredfiles=true .

6
répondu Gaurav Kumar 2015-09-16 15:46:27

vous pouvez exécuter une tâche map/reduce supplémentaire, où map et reduce ne changent pas les données, et le partitionneur affecte toutes les données à un réducteur unique.

3
répondu adamax 2011-04-18 09:19:34

les fichiers part-r-nnnnn sont générés après la phase de réduction désignée par " r " entre les deux. Maintenant, le fait est que si vous avez un réducteur de course, vous aurez un fichier de sortie comme partie-r-00000. Si le nombre de réducteurs est de 2, alors vous aurez la partie-r-00000 et la partie-r-00001 et ainsi de suite. Regardez, si le fichier de sortie est trop grand pour s'insérer dans la mémoire de la machine puisque le cadre hadoop a été conçu pour fonctionner sur Commodity Machines , alors le fichier se divise. Selon le MRv1, vous avez une limite de 20 réducteurs pour travailler sur votre logique. Vous avez peut-être plus, mais la même chose doit être personnalisée dans les fichiers de configuration mapred-site.xml . Parler de votre question; vous pouvez soit utiliser getmerge ou vous pouvez définir le nombre de réducteurs à 1 en intégrant l'énoncé suivant au Code du pilote

job.setNumReduceTasks(1);

J'espère que ceci répondra à votre question.

3
répondu Aniruddha Sinha 2015-10-27 05:47:23

en plus de ma réponse précédente, j'ai une autre réponse pour vous que j'essayais il y a quelques minutes. Vous pouvez utiliser CustomOutputFormat qui ressemble au code donné ci-dessous

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);
    }

}

Seulement, ont un oeil à la quatrième ligne de la dernière. J'ai utilisé mon propre nom comme nom de fichier de sortie et j'ai testé le programme avec 15 réducteurs. Toujours le Fichier reste le même. Afin d'obtenir un seul fichier au lieu de deux ou plus est possible encore pour être très clair la taille du fichier de sortie ne doit pas dépasser la taille de la mémoire primaire c.-à-d. le fichier de sortie doit s'adapter dans la mémoire de la machine de marchandises sinon il pourrait y avoir un problème avec la division du fichier de sortie. Merci!!

1
répondu Aniruddha Sinha 2015-10-27 10:20:59

pourquoi ne pas utiliser un script pig comme celui-ci pour fusionner des fichiers de partition:

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

store stuff into "/path/to/mergedir"
0
répondu Ian 2013-12-21 04:03:23

Si les fichiers d'en-tête, vous pouvez vous débarrasser de ceci:

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

puis ajouter l'en-tête manuellement pour la sortie.csv

0
répondu Masih 2017-01-18 18:12:16

. Est-ce que map / reduce fusionne ces fichiers?

Pas de. Il n'a pas de fusion.

vous pouvez utiliser IdentityReducer pour atteindre votre objectif.

N'effectue aucune réduction, en écrivant toutes les valeurs d'entrée directement à la sortie.

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

écrit toutes les clés et valeurs directement à la sortie.

regardez liées SE messages:

hadoop: différence entre 0 réducteur et de l'identité réducteur?

0
répondu Ravindra babu 2017-05-23 12:26:15