mapreduce en hadoop

67
MapReduce en Hadoop Tomás Fernández Pena Máster en Computación de Altas Prestaciones Universidade de Santiago de Compostela Computación en Sistemas Distribuidos Material bajo licencia Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) citius.usc.es

Upload: tomas-pena

Post on 25-May-2015

1.394 views

Category:

Software


4 download

DESCRIPTION

Uso de MapReduce en Hadoop v2. Algoritmos MapReduce.

TRANSCRIPT

Page 1: MapReduce en Hadoop

MapReduce en Hadoop

Tomás Fernández Pena

Máster en Computación de Altas Prestaciones

Universidade de Santiago de Compostela

Computación en Sistemas Distribuidos

Material bajo licencia Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)citius.usc.es

Page 2: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Índice

1 Java MapReduce en Hadoop

2 Serialización y Entrada/Salida

Entrada/salida con ficheros de texto

Compresión

Entrada salida/binaria

Serialización con Avro

3 Tareas MapReduce

Algoritmos: encadenamiento, ordenación, fuentes múltiples

Localización de dependencias

Contadores

Ejemplo avanzado

4 Otros aspectos

5 Alternativas a Java

MapReduce en Hadoop, CSD

Page 3: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Índice

1 Java MapReduce en Hadoop

2 Serialización y Entrada/Salida

Entrada/salida con ficheros de texto

Compresión

Entrada salida/binaria

Serialización con Avro

3 Tareas MapReduce

Algoritmos: encadenamiento, ordenación, fuentes múltiples

Localización de dependencias

Contadores

Ejemplo avanzado

4 Otros aspectos

5 Alternativas a Java

MapReduce en Hadoop, CSD

Page 4: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Java MapReduce en Hadoop

Un programa MapReduce en Java debe definir 3 clases:

1. Una clase mapper

2. Una clase reducer

3. Una clase principal, con el método main

Pueden crearse

como tres clases públicas separadas

como una sola, con el método main, y clases internas static para

mapper y reducer

MapReduce en Hadoop, CSD 1/58

Page 5: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Nueva y vieja API

Los programas pueden usar la nueva API (recomendado) o la antigua

Ambas APIs son incompatibles

Utilizaremos siempre la API nueva

Disponible desde Hadoop 0.20.0

Definida en el paquete org.apache.hadoop.mapreduce

Algunas librerías presentes en la API vieja no han sido portadas

API vieja (desaconsejada)

Definida en el paquete org.apache.hadoop.mapred

MapReduce en Hadoop, CSD 2/58

Page 6: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

WordCount Mapper

public class WordCountMapper

extends Mapper<LongWritable , Text , Text , IntWritable> {

@Override

public void map(LongWritable key , Text value , Context ctxt )

throws IOException , InterruptedException {

Matcher matcher = pat .matcher(value . toString ( ) ) ;

while (matcher . f ind ( ) ) {

word. set (matcher .group ( ) . toLowerCase ( ) ) ;

ctxt . write (word, one) ;

}

}

private Text word = new Text ( ) ;

private f ina l stat ic IntWritable one = new IntWritable (1) ;

private Pattern pat =

Pattern . compile ( " \ \ b[a−zA−Z\ \u00C0−\\uFFFF]+\\b" ) ;

}

MapReduce en Hadoop, CSD 3/58

Page 7: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

WordCount Mapper

Extiende la clase

Mapper<KEYIN,VALUEIN,KEYOUT,VALUEOUT>

Debe sobrescribir el método

map(KEYIN key, VALUEIN value, Mapper.Contextcontext)

Usa una instancia de Context en la que escribe los pares

clave/valor de salida

Debe utilizar tipos de datos que implementen la interfazWritable (como LongWritable o Text)

. optimizados para serialización

Otros métodos que se pueden sobrescribir:

. setup(Context context) Llamado una vez al comienzo de la

tarea

. cleanup(Context context) Llamado una vez al final de la

tarea

MapReduce en Hadoop, CSD 4/58

Page 8: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

WordCount Reducer

public class WordCountReducer

extends Reducer<Text , IntWritable , Text , IntWritable> {

@Override

public void reduce(Text key , Iterable<IntWritable> values ,

Context ctxt ) throws IOException , InterruptedException {

int sum = 0;

for ( IntWritable value : values ) {

sum += value . get ( ) ;

}

ctxt . write (key , new IntWritable (sum) ) ;

}

}

MapReduce en Hadoop, CSD 5/58

Page 9: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

WordCount Reducer

Extiende la clase

Reducer<KEYIN,VALUEIN,KEYOUT,VALUEOUT>

Debe sobrescribir el método

reduce(KEYIN key, Iterable<VALUEIN> values,Reducer.Context context)

Usa una instancia de Context en la que escribe los pares

clave/valor de salida

Debe utilizar tipos de datos que implementen la interfazWritable (como LongWritable o Text)

. optimizados para serialización

Otros métodos que se pueden sobrescribir:

. setup(Context context) Llamado una vez al comienzo de la

tarea

. cleanup(Context context) Llamado una vez al final de la

tarea

MapReduce en Hadoop, CSD 6/58

Page 10: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

WordCount Driver (I)

public class WordCountDriver

extends Configured implements Tool {

public int run( String [ ] arg0) throws Exception {

i f (arg0 . length != 2) {

System. err . pr int f ( "Usar : %s [ops] <entrada> <salida >\n" ,

getClass ( ) .getSimpleName() ) ;

ToolRunner .printGenericCommandUsage(System. err ) ;

return −1;

}

Configuration conf = getConf ( ) ;

Job job = Job . getInstance (conf ) ;

job .setJobName( "Word Count" ) ;

job . setJarByClass ( getClass ( ) ) ;

FileInputFormat . addInputPath( job , new Path(arg0[0]) ) ;

FileOutputFormat . setOutputPath ( job , new Path(arg0[1]) ) ;

MapReduce en Hadoop, CSD 7/58

Page 11: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

WordCount Driver (II)

job . setOutputKeyClass (Text . class ) ;

job . setOutputValueClass ( IntWritable . class ) ;

job .setNumReduceTasks(4) ;

job . setMapperClass(WordCountMapper. class ) ;

job . setCombinerClass (WordCountReducer . class ) ;

job . setReducerClass (WordCountReducer . class ) ;

return ( job . waitForCompletion ( true ) ? 0 : −1);

}

public stat ic void main( String [ ] args ) throws Exception {

int exitCode = ToolRunner . run(new WordCountDriver ( ) , args ) ;

System. exit (exitCode) ;

}

}

MapReduce en Hadoop, CSD 8/58

Page 12: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

WordCount Driver

Clase Configured: permite acceder a la configuración delsistema

. Método Configuration getConf(): devuelve la

configuración actual

Clase Configuration: proporciona acceso a la configuración

Clase Job: permite configurar, enviar y controlar la ejecución de un

trabajo

Clase FileInputFormat<K,V>: describe los ficheros de

entrada en un trabajo MapReduce

Clase FileOutputFormat<K,V>: describe los ficheros de

entrada en un trabajo MapReduce

MapReduce en Hadoop, CSD 9/58

Page 13: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

WordCount Driver

Interfaz Tool: interfaz estándar para aplicaciones MapReduce,

soporta el manejo de opciones en línea de comandos

Clase ToolRunner: ejecuta clases que implementan la interfaz

Tool

Clase Path: identifica a un fichero o directorio en el FileSystem

MapReduce en Hadoop, CSD 10/58

Page 14: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Número de Reducers

Tener un único reducer no suele ser una buena idea

Más reducers: más paralelismo

Más reducers: startup más lento, más overhead de disco y red

Difícil determinar el número óptimo

Ver wiki.apache.org/hadoop/HowManyMapsAndReduces

Varios reducers producen varios ficheros de salida:

Se pueden unir con hdfs dfs -getmerge

MapReduce en Hadoop, CSD 11/58

Page 15: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Compilación y ejecución

Preferiblemente, crear un jar con todas las clases y ejecutarlo con:

yarn jar fichero.jar [opciones]

Para gestionar las aplicaciones, utilizad:

. en general, la opción application del comando yarn (yarnapplication -help para ver las opciones)

. para trabajos MapReduce, la opción job del comando mapred(mapred job -help para ver las opciones)

Más información en

. hadoop.apache.org/docs/current/hadoop-yarn/hadoop-yarn-

site/YarnCommands.html

. hadoop.apache.org/docs/current/hadoop-mapreduce-client/hadoop-

mapreduce-client-core/MapredCommands.html

MapReduce en Hadoop, CSD 12/58

Page 16: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Índice

1 Java MapReduce en Hadoop

2 Serialización y Entrada/Salida

Entrada/salida con ficheros de texto

Compresión

Entrada salida/binaria

Serialización con Avro

3 Tareas MapReduce

Algoritmos: encadenamiento, ordenación, fuentes múltiples

Localización de dependencias

Contadores

Ejemplo avanzado

4 Otros aspectos

5 Alternativas a Java

MapReduce en Hadoop, CSD

Page 17: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Writables

Formato de serialización de objetos de Hadoop

Transforma objetos en un flujo de bytes para transmisión o

almacenamiento

Gran número de clases que implementan el interfaz Writable:

Objetos primitivos: BooleanWritable, ByteWritable,

IntWritable, LongWritable, FloatWritable,

DoubleWritable, Text (cadenas UTF-8)

Objetos primitivos de longitud variable: VIntWritable,

VLongWritable

Colecciones: ArrayWritable, ArrayPrimitiveWritable,

TwoDArrayWritable, MapWritable,

SortedMapWritable

Otros: NullWritable, BytesWritable, ObjectWritable,

GenericWritable,

MapReduce en Hadoop, CSD 13/58

Page 18: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Writables a medida

Es posible implementar writables a medida

Implementar la interfaz Writable. Implementar los métodos write(DataOutput out) y

readFields(DataInput in)

Un objeto que se quiera usar como clave debe implementar

WritableComparable

MapReduce en Hadoop, CSD 14/58

Page 19: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Ejemplo de writable

public class MyWritable implements Writable {

/ / Incluye un entero y un long

private IntWritable counter ;

private LongWritable timestamp;

public void write (DataOutput out ) throws IOException {

counter . write (out ) ;

timestamp. write (out ) ;

}

public void readFields (DataInput in ) throws IOException {

counter . readFields ( in ) ;

timestamp. readFields ( in ) ;

}

public stat ic MyWritable read(DataInput in ) throws IOException {

MyWritable w = new MyWritable ( ) ;

w. readFields ( in ) ;

return w;

}

}

MapReduce en Hadoop, CSD 15/58

Page 20: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Clase abstracta FileInputFormat<K,V>

Define métodos para añadir uno o varios paths de entrada al trabajoaddInputPath(Job job, Path path), addInputPaths(Jobjob, String commaSeparatedPaths)

Clase base para diferentes formatos de entrada concretos

El formato a usar se especifica mediante el método

setInputFormatClass del Job, por ejemplo:

job.setInputFormatClass(TextInputFormat.class)

MapReduce en Hadoop, CSD 16/58

Page 21: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Formatos de entrada

TextInputFormat: formato por defecto para ficheros de texto

KeyValueTextInputFormat: ficheros de texto con estructura

clave/valor

NLineInputFormat: permite que los mappers reciban un

número fijo de líneas de entrada

SequenceFileInputFormat: secuencias de datos binarios

clave/valor

CombineFileInputFormat: Permite empaquetar varios

ficheros pequeños en un split de entrada de un tamaño

determinado

FixedLengthInputFormat: Usado para leer ficheros con

registros de longitud fija

MapReduce en Hadoop, CSD 17/58

Page 22: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Formatos de entrada

TextInputFormat:

. Formato por defecto

. Cada mapper recibe un trozo (split) del fichero y lo procesa línea a

línea

. Como clave, toma el offset en bytes en el fichero desde el comienzo

de la línea (LongWritable)

. Como valor, toma toda la línea

KeyValueTextInputFormat:

. Igual que el anterior, pero separa cada línea en clave/valor

. Usa tabulado como separador por defecto

. Para cambiar, modificar en el objeto Configuration la propiedad

mapreduce.input.keyvaluelinerecordreader.key.value.separator

Nota: en la API vieja es key.value.separator.in.input.line

MapReduce en Hadoop, CSD 18/58

Page 23: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Salida de ficheros

Similar a la entrada: clase abstracta FileOutputFormat<K,V>

Clase base para diversos formatos de salida concretos

. TextOutputFormat: formato por defecto para ficheros de texto

- Escribe líneas de texto en formato clave/valor separados por un

tabulado

- Carácter de separación modificable:

mapreduce.output.textoutputformat.separatorAPI vieja mapred.textoutputformat.separator

. SequenceFileOutputFormat: secuencias de datos binarios

clave/valor

. MapFileOutputFormat: Un formato de salida que escribe

MapFiles

El formato a usar se especifica mediante el método

setOutputFormatClass del Job

MapReduce en Hadoop, CSD 19/58

Page 24: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Compresión

Como vimos en el WordCount, Hadoop lee directamente ficheros

comprimidos:

Los ficheros se descomprimen automáticamente, usando la

terminación del fichero para determinar que codec usar

Formato Java/Nativo Splittable Codec

zlib/DEFLATE Sí/Sí No DefaultCodecgzip Sí/Sí No GzipCodecbzip2 Sí/Sí Sí BZip2CodecLZO No/Sí No (Sí con preproceso) LzopCodecLZ4 No/Sí No Lz4CodecSnappy No/Sí No SnappyCodec

MapReduce en Hadoop, CSD 20/58

Page 25: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Compresión

Fuente: Kamat, G., Singh, S., “Compression Options in Hadoop - A Tale of Tradeoffs”, Hadoop Summit (San Jose), June 27, 2013

MapReduce en Hadoop, CSD 21/58

Page 26: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Compresión

Recomendaciones:

Usar contenedores binarios como Sequence File o Avro datafile

(soportan compresión y splitting)

Usar formatos splittables

Dividir los ficheros en trozos y comprimirlos por separado (cada

trozo comprimido debería ocupar un bloque HDFS)

No usar compresión

MapReduce en Hadoop, CSD 22/58

Page 27: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Entrada salida/binaria

Hadoop puede usar ficheros binarios de entrada/salida usando la clase

SequenceFile

Estructura de datos persistente para pares binarios clave/valor

Para crear un SequenceFile:

IntWritable key = new IntWritable (3) ;

Text value = new Text ( " tres " ) ;

Path path = new Path( ur i ) ;

writer = SequenceFile . createWriter ( conf , SequenceFile . Writer . f i l e (path) ,

SequenceFile . Writer . keyClass (key . getClass ( ) ) ,

SequenceFile . Writer . valueClass (value . getClass ( ) ) ) ;

writer .append(key , value ) ;

IOUti ls . closeStream( writer ) ;

Para leer el fichero, en el programa crear un SequenceFile.Readery usar next()

MapReduce en Hadoop, CSD 23/58

Page 28: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Serialización con Avro

Apache Avro es un sistema de serialización independiente del lenguaje

Formato procesable por varios lenguajes: C, C++, C#, Java, PHP,

Python y Ruby

Puede substituir a los Writables

Proporciona clases para facilitar crear programas MapReduce que

usen datos Avro (usa la API vieja)

Tipos de datos en Avro

Primitivos: null, boolean, int, long, float, double, string

Complejos: array, map, record, enum, fixed, union

MapReduce en Hadoop, CSD 24/58

Page 29: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Serialización con Avro

Apache Avro es un sistema de serialización independiente del lenguaje

Formato procesable por varios lenguajes: C, C++, C#, Java, PHP,

Python y Ruby

Puede substituir a los Writables

Proporciona clases para facilitar crear programas MapReduce que

usen datos Avro (usa la API vieja)

Tipos de datos en Avro

Primitivos: null, boolean, int, long, float, double, string

Complejos: array, map, record, enum, fixed, union

MapReduce en Hadoop, CSD 24/58

Page 30: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Esquemas Avro

Los esquemas Avro permiten construir estructuras de datos complejas

Se escriben habitualmente en formato JSON

Se guardan en un fichero con terminación .avsc

En Java podemos usar dos APIs para manejarlos:

API genérica:

. Mapping dinámico

. Puede usarse aunque el esquema no sea conocido hasta runtime

API específica

. A partir del esquema, se genera código que lo representa

. Necesita conocer el esquema en tiempo de compilación

MapReduce en Hadoop, CSD 25/58

Page 31: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Esquemas Avro

Ejemplo de esquema

{

"namespace" : "cursohadoop . creaavrofi le " ,

"type" : "record" ,

"name" : "PatentData" ,

"doc" : "Dos enteros y un string " ,

" f ie lds " : [

{"name" : "patente" , "type" : " long"},

{"name" : "anho" , "type" : " int "},

{"name" : "pais " , "type" : " string "}

]

}

MapReduce en Hadoop, CSD 26/58

Page 32: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Avro Datafiles

Contenedores de objetos similares a los SequenceFile

Crear un Avro DataFile con la API genérica

Schema. Parser parser = new Schema. Parser ( ) ;

Schema schema =

parser . parse( getClass ( ) . getResourceAsStream( "PatentData . avsc" ) ) ;

FileSystem fsout = FileSystem . get (URI . create (out ) , conf ) ;

OutputStream os = fsout . create (new Path(out ) ) ;

DatumWriter<GenericRecord> writer = new

GenericDatumWriter<GenericRecord>(schema) ;

DataFileWriter<GenericRecord> dataFileWriter = new

DataFileWriter<GenericRecord>(writer ) ;

dataFileWriter . create (schema, os) ;

GenericRecord patente = new GenericData .Record(schema) ;

patente . put ( "patente" , 12345678);

patente . put ( "anho" , 2013) ;

patente . put ( "pais" , "ES" ) ;

dataFileWriter .append(patente ) ;

MapReduce en Hadoop, CSD 27/58

Page 33: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Ejemplo: WordCount con salida Avro

Cambios en el WordCountDriver para usar salida Avro:

job . setInputFormatClass (TextInputFormat . class ) ;

job . setOutputFormatClass (AvroKeyValueOutputFormat . class ) ;

job . setMapOutputKeyClass(Text . class ) ;

job . setMapOutputValueClass( IntWritable . class ) ;

AvroJob .setOutputKeySchema( job , Schema. create (Type.STRING) ) ;

AvroJob . setOutputValueSchema( job , Schema. create (Type. INT) ) ;

Eliminar las definiciones job.setOutputKeyClass(Text.class) y

job.setOutputValueClass(IntWritable.class), y no uséis Combiner.

MapReduce en Hadoop, CSD 28/58

Page 34: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Ejemplo: WordCount con salida Avro

Cambios en el WordCountReducer para usar salida Avro:

public class AvroWordCountReducer extends Reducer<Text , IntWritable ,

AvroKey<CharSequence>, AvroValue<Integer>> {

public void reduce(Text key , Iterable<IntWritable> values , Context ctxt )

throws IOException , InterruptedException {

int sum = 0;

for ( IntWritable value : values ) {

sum += value . get ( ) ;

}

ctxt . write (new AvroKey<CharSequence>(key . toString ( ) ) , new

AvroValue<Integer>(sum) ) ;

}

}

MapReduce en Hadoop, CSD 29/58

Page 35: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Ejecutar el WordCount salida Avro en el cluster

Dependencias en el pom.xml

hadoop-core (2.5.1), avro (1.7.4 [jar]), avro-mapred (1.7.5,

[jar,hadoop2])

Definición del classpath:

Definir HADOOP_CLASSPATH (export HADOOP_CLASSPATH)

para que incluya los jars de avro, avro-mapred y paranamer

(separados por “:”)

Definir una variable LIBJARS que incluya los mismos jars, pero

separados por “,”

Esos jars los encontramos en $HOME/.m2/repository bajo

org/apache/avro/avro/1.7.4 y

org/apache/avro/avro-mapred/1.7.4

Ejecución:

$ yarn jar wordcountavro*.jar -libjars $LIBJARS libros

librosoutavro

MapReduce en Hadoop, CSD 30/58

Page 36: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Verificar la salida Avro

La salida del código anterior es uno o varios ficheros .avro

Para leerlo, podemos usar las avro-tools

Descargar el fichero avro-tools-*.jar desde avro.apache.org

(la versión estable)

Ejecutar:

$ java -jar avro-tools-*.jar tojson fichero.avro

MapReduce en Hadoop, CSD 31/58

Page 37: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Índice

1 Java MapReduce en Hadoop

2 Serialización y Entrada/Salida

Entrada/salida con ficheros de texto

Compresión

Entrada salida/binaria

Serialización con Avro

3 Tareas MapReduce

Algoritmos: encadenamiento, ordenación, fuentes múltiples

Localización de dependencias

Contadores

Ejemplo avanzado

4 Otros aspectos

5 Alternativas a Java

MapReduce en Hadoop, CSD

Page 38: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Encadenamiento de trabajos MapReduce

Es posible encadenar trabajos MapReduce

Basta con definir varios jobs y lanzarlos unos detrás de otros

La salida a disco de un job es leída por el siguiente

Alternativa

Usar las clases ChainMapper y ChainReducer

Permiten encadenar varios mappers seguidos de un reducer y un

mapper adicional ([MAP+ / REDUCE MAP*])

Reduce los accesos a disco

Para workflows complejos, se puede usar Apache Oozie o Cascading

MapReduce en Hadoop, CSD 32/58

Page 39: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Ordenación

Por defecto, MapReduce ordena los registros de entrada por las claves

Uso para hacer ordenamientos de datos

Problema si usamos múltiples reducers

Es posible usar hdfs dfs -getmerge para unirlos

Lento con ficheros grandes

MapReduce en Hadoop, CSD 33/58

Page 40: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Total Sort

Producir un conjunto de ficheros ordenados, que concatenados, formen

un fichero ordenado global

Usar como particionador un objeto de la clase

TotalOrderPartitioner

Efectúa una ordenación total leyendo marcas de separación de una

fuente externa

Usar un InputSampler para obtener las muestras

MapReduce en Hadoop, CSD 34/58

Page 41: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Secondary Sort

La ordenación se hace sólo por la clave:

El orden en que aparecen los valores no está fijado

Es posible imponer un orden en el que aparecen los valores:

Hacer que la clave esté compuesta por la clave natural y el valor

natural (objeto WritableComparable)

El comparador de ordenación debe ordenar usando esa clave

compuesta

El particionador debe considerar sólo la clave natural

El comparador de agrupamiento usa una u otra según el caso

MapReduce en Hadoop, CSD 35/58

Page 42: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Secondary SortEjemplo de clave compuesta

Clave compuesta

Clave Valor{ {{

Particionar

Ordenar/Agrupar

Se ordena por la clave compuesta [clave, valor](job.setSortComparatorClass)

Se particiona por clave (job.setPartitionerClass,

garantiza que las mismas claves van al mismo reducer)

Se agrupa por la clave o la clave compuesta [clave, valor]dependiendo del problema

(job.setGroupingComparatorClass)

MapReduce en Hadoop, CSD 36/58

Page 43: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Joins de datos de diferentes fuentes

Hacer uniones de datos de diferentes fuentes es complejo en Hadoop

Preferible usar lenguajes de alto nivel como Pig o Hive

En Hadoop hay varias soluciones:

Si un conjunto de datos es grande y el otro pequeño, se puede

replicar el pequeño en todos los nodos usando Distributed Cache

Map-Side joins: el join se realiza antes de llegar a la función map

. Los conjuntos de datos deben dividirse en el mismo número de

particiones y estar ordenados por la clave de unión

Reduce-side joins: el join se realiza en el reducer

. El mapper etiqueta cada dato con su fuente y usa la clave de unión

como clave de salida

MapReduce en Hadoop, CSD 37/58

Page 44: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Localización de dependencias

Mecanismo para copiar recursos (LocalResources) a los nodos del cluster

Hadoop (DistributedCache en Hadoop v1)

Los recursos (ficheros, archivos, librerías) se copian a todos los

nodos una vez por trabajo

Las aplicaciones pueden acceder directamente a estos recursos

Tipos de LocalResources:

. FILE: Ficheros normales

. ARCHIVE: Ficheros comprimidos (jar, tar, tar,gz, zip) que

descomprime el NodeManager

. PATTERN: Híbrido de ARCHIVE y FILE (se mantiene el fichero y se

descomprime parte)

Visibilidad de los LocalResources

. PUBLIC: accesibles por todos los usuarios

. PRIVATE: compartidos por aplicaciones del mismo usuario en el nodo

. APPLICATION: compartidos entre containers de la misma aplicación

MapReduce en Hadoop, CSD 38/58

Page 45: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Uso en línea de comandos

Si el código usa GenericOptionParser (o ToolRunner), los

ficheros a copiar se indican como parámetro:

-files + lista separada por comas de URIs de los ficheros

-archives + ficheros comprimidos (archivos)

-libjars + JARS para añadir al CLASSPATH

Ejemplo:

hadoop jar mr.jar -files ~/fichero in out

MapReduce en Hadoop, CSD 39/58

Page 46: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Uso desde la aplicación

Métodos definidos en Job

addCacheFile(URI uri): añade un fichero a la cache

addCacheArchive(URI uri): añade un archivo a la cache

addFileToClassPath(Path file): añade un fichero al

CLASSPATH

addArchiveToClassPath(Path file): añade un archivo

al CLASSPATH

URI[] getCacheFiles(): obtiene los ficheros en la cache

URI[] getCacheArchives(): obtiene los archivos en la

cache

MapReduce en Hadoop, CSD 40/58

Page 47: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Contadores

Hadoop incorpora contadores para obtener datos del trabajo:

Contadores internos: informan sobre el comportamiento de la

ejecución

Contadores definidos por el usuario (interfaz Counter)

. Permiten obtener información adicional sobre las tareas

. Definidos mediante Java enums, que permiten agrupar contadores

relacionados

. Se accede a ellos mediante el método getCounter() del

MapContext o el ReduceContext. Se modifican mediante los métodos del interfaz Counter

MapReduce en Hadoop, CSD 41/58

Page 48: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

WordCount2 Mapper (I)

public class WordCountMapper2 extends

Mapper<LongWritable , Text , Text , IntWritable> {

stat ic enum CountersEnum {

PALABRAS_INCLUIDAS

}

@Override

public void setup(Context ctxt ) throws IOException ,

InterruptedException {

conf = ctxt . getConfiguration ( ) ;

caseSensitive = conf . getBoolean( "wordcount . case . sensitive " , true ) ;

i f ( conf . getBoolean( "wordcount . skip . patterns" , false ) ) {

URI [ ] patternsURIs = Job . getInstance (conf ) . getCacheFiles ( ) ;

for (URI patternsURI : patternsURIs ) {

Path patternsPath = new Path( patternsURI . getPath ( ) ) ;

String patternsFileName = patternsPath .getName() . toString ( ) ;

parseSkipFile (patternsFileName) ;

}

}

}

MapReduce en Hadoop, CSD 42/58

Page 49: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

WordCount2 Mapper (II)@Override

public void map(LongWritable key , Text value , Context ctxt ) throws

IOException , InterruptedException {

String l ine = ( caseSensitive ) ? value . toString ( ) :

value . toString ( ) . toLowerCase ( ) ;

for ( String pattern : patternsToSkip ) {

l ine = l ine . replaceAll ( " \ \ b"+pattern+" \ \ b" , " " ) ;

}

Matcher matcher = pat .matcher( l ine ) ;

while (matcher . f ind ( ) ) {

String token = matcher .group ( ) ;

i f (words . containsKey( token) ) {

int total = words . get ( token) + 1;

words . put ( token , total ) ;

} else {

words . put ( token , 1) ;

}

ctxt . getCounter (CountersEnum.PALABRAS_INCLUIDAS) . increment(1) ;

}

}

MapReduce en Hadoop, CSD 43/58

Page 50: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

WordCount2 Mapper (III)

@Override

public void cleanup(Context ctxt ) throws

IOException , InterruptedException {

Iterator<Map. Entry<String , Integer>> i t = words . entrySet ( ) . i terator ( ) ;

while ( i t . hasNext ( ) ) {

Map. Entry<String , Integer> entry = i t . next ( ) ;

String sKey = entry .getKey ( ) ;

int total = entry . getValue ( ) . intValue ( ) ;

ctxt . write (new Text (sKey) , new IntWritable ( total ) ) ;

}

}

MapReduce en Hadoop, CSD 44/58

Page 51: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

WordCount2 Mapper (IV)

private void parseSkipFile ( String fileName) {

try {

f i s = new BufferedReader (new FileReader ( fileName) ) ;

String pattern = nul l ;

while ( ( pattern = f i s . readLine ( ) ) != nul l ) {

patternsToSkip .add( pattern ) ;

}

} catch ( IOException ioe ) {

System. err . pr int ln ( "Excepcion parseando el recurso local ’ " +

Str ingUti ls . stringifyException ( ioe ) ) ;

}

}

private boolean caseSensitive ;

private Set<String> patternsToSkip = new HashSet<String >() ;

private Map<String , Integer> words = new HashMap<String , Integer >() ;

private Pattern pat = Pattern . compile ( " \ \ b[a−zA−Z\ \u00C0−\\uFFFF]+\\b" ) ;

private Configuration conf ;

private BufferedReader f i s ;

}

MapReduce en Hadoop, CSD 45/58

Page 52: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

WordCount2 Driver (I)

public class WordCountDriver2 extends Configured implements Tool {

public int run( String [ ] args ) throws Exception {

Configuration conf = getConf ( ) ;

Job job = Job . getInstance (conf ) ;

job .setJobName( "Word Count 2" ) ;

job . setJarByClass ( getClass ( ) ) ;

GenericOptionsParser optionParser = new GenericOptionsParser (conf ,

args ) ;

String [ ] remainingArgs = optionParser . getRemainingArgs ( ) ;

i f ( ! ( remainingArgs . length != 2 | | remainingArgs . length != 4) ) {

System. err . pr int f ( "Usar : %s [ops] <entrada> <salida> [−skip

skipPatternFile ] \n" , getClass ( ) .getSimpleName() ) ;

return −2;

}

MapReduce en Hadoop, CSD 46/58

Page 53: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

WordCount2 Driver (II)

List<String> otherArgs = new ArrayList<String >() ;

for ( int i=0; i < remainingArgs . length ; ++i ) {

i f ( "−skip " . equals ( remainingArgs[ i ] ) ) {

job . addCacheFile (new Path( remainingArgs[++i ] ) . toUri ( ) ) ;

job . getConfiguration ( ) . setBoolean( "wordcount . skip . patterns" ,

true ) ;

} else {

otherArgs .add( remainingArgs[ i ] ) ;

}

}

FileInputFormat . addInputPath( job , new Path(otherArgs . get (0) ) ) ;

FileOutputFormat . setOutputPath ( job , new Path(otherArgs . get (1) ) ) ;

MapReduce en Hadoop, CSD 47/58

Page 54: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

WordCount2 Driver (III)

job . setOutputKeyClass (Text . class ) ;

job . setOutputValueClass ( IntWritable . class ) ;

job .setNumReduceTasks(1) ;

job . setMapperClass(WordCountMapper3. class ) ;

/ /Usa in−mapper combiner

job . setReducerClass (WordCountReducer3. class ) ;

return ( job . waitForCompletion ( true ) ? 0 : −1);

}

public stat ic void main( String [ ] args ) throws Exception {

int exitCode = ToolRunner . run(new WordCountDriver3 ( ) , args ) ;

System. exit (exitCode) ;

}

}

Ejemplo de ejecución:

yarn -jar wc2.jar \-Dwordcount.case.sensitive=true indir outdir \-skip skipfile.txt

MapReduce en Hadoop, CSD 48/58

Page 55: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Índice

1 Java MapReduce en Hadoop

2 Serialización y Entrada/Salida

Entrada/salida con ficheros de texto

Compresión

Entrada salida/binaria

Serialización con Avro

3 Tareas MapReduce

Algoritmos: encadenamiento, ordenación, fuentes múltiples

Localización de dependencias

Contadores

Ejemplo avanzado

4 Otros aspectos

5 Alternativas a Java

MapReduce en Hadoop, CSD

Page 56: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Reuso de las JVM

Por defecto, cada tarea Hadoop se ejecuta en su propia JVM

Mejora el aislamiento entre tareas

Puede suponer un sobrecosto en tareas pequeñas

Es posible reusar las JVMs

Varias tareas (del mismo job) se pueden ejecutar secuencialmente

en una misma JVM

La propiedad que controla el reuso es

mapreduce.job.jvm.numtasks

Su valor por defecto es 1

. Un -1 indica sin límite

MapReduce en Hadoop, CSD 49/58

Page 57: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Scheduling

Por defecto, YARN usa Capacity Scheduler con una única cola

(default)

En Hadoop V1 se usa una cola FIFO con prioridades

El scheduler a usar se especifica mediante la variable

yarn.resourcemanager.scheduler.class

En Hadoop V1 propiedad

mapred.jobtracker.taskScheduler

Los scheduler más usados son

Capacity Scheduler

Fair Scheduler

MapReduce en Hadoop, CSD 50/58

Page 58: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Capacity Scheduler

Desarrollado por Yahoo, características similares al anterior

Los trabajos se envían a colas, que pueden ser jerárquicas

A cada cola se le reserva una fracción de la capacidad total

En cada cola, los trabajos usan FIFO con prioridades

. Permite simular un cluster MapReduce con FIFO para cada usuario u

organización

Se configura mediante el fichero capacity-scheduler.xml

Más información: hadoop.apache.org/docs/current/hadoop-yarn/hadoop-

yarn-site/CapacityScheduler.html

MapReduce en Hadoop, CSD 51/58

Page 59: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Fair Scheduler

Desarrollado por Facebook, con el objetivo de compartir equitativamente

la capacidad del cluster

Intenta proporcionar tiempos de respuesta rápidos para trabajos

cortos y QoS para trabajos en producción

Los trabajos se colocan en pools

Por defecto, cada usuario tiene su propia pool

A cada pool se le garantiza un mínimo de capacidad

. Mínimo numero de map slots, reduce slots, y máximo número de

trabajos simultáneos

La capacidad sobrante se reparte entre los trabajos

Es apropiativo:

. Si un pool no recibe su capacidad mínima, el scheduler puede matar

trabajos que estén usando por encima de su capacidad

Más información: hadoop.apache.org/docs/current/hadoop-yarn/hadoop-

yarn-site/FairScheduler.html

MapReduce en Hadoop, CSD 52/58

Page 60: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Ejecución especulativa

Por defecto, la ejecución especulativa está activada

Si una tarea se retrasa, se lanza especulativamente una copia de la

misma

En un cluster muy ocupado, esto puede significar un consumo excesivo

de recursos

Se puede deshabilitar la especulación para mappers o reducers

Más interesante para reducers

. Un reduce duplicado implica volver a obtener las salidas de los

mappers

. Aumento del tráfico de red

Propiedades (booleanas):

mapreduce.map.speculativemapreduce.reduce.speculative

MapReduce en Hadoop, CSD 53/58

Page 61: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Tests unitarios con MRUnit

Apache MRUnit es una librería Java que facilita el desarrollo de tests

unitarios para trabajos MapReduce

Clases MapDriver y ReduceDriver

Utilidades que permiten testear el mapper y el reducer

. Se les proporciona pares clave-valor como entrada y se chequea que

la salida sea la esperada

MapReduce en Hadoop, CSD 54/58

Page 62: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Índice

1 Java MapReduce en Hadoop

2 Serialización y Entrada/Salida

Entrada/salida con ficheros de texto

Compresión

Entrada salida/binaria

Serialización con Avro

3 Tareas MapReduce

Algoritmos: encadenamiento, ordenación, fuentes múltiples

Localización de dependencias

Contadores

Ejemplo avanzado

4 Otros aspectos

5 Alternativas a Java

MapReduce en Hadoop, CSD

Page 63: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Alternativas a Java

Hadoop Streaming

API que permite crear códigos map-reduce en otros lenguajes

Utiliza streams Unix como interfaz entre Hadoop y el código

Permite usar cualquier lenguaje que pueda leer de la entrada

estándar y escribir en la salida estándar (Python, Ruby, etc.)

Más información .../HadoopStreaming.html

Hadoop Pipes

Interfaz C++ a Hadoop MapReduce

Usa sockets como canal de comunicación entre el tasktracker y el

proceso C++ que ejecuta el map o el reduce

MapReduce en Hadoop, CSD 55/58

Page 64: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Alternativas a Java

Hadoop Streaming

API que permite crear códigos map-reduce en otros lenguajes

Utiliza streams Unix como interfaz entre Hadoop y el código

Permite usar cualquier lenguaje que pueda leer de la entrada

estándar y escribir en la salida estándar (Python, Ruby, etc.)

Más información .../HadoopStreaming.html

Hadoop Pipes

Interfaz C++ a Hadoop MapReduce

Usa sockets como canal de comunicación entre el tasktracker y el

proceso C++ que ejecuta el map o el reduce

MapReduce en Hadoop, CSD 55/58

Page 65: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Ejemplo de streaming

WordCount Mapper en Python

#! / usr / bin /env python

#−*− coding : utf−8−*−import re , sys

pattern = re . compile (u ’ \ \ b[a−zA−Z\u00C0−\uFFFF]+\\b ’ )

for l ine in sys . stdin :

line2 = unicode( line , ’ utf−8’ ) . lower ( )

words = pattern . f inda l l ( l ine2 )

for w in words:

print " %s \ t %s" %(w.encode( ’ utf−8’ ) , 1)

MapReduce en Hadoop, CSD 56/58

Page 66: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Ejemplo de streaming

WordCount Reducer en Python

#! / usr / bin /env python

#−*− coding : utf−8−*−import sys

( last_key , total ) = (None, 0)

for l ine in sys . stdin :

(key , value ) = l ine . st r ip ( ) . sp l i t ( )

i f last_key and last_key != key:

print " %s \ t %s" %( last_key , total )

( last_key , total ) = (key , int (value ) )

else :

( last_key , total ) = (key , total+int (value ) )

i f last_key :

print " %s \ t %s" %( last_key , total )

MapReduce en Hadoop, CSD 57/58

Page 67: MapReduce en Hadoop

Java MapReduce en Hadoop Serialización y Entrada/Salida Tareas MapReduce Otros aspectos Alternativas a Java

Ejemplo de streaming

Ejecución del código Python

$ yarn jar \$HADOOP_PREFIX/share/hadoop/tools/lib/hadoop-streaming-*.jar \-input indir -output outdir \-mapper $PWD/WordCountMapper.py \-reducer $PWD/WordCountReducer.py \-file $PWD/WordCountMapper.py \-file $PWD/WordCountReducer.py

Nota: La opción -file sólo se necesita si se ejecuta en un cluster, para

copiar los scripts en los nodos del cluster

MapReduce en Hadoop, CSD 58/58