web-dev-qa-db-fra.com

Changer la taille du fichier fractionné dans Hadoop

J'ai un tas de petits fichiers dans un répertoire HDFS. Bien que le volume de fichiers soit relativement petit, le temps de traitement par fichier est énorme . C'est-à-dire qu'un fichier 64mb, qui correspond à la taille de division par défaut de TextInputFormat, prendrait même plusieurs heures pour être traité. 

Ce que je dois faire est de réduire la taille de la scission , afin de pouvoir utiliser encore plus de nœuds pour un travail. 

La question est donc de savoir comment est-il possible de scinder les fichiers en disons 10kb? Dois-je implémenter mes propres InputFormat et RecordReader pour cela, ou y a-t-il un paramètre à définir? Merci. 

22
Ahmedov

Le paramètremapred.max.split.sizequi peut être défini individuellement pour chaque travail correspond à ce que vous recherchez. Ne changez pasdfs.block.sizecar cela est global pour HDFS et peut entraîner des problèmes. 

32
Brainlag

Hadoop le guide définitif, page 203 "La taille de division maximale correspond par défaut à la valeur maximale pouvant être représentée par un type long Java. Elle n'a d'effet que si elle est inférieure à la taille du bloc, forçant les divisions à être inférieures à un bloc. La taille de la scission est calculée par la formule:

max(minimumSize, min(maximumSize, blockSize))

par défaut

minimumSize < blockSize < maximumSize

donc la taille de la division est blockSize

Par exemple, 

Minimum Split Size 1
Maximum Split Size 32mb
Block Size  64mb
Split Size  32mb

Hadoop fonctionne mieux avec un petit nombre de gros fichiers qu'un grand nombre de petits fichiers. Une des raisons est que FileInputFormat génère des fractionnements de sorte que chaque fractionnement constitue tout ou partie d'un fichier unique. Si le fichier est très petit ("petit" signifie beaucoup plus petit qu'un bloc HDFS) et qu'il y en a beaucoup, chaque tâche de carte traitera très peu d'entrées et il y en aura beaucoup (une par fichier), dont chacun impose des frais généraux supplémentaires de comptabilité. Comparez un fichier de 1 Go divisé en seize blocs de 64 Mo et environ 10 000 fichiers de 100 Ko. Les 10 000 fichiers utilisent une carte chacun, et la durée du travail peut être plusieurs fois inférieure à celle d'une tâche équivalente avec un seul fichier d'entrée et 16 tâches de carte. 


21
Ahmedov

Voici un fragment qui illustre la manière correcte de faire ce qui est nécessaire ici sans chaînes de configuration magiques. La constante nécessaire est définie dans FileInputFormat. La taille de bloc peut être prise si nécessaire à partir de la constante de bloc HDFS par défaut, mais elle a de bonnes chances d'être définie par l'utilisateur.

Ici, je divise simplement la taille de division maximale par 2 si elle a été définie.

import org.Apache.hadoop.conf.Configuration;
import org.Apache.hadoop.mapreduce.lib.input.FileInputFormat;

// ....

final long DEFAULT_SPLIT_SIZE = 128 * 1024 * 1024;
final Configuration conf = ...

// We need to lower input block size by factor of two.
conf.setLong(
    FileInputFormat.SPLIT_MAXSIZE,
    conf.getLong(
        FileInputFormat.SPLIT_MAXSIZE, DEFAULT_SPLIT_SIZE) / 2);
3
Roman Nikitchenko

Ecrivez un format d’entrée personnalisé qui étend le fichier combineinfichierinputformat [a ses propres avantages et inconvénients pour la distribution hadoop] qui combine les divisions d’entrée dans la valeur spécifiée dans mapred.max.split.size

1
Mahendran Ponnusamy