4. Fisonomía de un proyecto Big Data
Adquisición
Procesamiento
Servicio
4 / 34
5. Tipos de sistemas Big Data
● Offline
– La latencia no es un problema
● Online
– La inmediatez de los datos es importante
● Mixto
– Lo más común
Offline Online
MapReduce Bases de datos NoSQL
Hadoop Motores de búsqueda
Distributed RDBMS
5 / 34
6. “Swiss army knife of the
21st century”
Media Guardian Innovation
Awards
http://www.guardian.co.uk/technology/2011/mar/25/media-guardian-innovation-awards-apache-hadoop 6 / 34
7. Historia
● 2004-2006
– Google publica los papers de GFS y MapReduce
– Doug Cutting implementa una versión Open Source en
Nutch
● 2006-2008
– Hadoop se separa de Nutch
– Se alcanza la escala web en 2008
● 2008-Hasta ahora
– Hadoop se populariza y se comienza a explotar
comercialmente.
Fuente: Hadoop: a brief history. Doug Cutting
7 / 34
8. Hadoop
“The Apache Hadoop
software library is a
framework that allows for
the distributed
processing of large data
sets across clusters of
computers using a
simple programming
model”
De la página de Hadoop
8 / 34
9. Sistema de Ficheros Distribuido
● Sistema de ficheros distribuido (HDFS)
– Bloques grandes: 64 Mb
● Almacenados en el sistema de ficheros del SO
– Tolerante a Fallos (replicación)
– Formatos habituales:
● Ficheros en formato texto (CSV)
● SequenceFiles
– Ristras de pares [clave, valor]
9 / 34
10. MapReduce
● Dos funciones (Map y Reduce)
– Map(k, v) : [z,w]*
– Reduce(k, v*) : [z, w]*
● Ejemplo: contar palabras
– Map([documento, null]) -> [palabra, 1]*
– Reduce(palabra, 1*) -> [palabra, total]
● MapReduce y SQL
– SELECT palabra, count(*) GROUP BY palabra
● Ejecución distribuida en un cluster con escalabilidad
horizontal
10 / 34
11. El típico Word Count
Esto es una linea
Esto también
Map Reduce
reduce(es, {1}) =
map(“Esto es una linea”) =
es, 1
esto, 1
reduce(esto, {1, 1}) =
es, 1
esto, 2
una, 1
reduce(linea, {1}) =
linea, 1
linea, 1
map(“Esto también”) =
reduce(también, {1}) =
esto, 1
también, 1
también, 1
reduce(una, {1}) =
una, 1
es, 1
esto, 2
Resultado: linea, 1
también, 1
una, 1
11 / 34
12. Word Count en Hadoop
public class WordCountHadoop extends Configured implements Tool {
public static class TokenizerMapper extends Mapper<Object, Text, Text, IntWritable> {
private final static IntWritable one = new IntWritable(1);
private Text word = new Text();
public void map(Object key, Text value, Context context) throws IOException, InterruptedException {
StringTokenizer itr = new StringTokenizer(value.toString());
while(itr.hasMoreTokens()) {
word.set(itr.nextToken());
context.write(word, one);
}
}
}
public static class IntSumReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
private IntWritable result = new IntWritable();
public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException,
InterruptedException {
int sum = 0;
for(IntWritable val : values) {
sum += val.get();
}
¡Mejor vamos por partes!
result.set(sum);
context.write(key, result);
}
}
@Override
public int run(String[] args) throws Exception {
if(args.length != 2) {
System.err.println("Usage: wordcount-hadoop <in> <out>");
System.exit(2);
}
Path output = new Path(args[1]);
HadoopUtils.deleteIfExists(FileSystem.get(output.toUri(), conf), output);
Job job = new Job(getConf(), "word count hadoop");
job.setJarByClass(WordCountHadoop.class);
job.setMapperClass(TokenizerMapper.class);
job.setCombinerClass(IntSumReducer.class);
job.setReducerClass(IntSumReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
FileInputFormat.addInputPath(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));
job.waitForCompletion(true);
return 0;
}
public static void main(String[] args) throws Exception {
ToolRunner.run(new SortJobHadoop(), args);
}
}
12 / 34
13. Word Count en Hadoop - Mapper
public static class TokenizerMapper extends Mapper<Object, Text,
Text, IntWritable> {
private final static IntWritable one = new IntWritable(1);
private Text word = new Text();
public void map(Object key, Text value, Context context) throws
IOException, InterruptedException {
StringTokenizer itr = new StringTokenizer(value.toString());
while(itr.hasMoreTokens()) {
word.set(itr.nextToken());
context.write(word, one);
}
}
}
13 / 34
14. Word Count en Hadoop - Reducer
public static class IntSumReducer extends Reducer<Text, IntWritable,
Text, IntWritable> {
private IntWritable result = new IntWritable();
public void reduce(Text key, Iterable<IntWritable> values,
Context context) throws IOException,
InterruptedException {
int sum = 0;
for(IntWritable val : values) {
sum += val.get();
}
result.set(sum);
context.write(key, result);
}
}
14 / 34
15. Word Count en Hadoop – Configuración y
ejecución
if(args.length != 2) {
System.err.println("Usage: wordcount-hadoop <in> <out>");
System.exit(2);
}
Path output = new Path(args[1]);
HadoopUtils.deleteIfExists(FileSystem.get(output.toUri(), conf),
output);
Job job = new Job(getConf(), "word count hadoop");
job.setJarByClass(WordCountHadoop.class);
job.setMapperClass(TokenizerMapper.class);
job.setCombinerClass(IntSumReducer.class);
job.setReducerClass(IntSumReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
FileInputFormat.addInputPath(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));
job.waitForCompletion(true);
15 / 34
16. Ejecución de un Job MapReduce
Bloques del fichero de entrada
Nodo 1
Nodo 2
Mappers
Datos
Intermedios
Nodo 1
Nodo 2
Reducers
Resultado
16 / 34
17. Serialización
● Writables
• Serialización nativa de Hadoop
• De muy bajo nivel
• Tipos básicos: IntWritable, Text, etc.
● Otras
• Thrift, Avro, Protostuff
• Compatibilidad hacia atrás.
17 / 34
19. Tuple MapReduce
● Un MapReduce más simple
– Tuplas en lugar de key/value
– A nivel de job se define
● Los campos por los que agrupar
● Los campos por los que ordenar
– Tuple MapReduce-join
19 / 34
20. Pangool
● Implementación de
TupleMap reduce
– Desarrollado por Datasalt
– OpenSource
– Eficiencia equiparable a
Hadoop
● Objetivo: reemplazar la API
de Hadoop
● Si quieres aprender
Hadoop, empieza por
Pangool
20 / 34
22. Pangool – URL resolution
● Ejemplo de Join
– Muy difícil en Hadoop. Fácil en Pangool.
● Problema:
– Existen muchos acortadores de URLs y redirecciones
– Para analizar datos, suele ser útil reemplazar las URLs por su URL
canónica
– Supongamos que tenemos ambos datasets
● Un mapa con entradas URL → URL canónica
● Un dataset con URLs (que queremos resolver) y otros campos.
– El siguiente job Pangool soluciona el problema de manera escalable.
22 / 34