hadoop - means - mapreduce spark
¿Cómo funciona exactamente la partición en MapReduce? (2)
- Puede iniciar las tareas del reductor mientras las tareas del mapa aún se están ejecutando (utilizando una función conocida como inicio lento), pero los reductores solo pueden ejecutar la fase de copia (obteniendo los resultados completos de las tareas del mapa completadas. Deberá esperar todos los los mapeadores deben completarse antes de que puedan realizar la clasificación final y reducirlos.
- Una tarea de reducción realmente procesa cero, una o más claves (en lugar de tareas discretas para cada clave). Cada reductor deberá adquirir la salida del mapa de cada tarea del mapa que se relaciona con su partición antes de que estas salidas intermedias se clasifiquen y luego se reduzcan una clave a la vez.
- De vuelta a la nota en 2: una tarea reductora (una para cada partición) se ejecuta en cero, una o más teclas en lugar de una sola tarea para cada tecla discreta.
También es importante comprender la extensión y la variación de su clave intermedia, ya que está recortada y modulada (si usa el HashPartitioner predeterminado) para determinar qué partición reducida debe procesar esa clave. Digamos que tenía un número par de tareas del reductor (10), y teclas de salida que siempre tienen un número par - entonces, en este caso, el módulo de estos hashs números y 10 siempre será un número par, lo que significa que los reductores con números impares nunca procesar ningún dato.
Creo que tengo un buen entendimiento del modelo de programación de MapReduce en general, pero incluso después de leer el documento original y algunas otras fuentes, muchos detalles no están claros para mí, especialmente con respecto a la división de los resultados intermedios.
Resumiré rápidamente mi comprensión de MapReduce hasta el momento: tenemos un conjunto de datos de entrada potencialmente muy grande, que se divide automáticamente en M partes diferentes mediante el MR-Framework. Para cada pieza, el marco programa una tarea de mapa que es ejecutada por uno de los procesadores / máquinas disponibles en mi clúster. Cada una de las tareas del mapa M genera un conjunto de pares de valores-clave, que se almacenan localmente en la misma máquina que ejecutó esta tarea del mapa. Cada máquina divide su disco en particiones R y distribuye sus pares de valores de clave intermedia calculados en función de las claves intermedias entre las particiones. Luego, el marco comienza para cada tarea de reducción de una clave intermedia distinta, que es ejecutada nuevamente por cualquiera de las máquinas disponibles.
Ahora mis preguntas son:
- En algunos tutoriales, parece que podría haber un mapa y reducir las tareas ejecutadas en paralelo. ¿Es esto correcto? ¿Cómo podría ser eso, asumiendo que para cada clave intermedia distinta solo se inicia una tarea de reducción? ¿No tenemos que esperar hasta que finalice la última tarea del mapa para poder comenzar la primera tarea de reducción?
- Como tenemos una tarea de reducción por clave intermedia distinta, ¿es correcto que cada tarea de reducción requiera que la máquina en ejecución cargue la partición correspondiente desde cada otra máquina? Potencialmente, cada máquina puede tener un par de valor-clave con la clave intermedia deseada, por lo que para cada tarea de reducción potencialmente tenemos que consultar todas las otras máquinas. ¿Es eso realmente eficiente?
- El documento original dice que el número de particiones (R) está especificado por el usuario. ¿Pero no es una partición la entrada para una tarea de reducción? O más exactamente: ¿No es la unión de todas las particiones con el mismo número entre todas las máquinas la entrada de una tarea de reducción? Eso significaría que R depende del número de claves intermedias distintas que el usuario generalmente no sabe.
Conceptualmente, queda claro cuáles son las entradas y salidas del mapa y las funciones / tareas de reducción. Pero creo que todavía no he entendido MapReduce en el nivel técnico. ¿Podría alguien ayudarme por favor a entender?
Adenda a lo que dijo Chris,
Básicamente, una clase de particionador en Hadoop (por ejemplo, HashPartitioner predeterminado)
tiene que implementar esta función,
int getPartition(K key, V value, int numReduceTasks)
Esta función es responsable de devolverle el número de partición y obtendrá la cantidad de reductores que fijó al iniciar el trabajo desde la variable numReduceTasks , como se ve en el HashPartitioner.
Sobre la base de qué entero devuelve la función anterior, Hadoop selecciona el nodo donde se debe ejecutar la tarea de reducción para una clave en particular.
Espero que esto ayude.