Documentos de Académico
Documentos de Profesional
Documentos de Cultura
5 de diciembre de 2014
Facultad de Matemtica Astronoma y Fsica
Universidad Nacional de Crdoba
ndice general
1. Introduccin
2. Antecedentes
2.1. Implicancias del Computo Distribuido
2.2. Modelos Computo distribuido . . . .
2.3. Apache Hadoop . . . . . . . . . . .
2.4. Apache Mahout . . . . . . . . . . .
.
.
.
.
3
3
4
5
6
3. Herramientas y Motivaciones
3.1. Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2. Motivacin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7
7
8
4. Resultados - Poopy
4.1. Colas y Procesos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.2. Esperas y Timeouts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3. Anlisis del ciclo de vida del comando run . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9
9
11
14
5. Conclusin
5.1. Cierre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
15
15
17
17
20
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
II
CAPTULO 1
Introduccin
Nullius in verba
Lema de la Real Sociedad de Londres
El advenimiento de grandes volmenes de datos (o Big Data1 ) esta generando una necesidad de productos que sirvan
para la manipulacin y resumen de los mismos. Big Data puede considerarse de manera mas o menos precisa (no es
mas que un numero comercial) como una cantidad de informacin tal que no puede procesarse ni almacenarse en un
nico ordenador.
Las dificultades ms habituales vinculadas a la gestin de estas cantidades de datos se centran en la captura, el almacenamiento,2 bsqueda, comparticin, anlisis y visualizacin. La tendencia a manipular ingentes cantidades de datos
se debe a la necesidad en muchos casos de incluir los diferentes conjuntos de datos relacionados.
La tendencia actual es el almacenamiento y el procesamiento a travs de nodos distribuidos en una red de la manera
mas transparente posible para el programador, hacindolo parecer que esta ejecutando todo localmente; despegndose
un poco del modelo propuesto por el ya tradicional modelo distribuido de MPI2 (del ingls Interfaz de Paso de Mensaje)
de hacer evidente la no localidad del computo.
Por el dado del anlisis de datos; en la presencia de una cantidad ingente de informacin como la que planteamos
hace necesario el disponer de mecanismos automticos para el procesamiento de estos volmenes. Es en este campo
donde una herramienta como el aprendizaje automtico3 (o ML) obtiene un valor de piedra angular. El aprendizaje
automtico es una rama de la de la Inteligencia Artificial4 que consiste en crear programas que buscan de manera
autnoma patrones en la informacin a partir de ejemplos.
En el siguiente trabajo analiza la implementacin del modelo mas popular de los ltimos aos para el computo distribuido: Map-Reduce5 as como un sistema distribuido de almacenamiento de archivos utilizando como sistema de
transporte de informacin el modelo de colas de mensajes AMQP6 y utilizando como lenguaje de programacin Python7 y su librera de aprendizaje automtico Scikit-Learn8 .
El trabajo resultante se hizo publico bajo una licencia laxa bajo del nombre de Poopy9 en la siguiente direccin web
http://poopy.jbcabral.org.
Las fuentes de este trabajo pueden encontrarse en: https://bitbucket.org/leliel12/bigdata_famaf
1 http://es.wikipedia.org/wiki/BigData
2 http://en.wikipedia.org/wiki/Message_Passing_Interface
3 http://en.wikipedia.org/wiki/Machine_learning
4 http://en.wikipedia.org/wiki/Artificial_intelligence
5 http://research.google.com/archive/mapreduce.html
6 http://www.amqp.org/
7 http://python.org
8 http://scikit-learn.org
9 http://poopy.jbcabral.org
Captulo 1. Introduccin
CAPTULO 2
Antecedentes
A distributed system is one in which the failure of a computer you didnt even know existed can render
your own computer unusable.
Leslie Lamport, Premio Turing Award 2014 por sus contribuciones al cmputo distribuido
En la actualidad la herramienta mas popular de computo distribuido es sin dudas Hadoop1 . Hadoop es una implementacin del algoritmo MapReduce realizada ntegramente en Java2 , que ha servido de inspiracin y gua a lo en todo
este trabajo.
Con el objeto de entender mejor el trabajo realizado, a largo de este capitulo analizaremos algunos implicancias del
computo distribuido (teorema CAP), dos modelos de computo distribuido (AMQP y MapReduce) y cerraremos con el
anlisis de una herramienta construida con el objeto de hacer aprendizaje automtico sobre grandes en un cluster de
computadoras.
brewer/
4 http://www.berkeley.edu/index.html
5 http://people.csail.mit.edu/lynch/
6 http://web.mit.edu/
7 http://cassandra.apache.org/
8 http://couchdb.apache.org/
2.2.1 AMQP
AMQP12 (del ingles Advanced Message Queuing Protocol - Protocolo avanzado de colas de mensajes) es un estandar
en el nivel de aplicacin13 para middlewares oriantados a mensajes. Sus caractersticas principales son:
Orientacin a mensajes
Colas
Enrutamientos (punto a punto y publicador-suscripcin)
Exactitud y seguridad
AMQP estipula a nivel binario el comportamiento tanto del servidor que provee los mensajes como del cliente de la
mensajera hasta el punto de que las implementaciones en diferentes lenguajes son totalmente inter operables; de la
misma forma que lo lograron SMPT14 , HTTP15 y SFTP16 .
La infraestructura de AMQP es la siguiente:
El corredor de mensajes (o Broker): un servidor al que los clientes AMQP se conectan usando el protocolo
AMQP.
Usuario (o cliente): un usuario es una entidad que, mediante la presentacin de credenciales tales como una
contrasea, puede ser autorizado (o puede no ser autorizado) a conectarse a un corredor.
Conexin: una conexin fsica usando por ejemplo TCP/IP o SCTP. Una conexin est ligada a un usuario.
Canal: una conexin lgica que est unida a una conexin. As pues, la comunicacin a travs de un canal
posee un estado. Aquellos clientes que realicen operaciones concurrentes mediante una misma conexin deben
mantener un canal distinto para cada una de ellas.
Implementaciones populares de AMQP son rabbitMQ17 , y Apache ActiveMQ18
Si usamos extenciones para distribuirs brokers AMQP, segun el Teorema CAP, puede ser AP (si usamos Federation19
/ Shovel20 ) y CA Si usamos AMQP Clustering21
9 http://hbase.apache.org/
10 http://en.wikipedia.org/wiki/Relational_database_management_system
11 http://www.amqp.org/
12 http://www.amqp.org/
13 http://en.wikipedia.org/wiki/Application_layer
14 https://tools.ietf.org/html/rfc821
15 http://tools.ietf.org/html/rfc2774
16 http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13
17 http://www.rabbitmq.com
18 http://activemq.apache.org/
19 https://www.rabbitmq.com/federation.html
20 https://www.rabbitmq.com/shovel.html
21 https://www.rabbitmq.com/distributed.html
Captulo 2. Antecedentes
2.2.2 MapReduce
MapReduce es un modelo de cmputo que simplifica el uso de clusters22 ; el cual computa una funcin que recibe
como parmetros un conjunto de elementos llave-valor, y lo convierte en un nuevo conjunto el cual cada elemento es
una llave y una lista de valores.
({( , )}) {( , ( )}
Para lograr esto divide la operacin en dos etapas:
1. Etapa de Map: Transforma el conjunto de entrada en un lista intermedia de elementos llave de salida y un
valores intermedios para esa llave.
( , ) ( , )
2. Etapa reduce: Agrupa cada elemento de la lista intermedia segn la llave final a la que pertenece y genera una
nueva lista de salida para cada par llave lista intermedia de entrada
( , ( )) ( )
MapReduce se emplea en la resolucin prctica de algunos algoritmos susceptibles de ser paralelizados. Cabe aclarar
que MapReduce si bien es poderoso no sirve para cualquier problema, as como no es la forma mas eficiente para
todos los problemas que si son solucionables por esta tcnica.
Generalmente MapReduce es la forma de encarar problemas con un set de datos de gran tamao (mas de lo que
una computadora puede almacenar y procesar). Esta capacidad hace necesaria que para ejecutarse a los datos suelen
hacerse disponible en sistemas de archivos distribuidos; los cuales guardan redundantemente pedazos de los archivos
en diferentes nodos y de ser solicitados son enviados a otros nodos para ser procesados.
La primera implementacin de esta tecnologa fue una realizada por Google23 , pero logro su popularidad gracias
Hadoop24 y su sistema de archivos HDFS25 (Hadoop Distributed File System).
29 http://en.wikipedia.org/wiki/Java_virtual_machine#Execution_environment
30 http://en.wikipedia.org/wiki/Secure_Shell
31 https://hive.apache.org/
32 http://en.wikipedia.org/wiki/Data_warehouse
33 http://mahout.apache.org/
34 http://en.wikipedia.org/wiki/Machine_learning
35 http://hbase.apache.org/
36 http://nosql-database.org/
37 http://mahout.apache.org/
38 http://en.wikipedia.org/wiki/Collaborative_filtering
39 http://en.wikipedia.org/wiki/Clustering
40 http://en.wikipedia.org/wiki/Statistical_classification
Captulo 2. Antecedentes
CAPTULO 3
Herramientas y Motivaciones
La razn de la sinrazn que a mi razn se hace, de tal manera mi razn enflaquece, que con razn me
quejo de la vuestra fermosura.
Feliciano de Silva, recogido en Don Quijote de la Mancha de Miguel de Cervantes
Hadoop1 esta programado y desarrollado sobre Java2 . Java actualmente, es la tecnologa que esta acaparando la mayora de los sistemas modernos para el almacenamiento y procesamiento de grandes volmenes de informacin (Spark3
tambin esta desarrollado sobre la misma plataforma). Su eleccin radica principalmente en su plataforma subyacente:
la JVM4 .
La JVM (del ingls Java Virtual Machine o Maquina Virtual de Java) posee un sistema de concurrencia que hace til
para la escritura de sistemas que requieran alta disponibilidad y escalabilidad.
Por otro lado Python5 es un lenguaje de mas alto nivel que que Java, esta soportado una plataforma mucho menos
robusta que la JVM; pero aun as se esta destacando de manera notable en el mbito cientfico. Frente a la robustez
de la JVM, Python ofrece un lenguaje con una sintaxis mas clara y limpia, adems de un set de libreras propias y de
terceros con un stack cientfico muy robusto y extensible. Otra caracterstica es el gran numero de paquetes que sirve
par interactuar con otras plataformas como Python Java Bridge6 (con java), rpy27 (con R8 ), f2py9 (con Fortran10 ) o
Python-Weka11 (con la plataforma de aprendizaje automtico de java Weka12 )
3.1 Python
3.1.1 El stack cientfico de Python
Python ofrece un stack cientfico apoyado en la librera Numpy13 , la cual define una estructura de datos altamente
eficiente que es el array multidimensional muy til para el clculo cientfico.
1 http://hadoop.apache.org/
2 https://www.java.com
3 https://spark.apache.org/
4 http://en.wikipedia.org/wiki/Java_virtual_machine
5 http://python.org
6 http://pythonhosted.org//javabridge/
7 http://rpy.sourceforge.net/
8 http://www.r-project.org/
9 http://docs.scipy.org/doc/numpy-dev/f2py/
10 http://en.wikipedia.org/wiki/Fortran
11 http://pythonhosted.org//python-weka-wrapper/
12 http://www.cs.waikato.ac.nz/
ml/weka/
13 http://www.numpy.org/
Por encima de Numpy se ubican un buen numero de paquetes que implementan diferentes soluciones como: Scipy14
(implementacin de herramientas y algoritmos matemticos), Sympy15 para matemtica simblica o Scikit-Learn16
que implementa algoritmos de aprendizaje automtico entre otros.
La popularidad de Scikit-Learn esta en auge y en conjunto con herramientas como el Jupyter17 se esta volviendo un
estndar de facto para la realizacin de paper interactivos.
3.2 Motivacin
El proyecto en un principio naci con la necesidad de comprender las implicatorias de el diseo de un sistema MapReduce sobre AMQP tratando de lograr las mismas garantas que ofrecidas por Hadoop. Este planteo fue realizado en
el segundo prctico de la materia Aprendizaje automtico sobre grandes volmenes de datos y se presento como
resolucin un pseudo-cdigo que se anexa a este trabajo como Apndice A.
Actualmente se planteo evolucin del proyecto evolucin y se volvi un protipo funcional de lo planteado, aprovechando la expresividad de Python; tratando de facilitar el depliegue de los nodos para hacerlo de manera trivial para
lograr utilizar de manera distribuida Scikit-Learn.
El proyecto fue finalmente llamado Poopy26
14 http://scipy.org/
15 http://www.sympy.org/
16 http://scikit-learn.org
17 http://jupyter.org/
18 http://pydoop.sourceforge.net
19 http://hadoop.apache.org/docs/r1.2.1/libhdfs.html
20 http://www.hadoopy.com
21 https://pythonhosted.org/mrjob/
22 http://hadoop.apache.org/docs/r1.2.1/streaming.html
23 http://www.amqp.org/
24 https://pika.readthedocs.org
25 http://www.celeryproject.org/
26 http://poopy.jbcabral.org
CAPTULO 4
Resultados - Poopy
Significa que dentro de la carpeta que se configure que el nodo guarde sus archivos locales de poopyFS creara una
carpeta path/to y dentro de ella el archivo file.arff.
10
La llave UUID es un identificador nico que identifica la computadora en caso de utilizarse como nodo de
procesamiento.
SCRIPTS indica en que lugar van a copiarse los scripts que contienen las instrucciones Map-Reduce a correr.
En tercer lugar tenemos la llave POOPY_FS determina el lugar donde va a existir la copia local de los archivos
distribuidos.
Las ultimas dos llaves son las que tienen relevancia en este apartado.
Muchas veces por algn motivo de implementacin nos vimos obligados a dormir las colas por algn tiempo determinado. Por ejemplo antes de ejecutar las tareas MapReduce, Poopy, tiene que esperar que los nodos de cmputo
informen de su existencia. Estos nodos tienen una cadencia de aviso de la cantidad de segundos definidos en la llave
SLEEP que vemos mas arriba; as tambin el tiempo de espera del nodo central esta dado por una ves y media el valor
de SLEEP. El valor por defecto de 5 es experimentales y se prob satisfactoriamente en todos los casos, pero aun as
pueden ser manipulados por el usuario en el archivo de configuracin.
En el caso del valor de la llave TTL (del ingls Time to live, o Tiempo de vida) se utiliza para saber si el resultado de
un computo es aceptado dado el ultimo momento de anuncio de un nodo de procesamiento. Esta funcionalidad no esta
implementada pero se recolecta toda la informacin necesaria para desarrollarla de manera sencilla.
class Script(script.ScriptBase):
def map(self, k, v, ctx):
raise NotImplementedError()
def reduce(self, k, v, ctx):
9 http://www.json.org/
11
for vi in v:
ctx.emit(k, vi)
def setup(self, job):
job.name = "NO-NAME"
Los mtodos que ah se definen se utilizan en diferentes momentos del ciclo de ejecucin de una tarea Poopy.
El mtodo setup se ejecuta en el nodo central y define: el nombre de la tarea y que archivos va utilizar.
Los mtodos map y reduce son los que se ejecutan distribuidamente en el cluster de computadoras.
Por ejemplo implementacin primitiva de Random Forest10 con Poopy tendria la siguiente forma
#!/usr/bin/env python
# -*- coding: utf-8 -*-
class Script(script.ScriptBase):
def map(self, k, v, ctx):
import random
import numpy as np
import scipy
from sklearn import tree
attrs = ['sepallength', 'sepalwidth', 'petallength', 'petalwidth']
random.shuffle(attrs)
attrs.pop()
data, meta = v
target = np.array(data['class'])
train = np.array(data[attrs][:75])
X = np.asarray(train.tolist(), dtype=np.float32)
dt = tree.DecisionTreeClassifier(criterion='entropy',
max_features="auto",
min_samples_leaf=10)
ctx.emit(None, dt)
def reduce(self, k, v, ctx):
for vi in v:
ctx.emit("iris", vi)
def setup(self, job):
job.name = "Random Forest"
job.input_path.append([
"poopyFS://iris.arff", self.readers.ARFFReader, {}
])
Probablemente la linea mas interesante sea la ultima que ejemplifica como se indica que archivo utilizara esta tarea,
que parser utilizara para leerlo y que parmetros extra recibir el parser.
10 http://en.wikipedia.org/wiki/Random_forest
12
Actualmente estan soportados 4 formatos de archivos: ARFF11 , CSV12 , CSV Numrico y Texto plano13 .
13
14
CAPTULO 5
Conclusin
5.1 Cierre
El proyecto resultante supero ampliamente las espectativas iniciales de simplemente comprender cual es la mejor
forma de implementar algo similar a Hadoop cobre AMQP.
Finalmente se demostrado que AMQP posee la expresividad necesaria para servir de transporte de datos y sistema de
comunicacin para el diseo de sistemas flexibles para el computo distribuido de grandes volmenes de datos.
15
16
Captulo 5. Conclusin
CAPTULO 6
El pseudo-cdigo surge de una adaptacin del plan de ejecucin de la primer versin de Pooppy, que fue realizado
con el objetivo de profundizar el conocimiento sugerido en un practico de la materia de postgrado de Aprendizaje
automtico sobre grandes volmenes de datos dictado por el Dr. Pablo Duboue en el FaMAF1 .
Poopy como se menciono previamente ejecuta funciones map y reduce de manera distribuida sobre una serie de
nodos conectados por AMQP, con algunas garantas de Hadoop2 , como por ejemplo, garantiza la localidad de datos
replicando en cada nodo los archivos a procesar
En el siguiente cdigo puede observarse que en esta caso, s se menciona en el plan de ejecucin como debe ser la
publicacin de mensajes para lograr una localidad de datos similar a la de Hadoop (si algo no esta presente localmente
en el nodo se solicita que otro miembro de la red envie el archivo), as como tambin se describe como debera
implementarse conceptualmente la forma de descartar nodos que han sido particionados de la red (esto ltimo tampoco
lo implementa Poopy)
El pseudo cdigo esta escrito en castellano en una adaptacin libre de Javascript que sirve para dejar mas claro el
concepto de callbacks necesario en AMQP.
6.1 Cdigo perteneciente al nodo central encargado de lanzar las tareas distribuidas
1
// Nodo Central
2
3
4
5
6
7
8
9
10
11
tareas_map_ejecutandose = []
tareas_reduce_ejecutandose = []
12
13
14
tareas_map_completas = []
tareas_reduce_completas = []
15
16
17
18
1 http://www.famaf.unc.edu.ar/
2 http://hadoop.apache.org/
17
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
descubierto_exchange.conectar(function(nodo) {
// los nodos almacenan su tiempo de ultima conexion
nodos.agregar(nodo)
})
52
53
54
55
56
57
58
59
60
61
62
63
64
archivos_en_nodos = {}
para cada archivo en archivos:
// agregamos el archivo en cache para saber a que nodo fue a parar
// cada uno
archivos_en_nodos[archivo.nombre] = []
65
66
67
68
69
70
71
72
73
74
75
76
18
77
78
79
80
81
82
83
84
85
86
87
88
89
// agrupamos nodos de a 3
para cada grupo en los agrupar_al_azar(nodos, 3):
// ejecuta el script sobre un grupo de archivos dado tratando de tener
// localidad la misma tarea se envia a varios nodos por si algun nodo se
// cae la funcion "seleccionar_archivo" toma un grupo de archivos locales
// al los nodos del grupo, hay que tener en cuenta que no todos los nodos
// tienen los mismos archivos asi que puede romperse "un poco" la localidad
// de datos, pero esto es esperable
archivos_a_procesar = seleccionar_archivo(archivos_en_nodos, grupo)
id = obtener_id_unico() // un id de tarea
map_exchange.publicar(para_nodo=grupo, script.name, archivos_a_procesar, id)
tareas_map.agregar(id)
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
})
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
6.1. Cdigo perteneciente al nodo central encargado de lanzar las tareas distribuidas
19
135
136
137
138
139
})
140
141
142
// Nodo Cliente
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
20
46
47
48
file_exchange.conectar(para_nodo=node, function(archivo){
copiar_a_carpeta_local(archivo)
})
49
50
51
52
53
54
55
56
57
58
// verifica si
need_file.conectar(function(nombre_archivo, node_id){
si node_id == node:
return // no me escucho a mi mismo
si nombre_archivo no esta en carpeta_local:
fp = obtener_archivo_carpeta_local(script_name)
file_exchange.publicar(fp, node_id)
})
59
60
61
62
63
64
map_exchange.conectar(para_nodo=node,
function(script_name, archivos_a_procesar, id){
script = obtener_script_carpeta_local(script_name)
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
reduce_out_exchange.conectar(para_nodo=node
function(script_name, valores, id){
script = obtener_script_carpeta_local(script_name)
92
93
94
95
96
97
98
99
100
101
102
103
21
104
105
106
107
108
22