• No se han encontrado resultados

Montaje de un clúster Raspberry para procesamiento paralelo basado en programación funcional

N/A
N/A
Protected

Academic year: 2021

Share "Montaje de un clúster Raspberry para procesamiento paralelo basado en programación funcional"

Copied!
6
0
0

Texto completo

(1)

Montaje de un clúster Raspberry para procesamiento paralelo basado en

programación funcional

Jorge G. HOYOS

Facultad de ingeniería de sistemas Universidad Santo Tomás Tunja, Boyacá Colombia

y Alex PUERTAS

Facultad de ingeniería de sistemas Universidad Santo Tomás Tunja, Boyacá Colombia

RESUMEN

El objeto de este trabajo es realizar la instalación e implementación de un clúster basado en tecnologías de bajo costo, que se estructuren como soluciones de procesamiento distribuido y de tipo portable y que puedan estar en capacidad de satisfacer necesidades en comunidades informáticas específicas. Para este particular, usando Raspberries PI 2 y Python como lenguaje de programación.

Para desarrollar el proyecto se modificó una fuente de 400 vatios de salida para alimentación y se estructuró una red de datos de tipo cableado/estático, usando Raspbian Jessie, como sistema operativo y MPI4PY como controlador del clúster, teniendo en cuenta la implementación de llaves de autenticación RSA para establecer comunicación entre los dispositivos físicos.

En cuanto a la programación, se llevó a cabo el diseño y desarrollo de un programa que permite calcular el factorial de un número, usando las estructuras de las funciones lambda de Python y paralelizado a través de MPI, en función del tiempo de procesamiento y la cantidad de raspberries usadas para la ejecución de la tarea.

Palabras Claves: clúster Raspberry, programación funcional,

tecnología MPI y Procesamiento Paralelo.

1. INTRODUCCIÓN

En primera instancia, en este documento, se encuentra el diseño de la estructura general del clúster, en función tanto, del sistema operativo y lenguaje de programación usado, como de los dispositivos de hardware implementados para el montaje físico en una red de comunicaciones que también se encuentra documentada. En este apartado puede apreciarse el desarrollo del clúster, en función de las conexiones y procesos de instalación de sus sistemas de control y comunicación, en este caso MPI, sin dejar de lado las diferentes aplicaciones instaladas para el acceso y modificación del sistema.

Como segundo punto del documento, está consignado lo referente a la programación de aplicaciones, en este caso, usando el paradigma funcional y Python como lenguaje de desarrollo. En este punto se pueden apreciar, tanto las ejecuciones del algoritmo desarrollado, como los análisis comparativos de las diferentes

ejecuciones del programa, esto en función del procesamiento paralelo y el tiempo de ejecución de la aplicación.

Finalmente se observan las conclusiones, recomendaciones y bibliografía generada a partir de este proyecto

2. IMPLEMENTACIÓN FÍSICA

Diseño de clúster: Como estructuración principal, se construyó

un clúster con cuatro nodos de procesamiento, usando Raspberries Pi 2 nombradas: pi01, pi02, pi03 y pi04, e implementando a la primera como sistema de control y ejecución de comandos. Para desarrollar esta tarea se tuvo en cuenta el siguiente esquema de ejecución: Implementación de una fuente de poder, instalación de software en los nodos del clúster y desarrollo de la red de comunicaciones, como se muestra a continuación:

Implementación de una fuente de poder: Para dotar de

corriente a las Raspberries fue necesario implementar un tipo de alimentación especial, que resultara funcional para el número de elementos conectados y el tiempo de conexión de la estructura en general. Bajo esta premisa, se desarrolló un dispositivo basado en una fuente de poder de PC conectada a dos múltiples USB estándar, que realizan este trabajo, dotando de energía al sistema. Es así que se conectó una fuente ATX EVGA 400W Power Supply, a través de sus plugs de +5V con 17A totales, a dos multiplicadores de puertos USB 2.0 de 7 puertos con encendido independiente, como los se muestra en la figura 1:

Figura 1: Conexión Fuente - Multiplicador USB 2.0

(2)

Esta conexión se realizó a través del puerto USB de entrada del multiplicador. Es de notar que al usar estos dispositivos como fuente de poder, debieron retirarse sus reguladores de amperaje, dado que estos limitan la salida de cada uno de sus puertos a 0.5A, lo cual resulta siendo insuficiente para los requerimientos mínimos de funcionamiento del dispositivo incluyendo sus periféricos vía USB(1.5A)[1]. Para la implementación final se armaron las carcasas de los multiplicadores de tal suerte que puedan usarse de forma independiente, dejando uno de ellos como encendido general de la fuente.

Figura 2: Fuente - Multiplicador USB 2.0 terminada

Fuente: Los autores

Instalación de software en los nodos del clúster: Para

implementar el sistema operativo en los dispositivos, se usó Raspbian en su versión 2016-02-09-raspbian-jessie el cual se instaló en una tarjeta micro SD clase 10 usando el programa WIN32 Disk Imager. Acto seguido se conectó una de las raspberries usando teclado, mouse, conexión a internet (de forma cableada) cable HDMI para el video y un conector para energía [2].

Se procedió a expandir la memoria de la Raspberry. Esto tiene por objeto usar todo el espacio de la tarjeta, lo cual es de gran utilidad en caso de actualizaciones e instalación de contenidos. Luego se seleccionaron, tanto el idioma como la zona temporal y el tipo de teclado para la interfaz del dispositivo, y por último, se cambió el nombre de la Raspberry a pi01 para efectos de identificación en el clúster

Después de lo anterior, se procedió a actualizar el sistema operativo, mediante el comando apt-get update desde el modo de súper usuario. Después, para administración remota, se instaló un servidor VNC en el dispositivo, en este caso tightvncserver, cuyo servició se inició, usando el comando vncserver: 1

-geometry 1280x768 teniendo en cuenta que el parámetro: 1 se

refiere al número de escritorio remoto y geometry a la resolución del dispositivo que conectará con la interfaz.

Para el cliente VNC se usó la aplicación Ultra VNC Viewer, desde el equipo remoto, tal como puede apreciarse en la figura 3:

Figura 3: Detalle de la conexión al servidor VNC

Fuente: Los autores

Instalación de MPICH: Para continuar la instalación, se

incorporó al sistema la librería de MPI (Messaging Passing interface), denominada MPICH que se usó para la sincronización del clúster, teniendo en cuenta el procesamiento en paralelo, dado que este modelo es usado en casos donde los nodos poseen memoria independiente, como en este y además permite implementar procesos dentro de una sola máquina o en un arreglo de estas [3].

Para esta instalación, se creó una carpeta denominada MPICH y dentro de ella se implementó el comando wget

http://www.mpich.org/static/downloads/3.1/mpich-3.1.tar.gz teniendo en cuenta, como lo menciona la línea de texto, la versión 3.1 para este ejercicio [4].

Figura 4: Implementación de mpich

Fuente: Los autores

Después de descomprimir el archivo, se crearon dos carpetas, una en la ruta de instalación del programa, en este caso

/rpimpi/mpi-install en el /home/pi de la pi01 y la otra mpi-build para los

procesos de construcción e instalación de MPICH. Finalmente, se usaron los comandos make y make install para terminar con este proceso.

Instalación de Python: debido a la selección de este lenguaje de

programación para realizar las pruebas respectivas, en torno al paradigma funcional, se instalaron dos aplicaciones básicas en este orden: Python-dev para poder realizar la compilación del código fuente y MPI4PY que está compuesta por estructuras MPI uno y dos que paralelizan los procesos de los programas

(3)

desarrollados y es un módulo de Python, directamente asociado a MPICH [5].

Es de notar que para la instalación de MPI4PY se obtuvo el

archivo mediante wget

https://bitbucket.org/mpi4py/mpi4py/downloads/mpi4py-1.3.1.tar.gz Este archivo se descomprimió, y a través del comando Python setup.py build se construyó la aplicación, para ser utilizada dentro del clúster.

Figura 5: Detalle de la instalación de MPI4PY

Fuente: Los autores

En última instancia, se procedió a realizar la revisión de la instalación de todos los programas necesarios para el funcionamiento del clúster, además de exportar en el PATH de la Raspberry la ruta de MPI4PY.

Figura 6: Detalle del funcionamiento del paralelizador

Fuente: Los autores

Desarrollo de la red de comunicaciones: Para esta

implementación se utilizó una red cableada entre los dispositivos y un concentrador, para este caso un switch TP-LINK TL-SG1016 de 16 puertos Gigabit Ethernet no administrable, con cables UTP categoría 6 para conexión física con las Raspberries.

Montaje de dispositivos: Terminado el proceso de instalación

sobre un dispositivo, se procedió a clonar la imagen trabajada en

pi01 en otras tres memorias de tipo MicroSD Clase 10, a través

de la herramienta Win32DiskImager. Estas ISO se instalaron sobre las demás Raspberries, que fueron llamadas pi02, pi03 y

pi04 respectivamente.

En cuanto al direccionamiento, se implementaron direcciones estáticas en cada una de los dispositivos, usando el dominio 192.168.0.0/24 como base y haciendo las pruebas de conectividad respectivas. Realizado lo anterior, se escribió un archivo llamado nodos en la pi01, el cual contiene las direcciones

IP de los equipos de procesamiento del clúster, y que fue usado como parámetro para la ejecución del programa en paralelo.

Figura 7: Detalle del archivo nodos en pi01

Fuente: Los autores

Implementación de llaves de autenticación: Para lograr la

conexión entre las diferentes raspberrries, se procedió a la creación de llaves de autenticación, en cada uno de los nodos, con esquema público/privado usando RSA, debido a que sin esto, no es posible tener autorización desde MPI para el uso de recursos distribuidos[6].

Figura 8: Creación de llave de autenticación

Fuente: Los autores

Después de creadas todas las llaves, se compartieron entre las Raspberries, teniendo en cuenta que se copió la llave de pi01 en cada una de ellas, para luego, desde pi01 traer las llaves de pi02,

pi03 y pi04, de tal suerte que todos los nodos conozcan a pi01 y pi01 conozca a todos los nodos del clúster.

Estructura Final: Al final, desde el punto de vista físico se logró

el siguiente resultado, teniendo en cuenta todas las consideraciones anteriores.

Figura 9: Implementación Final

(4)

3. IMPLEMENTACIÓN DEL PROGRAMA FUNCIONAL

Diseño de la aplicación: Para probar los parámetros de

programación funcional se usó Python como lenguaje de aplicación, dado que cuenta con funciones lambda implementadas dentro del mismo. En cuanto al algoritmo matemático, se seleccionó el del factorial de un número. Así que, de forma general se desarrolló un programa, denominado fac.py que realizara este cálculo, como se muestra a continuación:

Figura 10: programa para cálculo del factorial del número 33 usando Python

Fuente: Los autores

Como eje central del programa está la función fac implementada a partir de una función Lambda recursiva como puede verse en la figura 10. Esta contiene las validaciones respectivas del factorial de un número, teniendo en cuenta tanto, la inclusión de un número negativo en cuyo caso, por definición su factorial no está definido, cómo el valor del factorial del número cero (0) que siempre es el valor constante uno (1)[7] Ahora bien, si el valor ingresado era un número positivo mayor que cero, se calculaba su factorial con base en la reducción del producto del rango comprendido entre uno (1) y el número ingresado, usando una función lambda con dos parámetros (x,y) la cual realiza esta multiplicación, como puede apreciarse a continuación:

Figura 11: Funcionamiento del cálculo de un factorial con la función implementada

Fuente: Los autores

En la figura 11, se muestra el cálculo del factorial del número cinco (5) como ejemplo de explicación en el programa: Como primera medida la estructura range(1, n+1) permitía crear una lista de números para el cálculo del factorial [8], el número uno (1) indicaba la cota inferior, en tanto que n+1 representaba la superior. Es de notar que n se incrementó en uno, dado que en Python el límite superior de un rango es abierto, por ende no incluía el número propiamente dicho:

Figura 12: Diferenciación de rangos en Python

Fuente: Los autores

En segundo lugar, la función lambda interna, tomaba dos parámetros de funcionamiento, notados por (x,y) en el código. Con ello la función usaba los valores que estaban en las dos primeras posiciones del rango, en este caso uno (1) y dos (2) para ejecutar alguna operación con ellos. Ahora bien, reduce, le permite a Python aplicar una función dada a cada par de elementos de una lista, de tal suerte que se puedan simplificar en un solo dato [9], así pues el producto de estos números, notado por x*y en el programa, se transformaba en la siguiente x de la operación del factorial, la cual se multiplicaba por el valor tres (3) que se encontraba en la tercera posición de la lista. Este proceso se repetía, de forma recursiva hasta llegar al final de la lista, obteniendo así el factorial de un número dado.

Por otra parte, las variables tiempoi y tiempof se usaron para medir el tiempo de ejecución del programa, para ello se tomaron dos timesptamps [10] (en segundos), uno antes de la ejecución del factorial y otro después del mismo, luego se calculó la diferencia entre ambos y se guardó en una tercera variable denominada tiempoe, cuyo contenido era una aproximación al tiempo de ejecución de la función desarrollada. Esta variable se imprimió por pantalla, de tal suerte que se tuviera un registro del proceso.

Por otra parte, se incluyó la línea de código sys.setrecursionlimit(2000) que permitía ampliar la cola de procesos recursivos, mediante la modificación del valor del número de funciones anidadas que soporta la aplicación [11], que por defecto es de 1000, lo cual previene volcados de pila en los programas ejecutados. Ahora bien, dado lo anterior no era posible ejecutar el factorial de 2.000.000, así que se optó por subir el valor a 2000 funciones mediante la línea de código citada.

Continuando con la explicación del código, la ejecución de la función que calcula el factorial de un número, se implementó mediante la línea fac(2000000) en el programa, siendo 2.000.000 el valor de entrada n en la función lambda. Esta función se embebió dentro de un print, con el fin de poder mostrarla por pantalla al momento de la ejecución del código.

También es de notar que se usaron tres imports en la construcción del programa: se trajeron los componentes de sys para el manejo de funciones anidadas, análogamente se hizo lo mismo desde functools y time, para poder utilizar las herramientas reduce y time respectivamente.

Por último se realizaron pruebas del funcionamiento de la aplicación usando valores conocidos de factoriales de números, como puede observarse a continuación:

Figura 13: Ejecución del programa con el número 33 como parámetro

Fuente: Los autores

4. PRUEBAS DE FUNCIONALIDAD MEDIANTE EJECUCIÓN PARALELA EN EL CLÚSTER

Para finalizar este estudio se diseñó una prueba en donde se ejecutó fac.py para número dos millones de forma paralela el arreglo de equipos.

(5)

En esta prueba se tuvieron en cuenta dos aspectos fundamentales: En primer lugar se ejecutó el programa utilizando MPI en un solo nodo del clúster, implementando de 1 a 8 procesos en la máquina seleccionada en 10 ejecuciones diferentes para cada uno. Al final de cada intento se registró el tiempo de duración y se realizó el promedio de las 10 iteraciones, con el fin de obtener la media de los datos obtenidos, los cuales fueron tomados como información de control en este ejercicio. En segundo lugar se desarrolló esta misma medición usando ahora los cuatro nodos componentes del clúster, y se realizaron las comparaciones contra los datos de base teniendo como variables de medición: El tiempo de ejecución del programa, la cantidad de procesos paralelos y el número de dispositivos físicos utilizados para esta tarea.

Ejecución para un solo nodo: la ejecución del programa se

desarrolló mediante el comando mpiexec en la terminal de Linux sobre la Raspberry. Es de notar que debido al diseño del clúster, todas estas pruebas aplicaron desde la pi01 como puede observarse a continuación:

Figura 14: Detalle de la ejecución del programa paralelizado en pi01

Fuente: Los autores

La figura 14, muestra el desarrollo en paralelo del programa para 3, 5 y 8 procesos en un solo nodo del clúster. Es importante tener en cuenta que fac.py se ejecutó paralelamente cómo tantos procesos fueron desplegados, es decir con n = 3 el código se implementó 3 veces en pi01. También cabe anotar que la ejecución del paralelizador se logró mediante el comando mpiexec y que se registraron evidencias de los procesos dentro de la máquina, como puede observarse a continuación con un n = 8 y usando el comando top –p numero_de_proceso en una terminal Linux.

Figura 15: Ejecución de fac.py para n = 8 en pi01

Fuente: Los autores

Ahora bien, para realizar la implementación del clúster, se realizaron las mismas pruebas utilizando la estructura de mpiexec desde pi01, como control de sistema, teniendo en cuenta la utilización del archivo nodos como parte de la sentencia del programa, usando la herramienta f del comando de ejecución y obteniendo los siguientes resultados:

Figura 16: Ejecución de proceso en el clúster para cinco procesos

Fuente: los autores

La figura16, muestra el comando de ejecución del programa para cinco procesos y sus correspondientes imágenes en cada uno de los nodos del clúster. Al finalizar la ejecución, los resultados del procesamiento de cada una de las máquinas fueron condensados en una sola respuesta en pi01.

Figura 17: Respuesta de la aplicación para 7 procesos en paralelo

Fuente: los autores

Al establecer la comparación entre el procesamiento paralelo usando una sola máquina (pi01) y el clúster implementado con cuatro nodos, fue posible determinar las diferencias de tiempo en el procesamiento de las peticiones solicitadas por consola

Figura 18: Comparación de tiempos de ejecución entre paralelismo en una máquina y en un clúster

Fuente: Los Autores

Para observar la cantidad de procesos implementados en el clúster, se procedió a contar las apariciones de fac.py en cada una de los registros de memoria en las Raspberries del sistema, luego se graficaron los procesos totales de las ejecuciones, es decir desde uno (1) hasta ocho (8) versus la cantidad de procesos creados en cada máquina en cada ejecución:

(6)

Figura 19: Cantidad de procesos en los nodos del clúster

Fuente: Los autores

Como puede observarse en la figura 19, el nodo pi01 fue quien más ejecutó el proceso durante todo el ejercicio, con un total de 12 implementaciones y presencia en todas las pruebas programadas.

De una forma más general, el porcentaje de uso de recursos en el clúster se puede observar de la siguiente manera:

Figura 20: Porcentajes de utilización de los nodos del clúster

Fuente: Los autores

5. CONCLUSIONES

Como una conclusión general, es importante anotar que es posible desarrollar una aplicación en paralelo a bajo costo y poco espacio físico de utilización, usando herramientas de Hardware y Software libre que supla necesidades de procesamiento para tareas de esta índole y que, usando el paradigma funcional, permita realizar operaciones a partir de funciones lambda ahorrando codificaciones mayores, debido a las asignaciones de memoria y tipos de variables utilizadas, sobre todo teniendo en cuenta el cálculo para números de gran tamaño, como fue en este caso, además, con la utilización de tecnología MPI para la ejecución paralela de aplicaciones fue posible lograr sincronización de los procesos ejecutados en paralelo, de una forma cómoda para el usuario de la aplicación y de forma independiente en cada una de los nodos de procesamiento.

Por otra parte, la utilización de clústeres de procesamiento funciona como una forma de optimización de procesos, ya que es posible ejecutar múltiples ejecuciones de un mismo programa en las diferentes máquinas que lo componen.

Sin embargo también cabe anotar que los datos obtenidos están sujetos también a las colas de procesos de cada uno de los nodos y a las condiciones de temperatura y manejo general de los mismos.

Python ofreció una gran versatilidad al momento de abordar el paradigma funcional, como forma de implementación de programas en el clúster desarrollado, dado a que contiene una sintaxis de fácil comprensión y utilización para este tipo de procedimientos.

6. REFERENCIAS

[1] Monk, Simon. Raspberry Pi cookbook: Software and hardware problems and solutions. " O'Reilly Media, Inc.", 2016. Pág. 5.

[2] Monk, Simon. Raspberry Pi cookbook: Software and hardware problems and solutions. " O'Reilly Media, Inc.", 2016. Pág. 15.

[3] Zaccone, Giancarlo. Python Parallel Programming Cookbook. Packt Publishing Ltd, 2015. Pág. 15

[4] Zaccone, Giancarlo. Python Parallel Programming Cookbook. Packt Publishing Ltd, 2015. Pág. 98

[5] Zaccone, Giancarlo. Python Parallel Programming Cookbook. Packt Publishing Ltd, 2015. Pág. 99

[6] Vega, Isidro Robledo. "INFORME FINAL DEL PROTOTIPO:“Cluster Beowulf de 16 Nodos”. 2009. Pág. 7 [7] Da Rosa, Sylvia, Beatriz Frioni, y Nélida Giraldez.

"Funciones Recursivas." Pág. 24

[8] Driscoll Michael. Python 101. Learnpub. 2016. Pág. 36 [9] Lutz, Mark. Learning python. " O'Reilly Media, Inc.", 2013.

Pág. 576.

[10] Driscoll Michael. Python 101. Learnpub. 2016. Pág 138.

[11] Goodrich, Michael T., Roberto Tamassia, y Michael H. Goldwasser. Data structures and algorithms in Python. John Wiley & Sons Ltd, 2013. Pág. 168.

Referencias

Documento similar

Por ello, es fundamental desentrañar cuál es el contexto, el proyecto de ciudadanía y el concepto de equidad que propone la Educación Popular en relación a la calidad educativa,

Parallel processes typically need to exchange data.. There are several ways this can be accomplished, such as through a shared memory bus or over a network, however the actual

En la tabla siguiente se muestran los diferentes tiempos de ejecución obtenidos para los distintos “workers”, junto con una pequeña gráfica de esta tabla donde podremos

En concreto se ha realizado la modificación del entorno de procesamiento Sleuthkit en una herramienta de procesamiento de datos en paralelo manteniendo el mismo

Resumen---- El diseño y la implementación de un clúster para aplicaciones de alto rendimiento y disponibilidad, que trabaje con sistema de ficheros paralelo

Separa y escribe en los recuadros las sílabas de cada dibujo y en la línea derecha coloca el nombre de la palabra según el número de sílabas que tienen.. Pronuncia las palabras,

El fin último del presente trabajo es conseguir la sensorización de un robot paralelo utilizado para aplicaciones médicas, conocido como “TrueLock Hexapod” (TL-Hex)

Los problemas de equilibrado de líneas de montaje en paralelo (Parallel Assembly Lines Balancing Problem (PALBP)) pueden presentar líneas con tiempos de ciclo diferentes.. Como