web-dev-qa-db-fra.com

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

Dans mapreduce, chaque tâche de réduction écrit sa sortie dans un fichier nommé part-r-nnnnn nnnnn est un ID de partition associé à la tâche de réduction. Est-ce que mapper/réduire fusionner ces fichiers? Si oui comment?

73
Shahryar

Au lieu de fusionner le fichier vous-même, vous pouvez déléguer la fusion complète des fichiers de sortie réduits en appelant:

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

Remarque Ceci combine les fichiers HDFS localement. Assurez-vous de disposer de suffisamment d'espace disque avant de lancer 

117
diliop

Non, ces fichiers ne sont pas fusionnés par Hadoop. Le nombre de fichiers que vous obtenez est identique au nombre de tâches réduites. 

Si vous avez besoin de cela comme entrée pour un prochain travail, ne vous inquiétez pas de fichiers séparés. Spécifiez simplement le répertoire entier comme entrée pour le travail suivant.

Si vous avez besoin des données hors du cluster, je les fusionne généralement du côté destinataire lorsque vous extrayez les données du cluster.

C'est à dire. quelque chose comme ça:

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

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
Mervyn

Pour les fichiers texte uniquement et HDFS en tant que source et destination, utilisez la commande ci-dessous:

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

Cela concaténera tous les fichiers dans input_hdfs_dir et réécrira la sortie sur HDFS à output_hdfs_file. N'oubliez pas que toutes les données seront ramenées sur le système local, puis à nouveau téléchargées sur hdfs, bien qu'aucun fichier temporaire ne soit créé et que cela se produit à la volée avec UNIX pe.

En outre, cela ne fonctionnera pas avec des fichiers non-texte tels que Avro, ORC, etc.

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

insert overwrite table tbl select * from tbl

Selon votre configuration, cela pourrait également créer plus que des fichiers. Pour créer un seul fichier, définissez explicitement le nombre de réducteurs sur 1 à l'aide de mapreduce.job.reduces=1 ou définissez la propriété Hive sur Hive.merge.mapredfiles=true.

7
Gaurav Kumar

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 en cours d'exécution, vous aurez un fichier de sortie comme part-r-00000. Si le nombre de réducteurs est égal à 2, les parties-r-00000, partie-r-00001, etc. Regardez, si le fichier de sortie est trop volumineux pour tenir dans la mémoire de la machine depuis que l'infrastructure hadoop a été conçue pour s'exécuter sur Commodity Machines , le fichier est alors divisé. Selon le MRv1, vous avez une limite de 20 réducteurs pour travailler sur votre logique. Vous en avez peut-être plus, mais les mêmes besoins doivent être personnalisés dans les fichiers de configuration mapred-site.xml . Parler de votre question; Vous pouvez utiliser getmerge ou définir le nombre de réducteurs sur 1 en incorporant l'instruction suivante au code du pilote.

job.setNumReduceTasks(1);

J'espère que ça répond à ta question.

4
Aniruddha Sinha

Vous pouvez exécuter une tâche de mappage/réduction supplémentaire, mappage et réduction ne modifiant pas les données, et le partitionneur attribuant toutes les données à un seul réducteur.

3
adamax

Outre ma réponse précédente, j’ai une dernière réponse à vous essayer que j’essayais il ya quelques minutes. Vous pouvez utiliserCustomOutputFormatqui 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);
    }

}

Jetez un coup d’œil à 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. Il est donc possible d’obtenir un seul fichier de sortie au lieu de deux ou plus, mais il est clair que la taille du fichier de sortie ne doit pas dépasser la taille de la mémoire primaire, c’est-à-dire que le fichier de sortie doit tenir dans la mémoire de la machine principale. un problème avec le fichier de sortie divisé . Merci !!

1
Aniruddha Sinha

Si les fichiers ont un en-tête, vous pouvez vous en débarrasser en procédant ainsi:

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

puis ajoutez l'en-tête manuellement pour output.csv

0
Masih

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
Ian

. La carte/réduction fusionne-t-elle ces fichiers? 

Non, il ne fusionne pas. 

Vous pouvez utiliser IdentityReducer pour atteindre votre objectif. 

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

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

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

Jetez un coup d'œil aux articles sur la SE:

Hadoop: différence entre 0 réducteur et réducteur d'identité?

0
Ravindra babu