J'ai récemment mis en place la compression LZO dans Hadoop. Quel est le moyen le plus simple de compresser un fichier dans HDFS? Je veux compresser un fichier puis supprimer l'original. Devrais-je créer un travail MR avec un IdentityMapper et un IdentityReducer qui utilise la compression LZO?
Je vous suggère d'écrire un travail MapReduce qui, comme vous le dites, utilise simplement le mappeur d'identité. Pendant que vous y êtes, vous devriez envisager d'écrire les données dans des fichiers de séquence pour améliorer le chargement des performances. Vous pouvez également stocker des fichiers de séquence en compression au niveau du bloc et au niveau de l'enregistrement. Vous devriez voir ce qui vous convient le mieux, car les deux sont optimisés pour différents types d’enregistrements.
Pour moi, écrire un Hadoop Streaming travail pour compresser des fichiers est moins lourd.
C'est la commande que je lance:
hadoop jar $HADOOP_HOME/contrib/streaming/hadoop-streaming-0.20.2-cdh3u2.jar \
-Dmapred.output.compress=true \
-Dmapred.compress.map.output=true \
-Dmapred.output.compression.codec=org.Apache.hadoop.io.compress.GzipCodec \
-Dmapred.reduce.tasks=0 \
-input <input-path> \
-output $OUTPUT \
-mapper "cut -f 2"
Je vais aussi généralement mettre la sortie dans un dossier temporaire au cas où quelque chose se passerait mal:
OUTPUT=/tmp/hdfs-gzip-`basename $1`-$RANDOM
Une note supplémentaire, je ne spécifie pas un réducteur dans le travail de streaming, mais vous pouvez certainement. Cela forcera le tri de toutes les lignes, ce qui peut prendre beaucoup de temps avec un fichier volumineux. Il y aurait peut-être un moyen de contourner cela en écrasant le partitionneur, mais je n'ai pas cherché à comprendre cela. Malheureusement, vous risquez de vous retrouver avec de nombreux petits fichiers qui n'utilisent pas efficacement les blocs HDFS. C’est une raison pour examiner Archives Hadoop
La commande de streaming de Jeff Wu accompagnée d'une concaténation des fichiers compressés donnera un seul fichier compressé. Lorsqu'un mappeur non Java est transmis au travail de diffusion en continu et que le format d'entrée est en mode texte, la transmission en continu du texte fournit uniquement la valeur et non la clé.
hadoop jar contrib/streaming/hadoop-streaming-1.0.3.jar \
-Dmapred.reduce.tasks=0 \
-Dmapred.output.compress=true \
-Dmapred.compress.map.output=true \
-Dmapred.output.compression.codec=org.Apache.hadoop.io.compress.GzipCodec \
-input filename \
-output /filename \
-mapper /bin/cat \
-inputformat org.Apache.hadoop.mapred.TextInputFormat \
-outputformat org.Apache.hadoop.mapred.TextOutputFormat
hadoop fs -cat /path/part* | hadoop fs -put - /path/compressed.gz
C'est ce que j'ai utilisé:
/*
* Pig script to compress a directory
* input: hdfs input directory to compress
* hdfs output directory
*
*
*/
set output.compression.enabled true;
set output.compression.codec org.Apache.hadoop.io.compress.BZip2Codec;
--comma seperated list of hdfs directories to compress
input0 = LOAD '$IN_DIR' USING PigStorage();
--single output directory
STORE input0 INTO '$OUT_DIR' USING PigStorage();
Bien que ce ne soit pas LZO, cela risque d’être un peu plus lent.
@Chitra Je ne peux pas commenter pour des raisons de réputation
Voici tout dans une commande: au lieu d’utiliser la deuxième commande, vous pouvez réduire en un seul fichier compressé
hadoop jar share/hadoop/tools/lib/hadoop-streaming-2.7.3.jar \
-Dmapred.reduce.tasks=1 \
-Dmapred.output.compress=true \
-Dmapred.compress.map.output=true \
-Dmapred.output.compression.codec=org.Apache.hadoop.io.compress.BZip2Codec \
-input /input/raw_file \
-output /archives/ \
-mapper /bin/cat \
-reducer /bin/cat \
-inputformat org.Apache.hadoop.mapred.TextInputFormat \
-outputformat org.Apache.hadoop.mapred.TextOutputFormat
Ainsi, vous gagnez beaucoup d’espace en n’ayant qu’un seul fichier compressé.
Par exemple, disons que j'ai 4 fichiers de 10 Mo (c'est du texte brut, formaté en JSON)
La carte seulement me donne 4 fichiers de 650 KB Si je mappe et réduis, j'ai 1 fichier de 1,05 MB
Je sais que c'est un vieux fil de discussion, mais si quelqu'un suit ce fil (comme moi), il serait utile de savoir que l'une des 2 méthodes suivantes vous donne un caractère tab
(\ t) à la fin de chaque ligne.
hadoop jar $HADOOP_HOME/contrib/streaming/hadoop-streaming-0.20.2-cdh3u2.jar \
-Dmapred.output.compress=true \
-Dmapred.compress.map.output=true \
-Dmapred.output.compression.codec=org.Apache.hadoop.io.compress.GzipCodec \
-Dmapred.reduce.tasks=0 \
-input <input-path> \
-output $OUTPUT \
-mapper "cut -f 2"
hadoop jar share/hadoop/tools/lib/hadoop-streaming-2.7.3.jar \
-Dmapred.reduce.tasks=1 \
-Dmapred.output.compress=true \
-Dmapred.compress.map.output=true \
-Dmapred.output.compression.codec=org.Apache.hadoop.io.compress.BZip2Codec \
-input /input/raw_file \
-output /archives/ \
-mapper /bin/cat \
-reducer /bin/cat \
-inputformat org.Apache.hadoop.mapred.TextInputFormat \
-outputformat org.Apache.hadoop.mapred.TextOutputFormat
De ce hadoop-streaming.jar ajoute x'09 'à la fin de chaque ligne , j'ai trouvé le correctif et nous devons définir les 2 paramètres suivants pour le délimiteur respectif que vous utilisez (dans mon cas, c'était,)
-Dstream.map.output.field.separator=, \
-Dmapred.textoutputformat.separator=, \
commande complète à exécuter
hadoop jar <HADOOP_HOME>/jars/hadoop-streaming-2.6.0-cdh5.4.11.jar \
-Dmapred.reduce.tasks=1 \
-Dmapred.output.compress=true \
-Dmapred.compress.map.output=true \
-Dstream.map.output.field.separator=, \
-Dmapred.textoutputformat.separator=, \
-Dmapred.output.compression.codec=org.Apache.hadoop.io.compress.Lz4Codec \
-input file:////home/admin.kopparapu/accenture/File1_PII_Phone_part3.csv \
-output file:///home/admin.kopparapu/accenture/part3 \
-mapper /bin/cat \
-reducer /bin/cat \
-inputformat org.Apache.hadoop.mapred.TextInputFormat \
-outputformat org.Apache.hadoop.mapred.TextOutputFormat