Hadoop y MapReduce, ¿Cómo envío el equivalente de una matriz de líneas extraídas de un csv a la función de mapa, donde cada matriz contenía líneas x - y?

De acuerdo, he estado leyendo mucho sobre Hadoop y MapReduce, y tal vez sea porque no estoy tan familiarizado con los iteradores como la mayoría, pero tengo una pregunta que parece que tampoco puedo encontrar una respuesta directa. Básicamente, según tengo entendido, la función de mapa se ejecuta en paralelo por muchas máquinas y / o núcleos. Por lo tanto, cualquier cosa en la que esté trabajando no debe depender de la ejecución previa del código para que el programa obtenga algún tipo de ganancia de velocidad. Esto funciona perfectamente para mí, pero lo que estoy haciendo requiere que pruebe la información en pequeños lotes. Básicamente, necesito enviar lotes de líneas en un .csv como matrices de 32, 64, 128 o cualquier línea cada una. Al igual que las líneas 0-127 van a la ejecución de core1 de la función de mapa, las líneas 128-255 van a core2, etc., .etc. También necesito tener el contenido de cada lote disponible como un todo dentro de la función, como si le hubiera pasado una matriz. Leí un poco sobre cómo la nueva API de Java permite algo llamado push and pull, y que esto permite que las cosas se envíen en lotes, pero no pude encontrar ningún código de ejemplo. No sé, seguiré investigando y publicaré todo lo que encuentre, pero si alguien lo sabe, ¿podría publicarlo en este hilo? Realmente agradecería cualquier ayuda que pudiera recibir.

editar

Si pudiera simplemente asegurarse de que los fragmentos del .csv se envíen en secuencia, podría preformarlo de esta manera. Supongo que esto también supone que hay globales en mapreduce.

//** concept not code **//

GLOBAL_COUNTER = 0;
GLOBAL_ARRAY = NEW ARRAY();

map()
{ 

GLOBAL_ARRAY[GLOBAL_COUNTER] = ITERATOR_VALUE;

GLOBAL_COUNTER++;
if(GLOBAL_COUNTER == 127)
{
//EXECUTE TEST WITH AN ARRAY OF 128 VALUES FOR COMPARISON
GLOBAL_COUNTER = 0;
}

}

preguntado el 27 de agosto de 11 a las 23:08

3 Respuestas

Si está tratando de obtener una parte de las líneas de su archivo CSV en el asignador, podría considerar escribir su propio InputFormat / RecordReader y potencialmente su propio objeto WritableComparable. Con el InputFormat / RecordReader personalizado, podrá especificar cómo se crean los objetos y cómo se pasan al asignador en función de la entrada que reciba.

Si el asignador está haciendo lo que usted quiere, pero necesita que estos fragmentos de líneas se envíen al reductor, haga que la clave de salida del asignador sea la misma para cada línea que desee en la misma función de reducción.

El TextInputFormat predeterminado le dará entrada a su asignador de esta manera (las claves / compensaciones en este ejemplo son solo números aleatorios):

0    Hello World
123  My name is Sam
456  Foo bar bar foo

Cada una de esas líneas se leerá en su mapeador como un par clave, valor. Simplemente modifique la clave para que sea la misma para cada línea que necesite y escríbala en la salida:

0    Hello World
0    My name is Sam
1    Foo bar bar foo

La primera vez que se lea la función de reducción, recibirá una clave, un par de valores con la clave "0" y el valor un objeto Iterable que contiene "Hola mundo" y "Mi nombre es Sam". Podrá acceder a ambos valores en la misma llamada al método de reducción utilizando el objeto Iterable.

Aquí hay un pseudocódigo:

int count = 0
map (key, value) {
      int newKey = count/2
      context.write(newKey,value)
      count++
}

reduce (key, values) {
    for value in values
        // Do something to each line
}

Espero que ayude. :)

Respondido 30 ago 11, 23:08

Si el objetivo final de lo que desea es forzar a ciertos conjuntos a ir a ciertas máquinas para su procesamiento, debe considerar escribir los suyos. Particionador. De lo contrario, Hadoop dividirá los datos automáticamente según la cantidad de reductores.

Sugiero leer el tutorial en el sitio de Hadoop para obtener una mejor comprensión de M / R.

Respondido 28 ago 11, 04:08

Si simplemente desea enviar N líneas de entrada a un solo asignador, puede utilizar el NLineInputFormat clase. A continuación, puede realizar el análisis de líneas (dividir en comas, etc.) en el asignador.

Si desea tener acceso a las líneas antes y después de la línea que el asignador está procesando actualmente, es posible que deba escribir su propio formato de entrada. Crear subclases de FileInputFormat suele ser un buen punto de partida. Puede crear un InputFormat que lea N líneas, las concatene y las envíe como un bloque a un asignador, que luego divide la entrada en N líneas nuevamente y comienza a procesar.

En lo que respecta a los globales en Hadoop, puede especificar algunos parámetros personalizados cuando crea la configuración del trabajo, pero hasta donde yo sé, no puede cambiarlos en un trabajador y esperar que el cambio se propague por todo el clúster. Para establecer un parámetro de trabajo que será visible para los trabajadores, haga lo siguiente donde está creando el trabajo:

job.getConfiguration().set(Constants.SOME_PARAM, "my value");

Luego, para leer el valor de los parámetros en el mapeador o reductor,

public void map(Text key, Text value, Context context) {

        Configuration conf = context.getConfiguration();
        String someParam = conf.get(Constants.SOME_PARAM);

        // use someParam in processing input
}

Hadoop tiene soporte para tipos básicos como int, long, string, bool, etc. para ser usados ​​en parámetros.

Respondido el 01 de Septiembre de 11 a las 13:09

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.