2012-08-03 37 views
9

¿Alguien sabe cómo implementar la operación Natural-Join entre dos datasets en Hadoop?Unir dos conjuntos de datos en Mapreduce/Hadoop

Más específicamente, esto es lo que exactamente tiene que hacer:

Estoy teniendo dos conjuntos de datos:

información
  1. punto que se almacena como (tile_number, point_id: point_info), esto es a 1: n pares clave-valor. Esto significa que para cada tile_number, puede haber varios point_id: point_info

  2. Información de línea que se almacena como (tile_number, line_id: line_info), este es de nuevo un 1: m pares clave-valor y para cada tile_number, puede haber ser más de un line_id: line_info

Como puede ver, los tile_numbers son los mismos entre los dos datasets. ahora lo que realmente necesito es unir estos dos conjuntos de datos basados ​​en cada tile_number. En otras palabras, para cada tile_number, tenemos n point_id: point_info y m line_id: line_info. Lo que quiero hacer es unirse a todos los pares de point_id: point_info con todos los pares de line_id: line_info para cada tile_number


Con el fin de aclarar, he aquí un ejemplo:

Para los pares de puntos:

(tile0, point0) 
(tile0, point1) 
(tile1, point1) 
(tile1, point2) 

de pares de líneas:

(tile0, line0) 
(tile0, line1) 
(tile1, line2) 
(tile1, line3) 

lo que yo quiero es la siguiente:

para el azulejo 0:

(tile0, point0:line0) 
(tile0, point0:line1) 
(tile0, point1:line0) 
(tile0, point1:line1) 

para el azulejo de 1:

(tile1, point1:line2) 
(tile1, point1:line3) 
(tile1, point2:line2) 
(tile1, point2:line3) 

Respuesta

7

Utilice un asignador de que las salidas de títulos como llaves y puntos/líneas como valores. Debe diferenciar entre los valores de salida de punto y los valores de salida de línea. Por ejemplo, puede usar un carácter especial (aunque un enfoque binario sería mucho mejor).

Así que el mapa de salida será algo así como:

tile0, _point0 
tile1, _point0 
tile2, _point1 
... 
tileX, *lineL 
tileY, *lineK 
... 

Luego, en el reductor, la entrada tendrá la siguiente estructura:

tileX, [*lineK, ... , _pointP, ...., *lineM, ..., _pointR] 

y usted tendrá que tomar los valores separan el puntos y las líneas, haga un producto cruzado y genere cada par del producto cruzado, como este:

tileX (lineK, pointP) 
tileX (lineK, pointR) 
... 

Si ya puede diferenciar fácilmente entre los valores de puntos y los valores de línea (según las especificaciones de su aplicación) no necesita los caracteres especiales (*, _)

Con respecto al producto cruzado que debe hacer en el reductor: en primer lugar, repetir la lista de valores enteros, separarlos en 2 lista:

List<String> points; 
List<String> lines; 

luego hacer el producto cruzado usando 2 bucles for anidados. Entonces iterar a través de la lista resultante y para cada elemento de salida:

tile(current key), element_of_the_resulting_cross_product_list 
+0

grande. pero ¿cómo debo hacer el producto cruzado en la sección de reducción? – reza

+0

¡Edité mi respuesta! – Razvan

+4

genial, pero esto solo funciona si puede ajustar todos los puntos/líneas en la memoria para almacenarlos en las dos listas mencionadas. Me temo que no es el caso en mis conjuntos de datos grandes :( – reza

1

Así que básicamente tiene dos opciones laterales here.Reduce unirse o unirse Mapa lateral.

Aquí su clave de grupo es "tile". En un solo reductor, obtendrás toda la salida del par de puntos y el par de líneas. Pero usted tendrá que guardar el par de puntos o el par de líneas en la matriz. Si cualquiera de los pares (punto o línea) es muy grande y ninguno puede caber en su memoria de matriz temporal para una clave de grupo único (cada mosaico único), entonces este método no funcionará para usted. Recuerde no tiene que mantener ambos pares de teclas para la tecla de un solo grupo ("mosaico") en la memoria, una será suficiente.

Si ambos pares de claves para la llave de un solo grupo son grandes, entonces tendrá que probar la unión del lado del mapa. Pero tiene algunos requisitos peculiares. Sin embargo, puede cumplir con esos requisitos haciendo un preprocesamiento de sus datos a través de algunas tareas de asignación/reducción con la misma cantidad de reductores para ambos datos.