Modifier la taille du fichier Split dans Hadoop

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

ce que je dois faire, c'est réduire la taille du segment, pour que je puisse utiliser encore plus les nœuds pour un emploi.

donc la question est, comment est-il possibilité de diviser les fichiers par disons 10kb? Ai-je besoin pour mettre en place mes propres InputFormat et RecordReader pour cela, ou est-il un paramètre à régler? Grâce.

22
demandé sur Ahmedov 2012-03-13 08:01:01

5 réponses

Le paramètre mapred.max.split.size ce qui peut être défini par tâche individuellement est ce que vous recherchez. Ne pas changer dfs.block.size parce que ceci est global pour les HDFS et peut conduire à des problèmes.

32
répondu Brainlag 2015-12-17 20:25:36

Hadoop the Definitive Guide, page 203 "Le maximum de diviser la taille par défaut est la valeur maximale qui peut être représenté par un Java de type long. Il n'a d'effet que lorsqu'elle est inférieure à la taille de bloc, forçant se divise pour être plus petit qu'un bloc. La scission de la taille est calculée par la formule:

max(minimumSize, min(maximumSize, blockSize))

par défaut

minimumSize < blockSize < maximumSize

donc la taille de split 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 fichiers volumineux qu'un grand nombre de petits fichiers. Une des raisons en est que FileInputFormat génère des fentes de telle sorte que chaque fente est tout ou partie d'un seul fichier. Si le fichier est très petit ("petit" signifie beaucoup plus petit qu'un bloc HDFS) et qu'il y en a beaucoup, alors chaque tâche de mappage traitera très peu d'entrées, et il y en aura beaucoup (une par fichier), chacune d'entre elles imposant des frais supplémentaires de comptabilité. Comparez un fichier de 1 Go divisé en 16 blocs de 64 Mo, et 10.000 environ 100KB fichiers. Les 10.000 fichiers utilisent une map chacun, et le temps de travail peut être des dizaines ou des centaines de fois plus lent que l'équivalent avec un seul fichier d'entrée et 16 tâches de map.


21
répondu Ahmedov 2012-04-10 05:59:21

voici fragment qui illustre la façon correcte de faire ce qui est nécessaire ici sans chaînes de configuration magiques. La constante nécessaire est définie à l'intérieur de FileInputFormat. La taille du bloc peut être prise si nécessaire à partir de la constante de bloc HDFS par défaut, mais il a une assez bonne probabilité d'être défini par l'utilisateur.

ici, je divise juste 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);
2
répondu Roman Nikitchenko 2015-04-21 22:08:39

Écrire un format d'entrée personnalisé qui étend combinefileinputformat[a ses propres avantages et inconvénients de base dans la distribution hadoop]. qui combine les entrées se divise dans la valeur spécifiée dans mapred.Max.Split.taille

1
répondu Mahendran Ponnusamy 2013-01-16 16:16:03

étant donné un ensemble de fichiers, comment FileInputFormat les transforme-t-il en divisions? FileInputFormat ne divise que les gros fichiers. Ici "Grand" signifie plus grand qu'un bloc HDFS. la taille de split est normalement celle d'un HDFS bloc.

vous devriez donc changer la taille du bloc HDFS, mais ce n'est pas la bonne façon. Peut-être que vous devriez essayer de revoir l'architecture de votre application MapReduce.

-1
répondu Alexander Verbitsky 2012-03-13 15:22:37