2012-10-07 22 views

Respuesta

6

Sí, es posible hacer con salidas múltiples, de acuerdo con los documentos, cualquier salida que pase a través de salidas múltiples durante la etapa del mapa es ignorada por el reductor, por lo que esto es exactamente lo que quiere. Escribo un pequeño ejemplo en my GitHub y espero que lo encuentres útil.

+0

¡Gracias por la respuesta! Lo intenté, ¡funciona! –

1

Usted puede simplemente escribir la salida directamente a HDFS de su aplicación asignador - Basta con crear un objeto de sistema de archivos utilizando la configuración del contexto y luego crear un archivo, escribir en él y recuerde cerrar el partido:

public void cleanup(Context context) { 
    FileSystem fs = FileSystem.get(context.getConfiguration()); 
    PrintStream ps = new PrintStream(fs.create(
     new Path("/path/to/output", "map-output"))); 
    ps.println("test"); 
    ps.close(); 
} 

Otros Consideraciones: cada archivo debe tener un nombre exclusivo en HDFS, por lo que puede agregar el sufijo del nombre de archivo con el número de ID del asignador, pero también debe apreciar la ejecución especulativa (en la que la instancia de la tarea del asignador puede ejecutarse en dos ubicaciones, ambas intentan escribir en el mismo archivo en HDFS).

Normalmente se abstrae de esto ya que Output Committer crea archivos en un directorio tmp HDFS con el ID de la tarea y el número de intento, solo moviéndolo a la ubicación y nombre de archivo correctos al realizar ese intento de tarea. No hay forma de evitar este problema cuando se ejecuta en el lado del mapa (los datos se escriben en el sistema de archivos local) sin desactivar la ejecución especulativa o crear múltiples archivos en HDFS, uno de cada intento.

Así que una solución más 'completo' se vería así:

FileSystem fs = FileSystem.get(context.getConfiguration()); 
PrintStream ps = new PrintStream(fs.create(new Path(
     "/path/to/output", String.format("map-output-%05d-%d", 
     context.getTaskAttemptID().getTaskID().getId(), 
     context.getTaskAttemptID().getId())))); 
ps.println("test"); 
ps.close(); 

MultipleOutputs ayudarían a reducir lado, pero no creo que el mapa del lado que iba a funcionar ya que no hay confirmador de salida y la obra directorio no está en HDFS.

Por supuesto, si se tratara de un trabajo de solo mapeador, entonces funcionaría MultipleOutputs. Entonces, un enfoque alternativo sería ejecutar un trabajo de solo mapa, y luego usar la parte deseada de la salida en un trabajo secundario (con un mapeador de identidad), depende de la cantidad de datos que suponga su movimiento.

+0

Hola, Chris! ¡Gracias por la respuesta! Intenté implementar la lógica de salidas múltiples en el asignador. Encuentro que todo lo que envío usando output.collect solo se envía al reductor. La salida que escribo utilizando múltiples salidas en una carpeta diferente, no se envía al reductor, por lo que he comprobado. ¿Puedo usar este tipo de implementación para mi proyecto? ¿Hay algún inconveniente al hacerlo? –

+0

No estoy seguro de entender por completo su comentario, pero si lo que ha intentado es trabajar para usted, entonces úselo. –

+0

Gracias por la respuesta! –

Cuestiones relacionadas