2010-08-23 45 views
30

Obtengo varios archivos pequeños en mi directorio de entrada que quiero fusionar en un único archivo sin usar el sistema de archivos local ni escribir mapreds. ¿Hay alguna manera de hacerlo usando comandos de hadoof fs o Pig?Fusionando múltiples archivos en uno dentro de Hadoop

Gracias!

+3

Debe aceptar una respuesta si su pregunta ha sido contestada. –

Respuesta

15
hadoop fs -getmerge <dir_of_input_files> <mergedsinglefile> 
+4

extrañamente esto no me da ningún resultado. no estoy seguro de por qué. – jayunit100

+0

tal vez su directorio solo tenga archivos vacíos –

+7

Creo que 'mergedsinglefile' es local, no distribuido – sds

7

bien ... me di cuenta de una manera usando comandos hadoop fs -

hadoop fs -cat [dir]/* | hadoop fs -put - [destination file] 

funcionó cuando lo probé ... cualquier escollo que uno pueda imaginar?

Gracias!

+9

Pero en este caso está descargando todos los datos de HDFS al nodo desde el que está ejecutando el comando (¿local?) Y luego lo sube a HDFS. Esto no es demasiado efectivo si tiene muchos datos – Vadim

+0

Otro inconveniente es que ocasionalmente puede obtener también alguna entrada no deseada de stdin. Lo encontré una vez en un clúster habilitado para HA cuando algunos mensajes de advertencia quedaron atrapados en la salida. – kasur

1

Puede utilizar la herramienta HDFSConcat, nueva en HDFS 0.21, para realizar esta operación sin incurrir en el costo de una copia.

+0

Gracias Jeff, investigará HDFSConcat. Actualmente estamos en 0.20.2 así que ahora estoy creando un Har de todos los archivos y luego leyendo de un cerdo. De esta manera, los datos permanecen en HDFS. – uHadoop

+0

Debo señalar que esta herramienta tiene limitaciones destacadas en https://issues.apache.org/jira/browse/HDFS-950. Los archivos deben tener el mismo tamaño de bloque y ser propiedad del mismo usuario. –

2

Si configura el fusible para montar su HDFS en un directorio local, su salida puede ser el sistema de archivos montado.

Por ejemplo, tengo nuestro HDFS montado a /mnt/hdfs localmente. Puedo ejecutar el siguiente comando y funciona muy bien:

hadoop fs -getmerge /reports/some_output /mnt/hdfs/reports/some_output.txt 

Por supuesto, hay otras razones para usar fusibles para montar HDFS a un directorio local, pero esto era un efecto secundario agradable para nosotros.

-1

Todas las soluciones son equivalente a hacer un

hadoop fs -cat [dir]/* > tmp_local_file 
hadoop fs -copyFromLocal tmp_local_file 

sólo significa que el local de m/c I/O está en el camino crítico de la transferencia de datos.

21

Para mantener todo en la grilla, use hadoop streaming con un solo reductor y cat como mapper y reductor (básicamente un noop) - agregue compresión utilizando MR flags.

hadoop jar \ 
    $HADOOP_PREFIX/share/hadoop/tools/lib/hadoop-streaming.jar \<br> 
    -Dmapred.reduce.tasks=1 \ 
    -Dmapred.job.queue.name=$QUEUE \ 
    -input "$INPUT" \ 
    -output "$OUTPUT" \ 
    -mapper cat \ 
    -reducer cat 

Si desea añadir compresión
-Dmapred.output.compress = true \ -Dmapred.output.compression.codec = org.apache.hadoop.io.compress.GzipCodec

+1

Creo que es el mejor método. – kholis

+1

Me imagino que esto cambiaría el orden de las líneas? –

+1

@AndredeMiranda Creo que el orden será determinista, ordenado por clave, ya que solo tenemos un reductor. Esto se basa en recordar el modelo de mezcla aleatoria, clasificación y reducción. – Mai

1

Si están trabajando en el clúster de Hortonworks y quieren fusionar múltiples archivos presentes en la ubicación de HDFS en un único archivo, luego pueden ejecutar el jar 'hadoop-streaming-2.7.1.2.3.2.0-2950.jar' que ejecuta un solo reductor y obtener el archivo fusionado en la ubicación de salida HDFS.

$ hadoop jar /usr/hdp/2.3.2.0-2950/hadoop-mapreduce/hadoop-streaming-2.7.1.2.3.2.0-2950.tarro \

-Dmapred.reduce.tasks=1 \ 
-input "/hdfs/input/dir" \ 
-output "/hdfs/output/dir" \ 
-mapper cat \ 
-reducer cat 

Puede descargar este frasco de Get hadoop streaming jar

Si está escribiendo trabajos de chispa y desea obtener un archivo combinado para evitar múltiples creaciones RDD y cuellos de botella de rendimiento utilizar este pedazo de código antes de la transformación de su RDD

sc.textFile("hdfs://...../part*).coalesce(1).saveAsTextFile("hdfs://...../filename)

Esto se fusionará todos los archivos de piezas en una sola y volver a guardarlo en hdfs ubicación

0

Dirigiéndose a esto desde la perspectiva de Apache Pig,

Para fusionar dos archivos con el esquema idéntico a través de cerdo, comando UNION puede utilizarse

A = load 'tmp/file1' Using PigStorage('\t') as ....(schema1) 
B = load 'tmp/file2' Using PigStorage('\t') as ....(schema1) 
C = UNION A,B 
store C into 'tmp/fileoutput' Using PigStorage('\t') 
Cuestiones relacionadas