Estructura básica del programa MapReduce

Los programas de MapReduce procesan datos en forma de pares (clave/valor), que se pueden expresar de la siguiente forma:

mapa: (K1,V1) ➞ lista(K2,V2)

reducir: (K2, lista (V2)) ➞ lista (K3, V3)

No es sorprendente que esta sea una representación de flujo de datos que va más allá de los datos generales. En este artículo, describiremos cada fase de un programa MapReduce con más detalle. En la figura se muestra un diagrama de alto nivel que representa un proceso completo de Hadoop, y presentaremos un poco las funciones de cada proceso.

 

Vale la pena señalar que la única vez que los nodos se comunican entre sí es durante la fase de "reproducción aleatoria", y tales restricciones de comunicación promueven en gran medida la escalabilidad del programa.

Antes de analizar la transferencia y el procesamiento de datos en una determinada etapa, primero debemos estar familiarizados con los tipos de datos compatibles con Hadoop.

Tipos de datos de Hadoop

Aunque no mencionamos el concepto (clave/valor) en la discusión anterior, la arquitectura de MapReduce no permite que algunos parámetros en el programa sean de clases arbitrarias. Por ejemplo, aunque hablamos de algunos valores clave como enteros, cadenas, etc., en realidad no son objetos estándar de Java (como enteros, cadenas, etc.). Esta es la razón por la que la arquitectura MapReduce tiene sus propios pares clave-valor serializados definidos para manejar los cálculos en el clúster, ya que estas clases admitirán mejor la serialización en esta arquitectura.

En particular, una clase que implementa la interfaz Writable puede ser un valor, mientras que una clase que implementa la interfaz WritableComparable<T> puede ser una clave o un valor. Entonces, la interfaz WritableComparable<T> es una mezcla de Writable y java.lang.Comparable<T>. Necesitamos comparar las claves porque se ordenan durante la fase Reducir, mientras que los valores simplemente se pasan en este punto.

Hadoop ya tiene un conjunto de clases bien definidas que implementan la interfaz WritableComparable, incluidas las clases contenedoras que encapsulan muchos tipos de datos básicos, como se muestra en la siguiente tabla:

Además, también puede crear su propia clase implementando la interfaz WritableComparable o Writable, como se muestra en el siguiente ejemplo:

public class Edge implements WritableComparable<Edge>{

    private String departureNode;

    private String arrivalNode;

    public String getDepartureNode() { return departureNode;}

    @Override

    public void readFields(DataInput in) throws IOException {

        departureNode = in.readUTF();

        arrivalNode = in.readUTF();

    }

    @Override

    public void write(DataOutput out) throws IOException {

        out.writeUTF(departureNode);

        out.writeUTF(arrivalNode);

    }

    @Override

    public int compareTo(Edge o) {

        return (departureNode.compareTo(o.departureNode) != 0)? departureNode.compareTo(o.departureNode) : arrivalNode.compareTo(o.arrivalNode);

    }

}

Esta clase implementa los dos métodos de readFields() y write() en Writable. En el programa subsiguiente, las clases DataInput y DataOutput en Java se utilizan para realizar la serialización del contenido de la clase. Esta clase también implementa el método compareTo() en la interfaz Comparable, donde el valor devuelto es -1, 0 y 1, respectivamente, representan la relación de que el objeto Edge es más pequeño, igual o mayor que el objeto Edge dado.

Mapeador

Para implementar la función de mapeador, una clase puede heredar de la clase MapReduceBase e implementar la interfaz Mapper. La clase MapReduce es la clase básica de mapeador y reductor. Esta clase incluye dos métodos importantes. Estos dos métodos son equivalentes a las funciones de constructor y destructor en la clase:

①void configure(JobConf job)——En esta función, puede extraer los parámetros relevantes a través del archivo XML, o llamar a esta función para extraer los parámetros relevantes al comienzo del programa, es decir, antes de que los datos comiencen a procesarse.

②void close()——Como último paso antes del final del programa de mapas, esta función debe hacer todo el trabajo final: conexión a la base de datos, apertura de archivos, etc.

La interfaz de Mapper es responsable del procesamiento de datos, que utiliza la forma de Mapper<K1, V1, K2, V2> (donde la clase clave-valor implementa WritableComparable y Writable respectivamente). Su única forma es tratar con pares clave-valor.

void map(K1 key,V1 value,OutputCollector<K2,V2> output,Reporter reporter) throws IOException

Esta función genera una secuencia de pares clave-valor (K2,V2) en función de un par de entrada clave-valor (K1,V1) determinado. OutputCollector acepta el resultado del procesamiento del mapa y Reporter proporciona información adicional para registrar el procesamiento del mapeador.

Hadoop proporciona algunas extensiones de clase de mapeador útiles, como puede ver en la siguiente tabla:

reductor

Al igual que el mapeador anterior, el reductor primero debe heredar la clase MapReduce e implementar la interfaz Reducer. Y existe el siguiente método en la interfaz de Reducer:

void reduce(K2 key,Iterator<V2> values,OutputCollector<K3,V3> output,Reporter reporter

) throws IOException

Cuando la tarea reducer recibe resultados de diferentes mapeadores, ordena los datos entrantes por clave y agrega todos los valores con la misma clave. Después de esto, se llama a la función reduce() y luego genera pares <K3, V3> iterando el valor y la clave correspondiente, y OutputCollector acepta el resultado del proceso de reducción y envía el resultado a un archivo. Reporter también proporciona información adicional para registrar tareas de reducción.

El siguiente diagrama proporciona un par de clases de utilidad de reducción proporcionadas por Hadoop

 

Supongo que te gusta

Origin blog.csdn.net/caryxp/article/details/131280363
Recomendado
Clasificación