Está en la página 1de 26

Implementacin de un sistema de

cmputo distribudo Map-Reduce sobre


AMQP
Aprendizaje automtico sobre grandes volmenes de
datos

Docente: Dr. Pablo Duboue


Autor: Juan B Cabral

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

6. Apndice A: Pseudo Cdigo de Poopy


6.1. Cdigo perteneciente al nodo central encargado de lanzar las tareas distribuidas . . . . . . . . . . . .
6.2. Cdigo de nodos clientes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

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

Implementacin de un sistema de cmputo distribudo Map-Reduce sobre AMQP

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.

2.1 Implicancias del Computo Distribuido


Un sistema distribuido se define como una coleccin de computadoras separadas fsicamente y conectadas entre s por
una red de comunicaciones; cada mquina posee sus componentes de hardware y software.

2.1.1 Teorema CAP


El teorema CAP surge de una conjetura muy sencilla:
No se puede garantizar consistencia, disponibilidad (Availability en ingls) y ser tolerante a las particiones
en un sistema de cmputo distribuido.
Esta conjetura fue realizada por Eric Bewer3 en la Universidad de California Berkley4 y demostrada debidamente por
Gilber y Lynch5 en el MIT6 .
Segn satisfagan estos criterios podemos clasificar varios sistemas como por ejemplo
Disponibilidad y tolerancia a las particiones: Cassandra7 y CouchDB8 .
1 http://hadoop.apache.org/
2 https://www.java.com
3 http://www.cs.berkeley.edu/

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/

Implementacin de un sistema de cmputo distribudo Map-Reduce sobre AMQP

Consistencia y tolerancia a las particiones: HBase9 y Paxos.


Consistencia y Disponibilidad: RDBMS10 .

2.2 Modelos Computo distribuido


Existen varios modelos de computo distribuido de los cuales analizaremos 2 que tienen relevancia para el proyecto:
AMQP11 y MapReduce

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

Implementacin de un sistema de cmputo distribudo Map-Reduce sobre AMQP

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).

2.3 Apache Hadoop


Hadoop es un proyecto perteneciente a la Fundacin Apache26 (inspirado en documentos de Google27 sobre MapReduce y Google File System) y ha sido el estndar de facto los ltimos aos para el tratamiento de grandes volmenes
de datos.
Desde el punto de vista de Teorema CAP hadoop es AP
Adems de la implementacin de MapReduce, Hadoop brinda un set de funcionalidades para el acceso a sistemas de
archivo soportados siendo el mas importante HDFS28 .
Un despliegue tpico Hadoop incluye un nodo maestro y mltiples nodos esclavo. El nodo maestro consiste en:
TaskTracker: donde se comunican los resultados MapReduce de los nodos clientes,
JobTracker que se encarga de mantener las tareas tan cerca de los nodos que posean los datos que va a utilizar22 http://en.wikipedia.org/wiki/Computer_cluster
23 http://google.com/
24 http://hadoop.apache.org/
25 http://hadoop.apache.org/docs/r1.2.1/hdfs_design.html
26 http://www.apache.org/
27 http://google.com/
28 http://hadoop.apache.org/docs/r1.2.1/hdfs_design.html

2.3. Apache Hadoop

Implementacin de un sistema de cmputo distribudo Map-Reduce sobre AMQP

Namenode: identifica cada nodo cliente y


Datanode: mantiene la informacin de donde se encuentran los datos.
Un esclavo o compute node (nodo de cmputo) consisten en un nodo de datos y un rastreador de tareas.
Hadoop requiere tener instalados entre nodos en el clster JRE29 1.6 o superior, y SSH30 .
Esta esta infraestructura ha sido el corazn de el desarrollo de diferentes proyectos para aprovechar as caractersticas
distribuidas que ofrece Hadoop como Hive31 (un sistema de Data Warehouse32 distribuido), Mahout33 (algoritmos de
machine learning34 ) o HBase35 (un sistema No-SQL36 )
En la actualidad la popularidad de Hadoop esta siendo siendo amenazada por otro proyecto de apache llamado Spark,
el cual posibilita el trabajo en tiempo real adems de permitir el almacenamiento intermedio no solo en disco sino
tambin en memoria.

2.4 Apache Mahout


Mahout37 es un proyecto de codigo abierto desarrollado por la fundacin Apache sobre Hadoop que implementa escalablemente algoritmos de aprendizaje automtico; enfocndose principalmente en filtrado colaborativo38 , clustering39
y clasificacin40 .
El proyecto es utilizado principalmente dada sus caracterstica para el anlisis automtico de grandes volmenes de
datos el cual seria imposible de realizar en una unica maquina.

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/

Implementacin de un sistema de cmputo distribudo Map-Reduce sobre AMQP

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.1.2 Python, Hadoop y AMQP


Se dispone actualmente e varias implementaciones para interactuar entre Python y Haddop, de las cuales la mas
populares son Pydoop18 la cual utiliza el API C19 de Hadoop, mientras que Hadoopy20 y MrJob21 utilizan el API
Streaming22 . En ambos casos esto no disminuye el esfuerzo de despliegue de los nodos Hadoop.
Como interfaces a otros sistemas de computo distribuido Python encuentra varias libreras para el trabajo contra
AMQP23 de las cuales caben destacar Pika24 que ofrece acceso a las primitivas de los mensajes, y Celery25 (de un
poco mas alto nivel)

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 3. Herramientas y Motivaciones

CAPTULO 4

Resultados - Poopy

Veni, vidi, vici


Cayo Julio Csar
En este apartado comentaremos la decisiones de diseo y las tcnicas que hemos tomado para el desarrollo de Poopy1 .
Esto involucra la eleccin de libreras el modelo de concurrencia, la creacin de las colas y el sistema de archivos
distribuidos.

4.1 Colas y Procesos


Si bien Python2 posee varias alternativas para el acceso a AMQP3 , en este trabajo se ha optado por uno de los mas
simples: Pika4 . Pika tiene la particularidad de ser una implementacin robusta, probada y bien documentada, ya que
el broker5 que hemos usado para el desarrollo, rabbitMQ6 , da los ejemplos en Python con Pika.
El primer detalle de Pika que hay que tener en cuenta es que ofrece diferentes mecanismos de conexiones: las bloqueantes y las asncronas. Si bien las segundas son mas eficientes en el sentido de que solo reaccionan al momento
de que reciben un mensaje, tambin son mas difciles de programas y de depurar. Es por esto que se decidi utilizar la
conexin bloqueante en un esquema de multiprocesos comunicados.
Poopy actualmente tiene 3 funcionalidades bsicas divididas cada en una serie de colas diferentes implementadas con
el patrn publicador subscriptor7
Las funcionalidades son:
Anunciar la existencia de un nodo cliente al central: Esto cociste en el anuncio al nodo principal conectado
al broker cada cierta cantidad de segundos de la existencia y el estado de la configuracin de un nodo de
procesamiento. Por el lado del nodo central cociste en un proceso que registra cuando fue el ultimo momento
que un nodo de comunico y verificar su disponibilidad. Esta funcionalidad en el cdigo fuente de Poopy se
encuentra en dos clases definidas en el modulo pong_node.py; y hace las veces del namenode de Hadoop.
Distribuir los archivos en en el sistema de archivos distribuido: Actualmente toda esta funcionalidad esta
definida en el modulo poopyfs_node.py. El nodo central simplemente publica en la cola determinada para
tal fin la informacin de un archivo y la metadata necesaria para reconstruirlo en todos los nodos de computo.
Esta funcionalidad en Hadoop esta implementada en el HDFS8 .
1 http://poopy.jbcabral.org
2 http://python.org
3 http://www.amqp.org/
4 https://pika.readthedocs.org
5 https://www.rabbitmq.com/tutorials/amqp-concepts.html
6 http://www.rabbitmq.com
7 http://en.wikipedia.org/wiki/Publish %E2 %80 %93subscribe_pattern
8 http://hadoop.apache.org/docs/r1.2.1/hdfs_design.html

Implementacin de un sistema de cmputo distribudo Map-Reduce sobre AMQP

Ejecucin de una tarea MapReduce: Esta funcionalidad esta implementada en 3 archivos:


script_node.py: Posee un colas definidas para copiar los scripts a todos los nodos disponibles en la
red. El nodo central acta de publisher y los nodos de procesamiento reciben y almacenan los scripts.
map_node.py: Consiste en 2 colas. La primera es un publicador que emite la seal de ejecucin map a
los nodos de procesamiento informandoles con que tareas y que datos debern funcionar. La segunda cola
informa de los resultados de cada nodo procesamiento al nodo central.
reduce_node.py: Como la ejecucin de map, la ejecucin de reduce tambin cociste en 2 colas: una
para emitir la seal de ejecucin a los reducers y la segunda para informar al nodo central de los resultados
obtenidos.
Todo este conjunto de funcionalidades hace las veces del Hadoop JobTracker y el TaskTracker.
Dada esta infraestructura un nodo de computo de de Poopy consiste en los siguientes procesos:
Publicador de anuncio de existencia.
Subscriptor de sistema de archivos distribuidos.
Subscriptor de distribucin de tareas (scripts) a ejecutar.
Subscriptor de tareas map a ejecutar.
Publicador de resultados de tareas map.
Subscriptor de tareas reduce a ejecutar.
Publicador de resultados de tareas reduce.
Mientras que el Nodo central consiste en:
Subscriptor de anuncio de existencia de nodos de computo.
Publicador del sistema de archivos distribuidos.
Publicador de tareas (scripts) a ejecutar.
Publicador de tareas map a ejecutar.
Subscriptor de resultados de tareas map.
Publicador de tareas reduce a ejecutar.
Subscriptor de resultados de tareas reduce.

4.1.1 Sistema de Archivo Distribuido poopyFS


Si bien por una motivo conceptual fueron primeros explicados los procesos que se ejecutan en cada nodo de Poopy; la
realidad desde el punto de vista tcnico es que la funcionalidad mas fundamental de un sistema de estas caractersticas
es la distribucin de los datos a los nodos de procesamiento.
Se opto por una cuestion de simplicidad en ves de trabajar con chuks replicados como hace HFS, se opto por simplemente copiar todos los archivos a todos los nodos.
El comA nivel de sistema de archivos local, una direccion de poopyFS del tipo:
poopyFS://path/to/file.arff

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

Captulo 4. Resultados - Poopy

Implementacin de un sistema de cmputo distribudo Map-Reduce sobre AMQP

4.2 Esperas y Timeouts


La configuracin de Poopy se alamcena en formato JSON9 dentro del directorio ~/.poopy/conf.json y tiene la
siguiente forma:
{
"UUID": "65d778d2-94b6-4965-8dd7-0418bc73e416",
"SCRIPTS": "/home/juan/.poopy/scripts",
"POOPY_FS": "/home/juan/.poopy/poopy_fs",
"SLEEP": 5,
"TTL": 30
}

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.

4.2.1 Diseo de un programa MapReduce


Siguiendo las instrucciones de instalacin de Poopy usted dispondr de un comando de consola llamado poopy.
La forma mas rpida de crear una tarea MapReduce para correr con Poopy es ejecutar el comando:
$ poopy createscript example.py
[INFO|2014-14-35 25:68:61,595] Poopy > Script created at 'example.py'

El contenido de ese archivo sera el siguiente


#!/usr/bin/env python
# -*- coding: utf-8 -*from ampoopq import script

class Script(script.ScriptBase):
def map(self, k, v, ctx):
raise NotImplementedError()
def reduce(self, k, v, ctx):
9 http://www.json.org/

4.2. Esperas y Timeouts

11

Implementacin de un sistema de cmputo distribudo Map-Reduce sobre AMQP

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 -*-

from poopy import script

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

Captulo 4. Resultados - Poopy

Implementacin de un sistema de cmputo distribudo Map-Reduce sobre AMQP

Actualmente estan soportados 4 formatos de archivos: ARFF11 , CSV12 , CSV Numrico y Texto plano13 .

4.2.2 Ciclo de ejecucin de una tarea Poopy


En primer lugar hay que instalar un broker como rabbitMQ14 o ActiveMQ15 en un servidor y obtener su IP que sera
referenciada en los comandos como amqp://<BROKER-IP>
1. Instalar Poopy en cada maquina que ejecutar un nodo de computo y poner a correr dicho nodo con el comando
$ poopy deploy amqp://<BROKER_IP>
[INFO|...] Poopy > Starting poopyFS on '~/.poopy/poopy_fs'...
[INFO|...] Poopy > Starting scripts deployment storage on '~/.poopy/scripts'...
[INFO|...] Poopy > Preparing mappers...
[INFO|...] Poopy > Preparing reducers...
[INFO|...] Poopy > Start announce my existence...
[INFO|...] Pong > Announcing myself with uuid 'XXXXX' every '5' seconds

2. Subir en el archivo a procesar (por ejemplo uno llamado iris.arff a poopyFS


$ poopy upload amqp://<BROKER_IP> iris.arff poopyFS://iris.arff
[INFO|...] Poopy > Start discover nodes...
[INFO|...] Poopy > Start uploading file...
[INFO|...] poopyFS > Upoloading 'iris.arff' to 'poopyFS://iris.arff'
[INFO|...] Poopy > Killing 2 processes..

3. Ejecutar la tarea map reduce especificando, script, clase y directorio de salida


$ poopy run amqp://<BROKER_IP> randomforest.py Script out
[INFO|...] Poopy > Start discover nodes...
[INFO|...] Poopy > Iname generated: i061ae100c21043e4ad856126e99d21db_randomforest.py
[INFO|...] Poopy > Deploying script...
[INFO|...] Scripts > Deploying script 'randomforest.py'
[INFO|...] Poopy > Run will start in 8.0 seconds...
[INFO|...] Poopy > Found 1 nodes
[INFO|...] Poopy > Starting Map Responsers...
[INFO|...] Poopy > Starting Reduce Responsers...
[INFO|...] Poopy > Starting Mapperss...
[INFO|...] Map > Reading script randomforest.py...
[INFO|...] Map > Reading randomforest.py configuration...
[INFO|...] Map > Sending Map Execution signal for script 'Random Forest' to node 'XXX'
[INFO|...] Poopy > Mappers finished
[INFO|...] Poopy > Starting Reducers...
[INFO|...] Reduce > Reading script randomforest.py...
[INFO|...] Reduce > Reading randomforest.py configuration...
[INFO|...] Reduce > Sending Reduce Execution signal for job 'Random Forest' to node 'XXX'
[INFO|...] Poopy > Reducers finished
[INFO|...] Poopy > Writing output
[INFO|...] Poopy > Your data is pickled in base64 here out/2014-12-05T04-24-20.502159
If you want to extract the model use 'serializer.load|s'
[INFO|...] Poopy > Killing 6 processes..
11 http://www.cs.waikato.ac.nz/ml/weka/arff.html
12 http://www.ietf.org/rfc/rfc4180.txt
13 http://en.wikipedia.org/wiki/Plain_text
14 http://www.rabbitmq.com
15 http://activemq.apache.org/

4.2. Esperas y Timeouts

13

Implementacin de un sistema de cmputo distribudo Map-Reduce sobre AMQP

Finalmente el resultado de la tarea se ecuenntra en el archivo: out/2014-12-05T04-24-20.502159. Para leerlo


se puede utilizar el modulo serializer de poopy

4.3 Anlisis del ciclo de vida del comando run


Al momento de ejecutar el comando run, Poopy nos informa por pantalla paso a paso como se va preparando para
ejecutar y efectivamente ejecuta la tarea. Los pasos relevantes son:
[INFO|...] Poopy > Start discover nodes...
En este momento Poopy empieza a escuchar cuales son los nodos que existen que estan preparados para procesar.
[INFO|...] Poopy > Iname generated: i061ae100c21043e4ad856126e99d21db_randomforest.py
Genera nombre unico para el script para desplegarlo en todos los nodos disponibles, lo hace en las siguientes
dos lineas.
[INFO|...] Poopy > Run will start in 8.0 seconds...
Espera un momento para recopilar informacin de todos los nodos disponibles para el cmputo. Luego lanza las
tareas en los nodos encontrados
[INFO|...] Poopy > Writing output
Escribe la salida de a ejecucin en el directorio que se pas como parmetro.

14

Captulo 4. Resultados - Poopy

CAPTULO 5

Conclusin

La vida es el arte de sacar conclusiones suficientes a partir de datos insuficientes.


Samuel Butler (1612-1680) Poeta ingls.
Si bien el proyecto en su estado actual es utlizable y posee bastantes caracterstica tiles, es conveniente realizar los
siguientes cambios si se desea usar Poopy en un entorno real:
Implementar correctamente los timeouts: actualmente si un nodo falla el nodo central se queda esperando eternamente. Dado que la informacin de vida de un nodo de computo se esta recolectando es solamente
utilizarla.
Crear una cola para el pasaje de errores: Esto es importante para que el nodo central sepa por que fallo un
nodo de cmputo.
Crear un sistema distribuido de archivos real: Actualmente lo nico que hace Poopy es dejar todos los
archivos en todos los nodos. Esto implicara guardar en el nodo de aviso de vida que pedazos de archivos tiene
que nodo para distribuir correctamente las tareas.
Permitir mas de un map-reduce por tarea.
Mejorar los formatos de salida: Actualmente solo se genera un formato binario bastante intil si lo que se
quiere es generar reportes legibles por humanos.
Evitar que el nodo central sea utilizado como memoria intermedia: Todas las salidas de las tareas map
actualmente viven en la memoria del nodo central, esto es un cuello de botella. Se podra solucionar utilizando
como memoria intermedia el propio poopyFS.
Hacer un reordenamiento de cdigo para facilitar la mantenibilidad.
Implementar herramientas para navegar el contenido de poopyFS.
Cabe aclarar que AMQP para lograr una robustez similar a la de Hadoop es necesario desplegar mas un broker; ya
que una cada de un nico nodo central implicara que todo el sistema falle, al punto de que se volvera inaccesible los
datos almacenados en poopyFS.

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

Implementacin de un sistema de cmputo distribudo Map-Reduce sobre AMQP

16

Captulo 5. Conclusin

CAPTULO 6

Apndice A: Pseudo Cdigo de Poopy

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

// coneccion al broker de ampq


conn = obtener_conexion_de_ampq()

5
6
7
8

// variables que mantienen el estado de las tareas


tareas_map = []
tareas_reduce = []

9
10
11

tareas_map_ejecutandose = []
tareas_reduce_ejecutandose = []

12
13
14

tareas_map_completas = []
tareas_reduce_completas = []

15
16
17

// contiene todos los nodos descubiertos


nodos = []

18

1 http://www.famaf.unc.edu.ar/
2 http://hadoop.apache.org/

17

Implementacin de un sistema de cmputo distribudo Map-Reduce sobre AMQP

19
20

// valores intermedios de map (podria usarse archivos)


valores_intermedios = {}

21
22
23

// Exchange para transportar archivos entre nodos


file_exchange = conn.obtener_exchange()

24
25
26

// Exchange para enviar datos a los mappers


map_out_exchange = conn.obtener_exchange()

27
28
29

// Exchange para resumir datos a los reducers


map_in_exchange = conn.obtener_exchange()

30
31
32

// Exchange para avisar tareas map finalizadas


map_end_exchange = conn.obtener_exchange()

33
34
35

// Exchange para enviar datos a los reducers


reduce_out_exchange = conn.obtener_exchange()

36
37
38

// Exchange para recibir y enviar a la salida los datos provenientes de reducers


reduce_in_exchange = conn.obtener_exchange()

39
40
41

// Exchange para avisar tareas reduce finalizadas


reduce_end_exchange = conn.obtener_exchange()

42
43
44
45

// Exchange para descubir nodos y obtener los descubiertos


descubir_exchange = conn.obtener_exchange()
descubierto_exchange = conn.obtener_exchange()

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

// cada nodo que se encuentre emitira un evento en descubierto_exchage


// y sera capturado por el callback de arriba
repetir_en_segundo_plano:
descubir_exchange.publicar_broadcast()

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

// obtiene 3 nodos al azar (por copiar a hadoop en su ejemplo por defecto


// para replicar los archivos en los diferentes nodos
// asumimos que algunos nodos se conectaron
para cada nodo en obtener_al_azar(nodos, 3)
file_exchange.publicar(archivo, para_nodo)
archivos_en_nodos[archivo.nombre].agregar(nodo)

66
67
68
69
70
71
72
73
74
75

// enviamos copias del archivo a ejecutar a todas los nodos


file_exchange.publicar_broadcast(script)

76

18

Captulo 6. Apndice A: Pseudo Cdigo de Poopy

Implementacin de un sistema de cmputo distribudo Map-Reduce sobre AMQP

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

map_in_exchange.conectar(function(node, id_tarea, k, v){


// si el nodo no se comunica hace mucho ignoramos el valor
si node esta en nodos y ahora - nodos[node].ultima_conexion < LIMITE:
// ver si esta tarea no fue emitida por algun nodo
si k not in valores_intermedios o id_tarea in tareas_map_ejecutandose:
si k no esta en valores_intermedios:
valores_intermedios[k] = []
valores_intermedios[k].agregar(v)
tareas_map_ejecutandos.agregar(id_tarea)
})

102
103
104
105
106

// si se terminan todos los maps de algun nodo


map_end_exchange.conectar(function(id_tarea){
tareas_map_completas.agregar(id_tarea)

107

// si todas las tareas estan completas


si tareas_map == tareas_map_completas:
// agrupamos valores intermedios en grupos de tamao n
para valores grupo agrupar(valores_intermedios, n)
// seleccionamos nodos para ejecutar los reduces
para cada grupo en los agrupar_al_azar(nodos, 3):
id = obtener_id_unico() // un id de tarea
reduce_out_exchange.publicar(
para_nodos=grupo, script.name, valores, id
)
tareas_reduce.agregar(id)

108
109
110
111
112
113
114
115
116
117
118
119

})

120
121
122
123
124
125
126
127
128
129

reduce_in_exchange.conectar(function(node, id_tarea, v){


// si el nodo no se comunica hace mucho ignoramos el valor
si node esta en nodos y ahora - nodos[node].ultima_conexion < LIMITE:
// ver si esta tarea no fue emitida por algun nodo
si k not in valores_intermedios o id_tarea in tareas_map_ejecutandose:
escribir_en_la_salida(v)
tareas_reduce_ejecutandose.agregar(id_tarea)
})

130
131
132
133
134

// si se terminan todos los reduce de algun nodo


map_end_exchange.conectar(function(id_tarea){
tareas_reduce_completas.agregar(id_tarea)

6.1. Cdigo perteneciente al nodo central encargado de lanzar las tareas distribuidas

19

Implementacin de un sistema de cmputo distribudo Map-Reduce sobre AMQP

135

// si todas las tareas estan completas


si tareas_reduce == tareas_reduce_completas:
conn.dejar_de_consumir()

136
137
138
139

})

140
141
142

// empezar a consumir las conexiones


conn.consumir()

6.2 Cdigo de nodos clientes


1

// Nodo Cliente

2
3
4

// coneccion al broker de ampq


conn = obtener_conexion_de_ampq()

5
6
7

// un id para identificar el nodo


nodo = obtener_id_al_azar()

8
9
10

// Exchange para transportar archivos entre nodos


file_exchange = conn.obtener_exchange()

11
12
13

// Exchange para enviar datos a los mappers


map_out_exchange = conn.obtener_exchange()

14
15
16

// Exchange para resumir datos a los reducers


map_in_exchange = conn.obtener_exchange()

17
18
19

// Exchange para avisar tareas map finalizadas


map_end_exchange = conn.obtener_exchange()

20
21
22

// Exchange para enviar datos a los reducers


reduce_out_exchange = conn.obtener_exchange()

23
24
25

// Exchange para recibir y enviar a la salida los datos provenientes de reducers


reduce_in_exchange = conn.obtener_exchange()

26
27
28

// Exchange para avisar tareas reduce finalizadas


reduce_end_exchange = conn.obtener_exchange()

29
30
31
32

// Exchange para descubir nodos y obtener los descubiertos


descubir_exchange = conn.obtener_exchange()
descubierto_exchange = conn.obtener_exchange()

33
34
35

// exchange para pedir archivos a otros nodos


need_file = conn.obtener_exchange()

36
37
38
39
40
41
42

// si se recibe el una peticion de descubrimiento


descubrir_exchange.conectar(function(){
repetir en segundo plano:
descubrir_exchange.publicar_broadcast(nodo)
})

43
44
45

// si se envia un archivo a este nodo

20

Captulo 6. Apndice A: Pseudo Cdigo de Poopy

Implementacin de un sistema de cmputo distribudo Map-Reduce sobre AMQP

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

// crea un contexto que si desde el archivo ejecutan


// ctx.write(llave, valor) agrega los datos de nodo y id de tarea es el
// write del ctx el que publica en map_out_exchange
ctx = crear_contexto_map(node, id)
para cada nombre_archivo en archivos_a_procesar:
si nombre_archivo no esta en carpeta_local:
// pedimos el archivo si no esta local
// esto puede implementarse de muchas formas como hacer la
// peticin y esperar que nos informe quien es el nodo que tiene
// y recien pedir el archivo explicitamente o est version mas
// resumida que pide los archivos y si responden 2 solo
// recibe los datos de uno
need_file.publicar_broadcast(nombre_archivo, node)
mietras nombre_archivo no esta en carpeta_local:
esperar()
fp = obtener_archivo_carpeta_local(nombre_archivo)
script.map(ctx, nombre_archivo, fp)

66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83

// avisamos que esta tarea termino


map_end_exchange.publicar_broadcast(id)

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

// crea un contexto que si desde el archivo ejecutan


// ctx.write(valor) agrega los datos de nodo y id de tarea es el
// write del ctx el que publica en reduce_out_exchange
ctx = crear_contexto_reduce(node, id)

93
94
95
96
97

para cada k, v en valores:


script.reduce(ctx, k, v)

98
99
100

// avisamos que esta tarea termino


reduce_end_exchange.publicar_broadcast(id)

101
102
103

6.2. Cdigo de nodos clientes

21

Implementacin de un sistema de cmputo distribudo Map-Reduce sobre AMQP

104

105
106
107
108

// empezar a consumir las conexiones


conn.consumir()

22

Captulo 6. Apndice A: Pseudo Cdigo de Poopy

También podría gustarte