Desarrollo de aplicaciones
con Hadoop
Tomas Delvechio
@tdelvechio
tomasdelvechio17@gmail.com
Indice
- Instalación de Hadoop
- Uso básico de HDFS
- Desarrollo en Hadoop
- Hadoop Streaming
El objetivo es poder realizar una instalación local y desarrollar algunas aplicaciones MapReduce, haciendo un uso simple del Sistema de Archivos Distribuido que proporciona Hadoop.
Objetivo
Instalación de Hadoop
- Single Node
- Multi Node
Instalar Hadoop implica instalar sus 3 componentes principales:
- Hadoop common
- HDFS
- MapReduce
En todos los nodos. La diferencia entre nodo master y nodo slave se establece en la configuración e inicialización de los servicios
Instalación Single Node
Sistema Operativo Linux
No hay procesamiento distribuido
Instalación para desarrollo
Linux: Ubuntu 14.04
Hadoop 2.7 / Hadoop 2.4 / Hadoop 2.5
OpenJDK 6 / 7
Instalación vía Docker
Instalación vía Docker
- Instalar Docker
- Descargar imagen
- Iniciar Contenedor
- Ejecutar Test
Instalación vía Docker
- Instalar Docker
https://docs.docker.com/engine/installation/
Comprobar si el cliente esta instalado:
$ docker --version Docker version 1.12.1
Instalación vía Docker
2. Descargar imagen
$ docker pull sequenceiq/hadoop-docker:2.7.1
Instalación vía Docker
3. Iniciar Contenedor
docker run -it sequenceiq/hadoop-docker:2.7.1 /etc/bootstrap.sh -bash
4. Ejecutar Test
(Dentro del contenedor)
cd $HADOOP_PREFIX
bin/hadoop jar \
> share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.1.jar \
> grep input output 'dfs[a-z.]+'
bin/hdfs dfs -cat output/*
Instalación vía Docker
mkdir ~/cursohadoop
docker run -v ~/cursohadoop:/cursohadoop \
-w /cursohadoop -it sequenceiq/hadoop-docker:2.7.1 \
/etc/bootstrap.sh -bash
Ejecución de contenedor para trabajar en el curso.
Agregar los ejecutables de hadoop al path del sistema
export PATH=$PATH:/usr/local/hadoop/bin
Web UI Hadoop
Desde el navegador web de nuestro equipo
ResourceManager: <ip_container>:8088
NameNode: <ip_container>:50070
ResourceManager Web UI
NameNode Web UI
Uso basico de HDFS
Listar archivos y directorios
Crear directorios en HDFS
Copiar archivos locales al HDFS
Descarga de archivos de ejemplo: https://goo.gl/ngB0aP
hdfs dfs -ls /
hdfs dfs -mkdir /user/hduser
hdfs dfs -mkdir /user/hduser/test
hdfs dfs -ls /user/hduser/
$ ls
pg135.txt pg1661.txt pg4300.txt
$ hdfs dfs -copyFromLocal pg135.txt pg1661.txt pg4300.txt /user/hduser/test
$ hdfs dfs -ls /user/hduser/test/
Found 3 items
-rw-r--r-- 1 hduser supergroup 3322651 2014-09-08 13:21 /user/hduser/test/pg135.txt
-rw-r--r-- 1 hduser supergroup 594933 2014-09-08 13:21 /user/hduser/test/pg1661.txt
-rw-r--r-- 1 hduser supergroup 1573150 2014-09-08 13:21 /user/hduser/test/pg4300.txt
Uso básico de HDFS (Sigue)
Ver contenido de un archivo en el FS
Descargar archivos desde HDFS
hdfs dfs -cat /user/hduser/test/pg1661.txt
hdfs dfs -copyToLocal /user/hduser/test/pg1661.txt pg1661_bis.txt
diff pg1661_bis.txt pg1661.txt
Programar en Hadoop: WordCount
Aplicación MapReduce que computa la frecuencia de cada termino de la entrada
MapReduce WordCount DataFlow
WordCount: Version Java (Mapper)
public static class Map extends Mapper<LongWritable, Text, Text, IntWritable> {
private final static IntWritable one = new IntWritable(1);
private Text word = new Text();
@Override
public void map(LongWritable key, Text value, Context context)
throws IOException, InterruptedException {
String line = value.toString();
StringTokenizer tokenizer = new StringTokenizer(line);
while (tokenizer.hasMoreTokens()) {
word.set(tokenizer.nextToken());
context.write(word, one);
}
}
}
WordCount: Version Java (Reducer)
public static class Reduce extends Reducer<Text, IntWritable, Text, IntWritable> {
@Override
public void reduce(Text key, Iterable<IntWritable> values, Context context)
throws IOException, InterruptedException {
int sum = 0;
for (IntWritable val : values) {
sum += val.get();
}
context.write(key, new IntWritable(sum));
}
}
WordCount: Version Java (Main class)
public class WordCount {
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
Job job = Job.getInstance(conf);
job.setJarByClass(WordCount.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
job.setMapperClass(Map.class);
job.setReducerClass(Reduce.class);
job.setInputFormatClass(TextInputFormat.class);
job.setOutputFormatClass(TextOutputFormat.class);
FileInputFormat.addInputPath(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));
job.waitForCompletion(true);
}
}
WordCount: Version Java (API import)
package wordCount;
import java.io.IOException;
import java.util.*;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.conf.*;
import org.apache.hadoop.io.*;
import org.apache.hadoop.mapreduce.*;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
Ejemplo completo
Pasos para correr el programa
- Descargar el código en un archivo de nombre WordCount.java
- Crear una carpeta de nombre wordCount: mkdir wordCount
- Compilar el código: javac -classpath `hadoop classpath` -d wordCount WordCount.java
- Armar paquete: jar -cvf wordcount.jar -C wordCount/ .
Ejecutar en Hadoop: hadoop jar wordcount.jar wordCount.WordCount /user/hduser/test/* /user/hduser/out-wc
Hadoop Streaming
Map / Reduce con otros lenguajes
Ejemplo: Contar la cantidad de palabras de un archivo
hadoop jar hadoop-streaming-2.7.1.jar \ -input /user/hduser/test/* \ -output /user/hduser/out-wc-sh \ -mapper /bin/cat \ -reducer /usr/bin/wc
La librería hadoop-streaming se puede localizar en el path
/usr/local/hadoop/share/hadoop/tools/lib/hadoop-streaming-2.7.1.jar
Hadoop Streaming
El flujo de datos es similar al visto para Hadoop
Sin embargo, Map y Reduce ejecutan los scripts que se pasan por parametro. El I/O se hace por Entrada y Salida Estandar.
Ejercicio con Streaming
Elija el lenguaje que crea conveniente (Python, Ruby, Perl, Bash), y porgráme un Mapper y un Reducer para que realicen un WordCount.
Recordar que el I/O del script Map y Reduce es via Entrada/Salida Estandar.
Por ejemplo, en python, un script que haga print "Hola mundo" imprime el string por la salida estandar.
Trabajo Practico
Tomando el ejemplo de WordCount, piense alguna modificación para crear un programa que realice otra tarea.
Implementarlo en Hadoop
Ejemplos:
Contador de Bigramas
Indice Invertido Booleano
Ayuda: Muchas veces programas de estructura similar ofrecen respuestas diferente en función de las decisiones de que es clave o valor en map y reduce.