2010-02-25 21 views
33

Tenemos un gran conjunto de datos para analizar con múltiples reducir las funciones.Hadoop one Map y multiple Reducir

Todo reducir trabajo algoritmo en el mismo conjunto de datos generados por la misma función mapa. Leer el gran conjunto de datos cuesta demasiado para hacerlo cada vez, sería mejor leer solo una vez y pasar los datos mapeados a múltiples reducir las funciones.

¿Puedo hacer esto con Hadoop? He buscado los ejemplos y el intarweb pero no he podido encontrar ninguna solución.

Respuesta

3

¿Está esperando que cada reductor trabaje en exactamente los mismos datos asignados? Pero al menos la "clave" debería ser diferente ya que decide a qué reductor ir.

Puede escribir una salida varias veces en el asignador, y la salida como clave (donde $ i es para el i-th reductor, y $ key es su clave original). Y debe agregar un "Particionador" para asegurarse de que estos n registros se distribuyan en reductores, en función de $ i. Luego, use "GroupingComparator" para agrupar registros por $ key original.

Es posible hacerlo, pero no de manera trivial en un solo MR.

+0

pero si agrego una nueva clave a la salida con el método 'context.write()' multiplique la transferencia de datos de los objetos 'Mapper'. solo resuelve el problema de lectura de archivos, ¿no? –

+0

, entonces sugeriría mostrar los datos asignados como archivos y usar otros MR para procesar estos archivos. – Victor

0

Por supuesto, puede definir varios reductores. Para el trabajo (Hadoop 0.20) simplemente agregue:

job.setNumReduceTasks(<number>); 

Pero. Su infraestructura tiene que apoyar las múltiples reductores, lo que significa que usted tiene que

  1. tener más de una CPU disponible
  2. ajustar mapred.tasktracker.reduce.tasks.maximum en site.xml mapred consecuencia

Y, por supuesto, su trabajo tiene que coincidir con algunas especificaciones. Sin saber exactamente lo que usted quiere hacer, sólo puedo dar grandes consejos:

  • la tecla mapa-salida o bien han de ser divisible por% numreducers o tiene que definir su propio particionador: job.setPartitionerClass(...) de con un ejemplo al azar-partidor ...
  • los datos debe ser capaz de reducir-en el formato particionado ... (referencias necesarias?)

obtendrá varios archivos de salida, uno para cada reductor. Si desea una salida ordenada, debe agregar otra tarea leyendo todos los archivos (múltiples tareas de mapa esta vez ...) y escribirlas ordenadas con un solo reductor ...

Eche un vistazo también al Combiner- Clase, que es local Reducer. Significa que puede agregar (reducir) ya en la memoria sobre los datos parciales emitidos por el mapa. Muy buen ejemplo es el WordCount-Example. El mapa emite cada palabra como clave y su cuenta como 1: (palabra, 1). El combinador obtiene datos parciales del mapa, emite (,) localmente. El Reducer hace exactamente lo mismo, pero ahora algunos (Combinados) wordcudos ya son> 1. Ahorra ancho de banda

+3

Por lo que puedo decir; OP pregunta por "Tener implementaciones de reductores múltiples" y está hablando de "Varias instancias del mismo código de reductor". Que es algo completamente diferente. –

11

Quizás una solución simple sea escribir un trabajo que no tenga una función de reducción. Entonces pasaría todos los datos mapeados directamente a la salida del trabajo. Usted acaba de establecer el número de reductores a cero para el trabajo.

Luego, escribiría un trabajo para cada función de reducción diferente que funcione con esos datos. Sin embargo, esto significaría almacenar todos los datos asignados en el HDFS.

Otra alternativa podría ser combinar todas sus funciones de reducción en un único Reducer que genera múltiples archivos, usando una salida diferente para cada función diferente. Se mencionan múltiples salidas en this article for hadoop 0.19. Estoy bastante seguro de que esta característica está rota en la nueva API mapreduce publicada con 0.20.1, pero aún puedes usarla en la API mapred más antigua.

0

todavía no consigo el problema, puede utilizar siguiente secuencia:

base de datos -> Mapa -> reducir (uso gato o Ninguno dependiendo de las necesidades) a continuación, almacenar la representación de datos se han extraído. si usted dice que es lo suficientemente pequeño como para caber en la memoria, entonces almacenarlo en el disco no debería ser un problema.

También su uso del paradigma MapReduce para el problema dado es incorrecto, usar una sola función de mapa y múltiples funciones de reducción "diferentes" no tiene sentido, muestra que solo está usando el mapa para transferir datos a diferentes máquinas para hacer cosas diferentes. no necesita hadoop ni ninguna otra arquitectura especial para eso.

+0

map reduce es un paradigma para hacer un proceso único más rápido al utilizar múltiples máquinas, pero hacer cosas diferentes utilizando los mismos datos no es reducir mapa. También un solo mapa y reducción múltiple no tienen ningún sentido. Lo máximo que puede hacer es usar map1-> reduce1-> map2 (hacer el trabajo) -> reduce2 El map2 debe hacer la única función en múltiples divisiones de los datos. –

3

Puede usar claves compuestas. Digamos que necesitas dos tipos de reductores, 'R1' y 'R2'. Agregue identificadores para estos como un prefijo a sus claves o/p en el asignador. Entonces, en el mapeador, una clave 'K' ahora se convierte en 'R1: K' o 'R2: K'.

Luego, en el reductor, pase los valores a las implementaciones de R1 o R2 según el prefijo.

1

Supongo que quiere ejecutar diferentes reductores en una cadena. En hadoop, "múltiples reductores" significa ejecutar varias instancias del mismo reductor. Yo propondría que ejecutaras un reductor a la vez, proporcionando una función de mapa trivial para todas ellas, excepto la primera. Para minimizar el tiempo de transferencia de datos, puede usar la compresión.

Cuestiones relacionadas