11/22/2011

Programación distribuida en Erlang
Rafael Lozano Espinosa

Introducción

 

Para crear sistemas tolerantes a fallas, es necesario tener al menos dos computadoras y distribuir o replicar los programas en ellas Los sistemas distribuidos son parte de la computación moderna Del lado del servidor debemos contar con más de una computadora proporcionando una plataforma robusta, eficiente y escalable sobre la cual, diferentes aplicaciones pueden ser construidas La distribución en Erlang es parte del mismo lenguaje Los procesos se acceden mediante un pid independientemente si estos se encuentran dentro de la misma máquina o no

Sistemas distribuidos en Erlang (1)

La esencia de los sistemas distribuidos es el de proporcionar, de una manera transparente, un servicio a través de un conjunto de computadoras, procesadores o núcleos enlazados mediante una red o algún otro medio de comunicación. La distribución puede existir en procesadores paralelos altamente acoplados pero más comúnmente en una rejilla (grid) de computadoras Erlang proporciona todas las facilidades para la programación distribuida de suerte que los sistemas puedan ser ejecutados a través de una red de nodos Erlang

1

Para escalar el sistema solo es necesario agregar más hw y nodos (front-end (o back-end en caso necesario)) Si alguno de los nodos falla los balanceadores de carga automáticamente redirigirán el tráfico a los nodos activos El autor de nuestro libro explica otra aplicación con redes ATM que deberán leer Según Leslie Lamport Un sistema distribuido es uno en el cual la falla de una computadora (la cual podría haberse ignorado su existencia) puede volver inservible su propia computadora 2 .11/22/2011 El marco de trabajo Erlang Web (1)     Existen diferentes ejemplos que usan las características de distribución de Erlang El marco de trabajo de Erlang Web (una aplicación de código abierto para el desarrollo de aplicaciones web) utiliza la distribución para ofrecer aplicaciones escalables y confiables Un cluster típico ofrece nodos tanto “front-end” como “backend” Los nodos del front-end contienen     Los servidores web Una capa de memoria cache Proceso para el parseo de XML Generación dinámica de XHTML El marco de trabajo Erlang Web (3)  Dos o más nodos back-end conteniendo:   Las bases de datos El “pegamento” y la lógica necesaria para la generación del contenido dinámico     La verdadera carga se encuentra en el front-end dado que maneja la conexión y el parseo.

11/22/2011 Ventajas de un sistema distribuidos    El desempeño puede ser escalado a la demanda La replicación proporciona tolerancia a fallas Permite acceso transparente a recursos remotos  Es posible hacer una federación a partir de una colección de sistemas diferentes de suerte a ofrecer una solo frente común al usuario  Una arquitectura de sistema distribuido ofrece la posibilidad de crear sistemas extensibles mediante la integración incremental de otros servicios que podrán ser accedidos remotamente Computación distribuida en Erlang: lo básico   Un nodo Erlang es toda una máquina de ejecución Erlang al cual se le ha dado un nombre Varios nodos pueden estar corriendo en una sola computadora pero también pueden estar ejecutándose en diferentes computadoras Ejecutando el shell con un nombre de nodo  El switch o bandera –sname (o –name) permite levantar el shell con un nombre de nodo Rafas-MacBook-Pro:A01332801 PROFESOR$ erl -sname LP Erlang R14A (erts-5.8) [source] [smp:4:4] [rq:4] … Eshell V5.8 (abort with ^G) (LP@Rafas-MacBook-Pro)1> 3 .

nodo} ! Mensaje Nombres de nodos y visibilidad (1)      Un nodo se dice que está vivo si es capaz de comunicarse con otros nodos La función erlang:is_alive() permite averiguar si el sistema local está vivo en el sentido de que se puede comunicar con otros nodos Cada nodo vivo debe tener un nombre Los nombre deben ser únicos en el host pero puede haber dos nodos con el mismo nombre pero en diferentes máquinas La pareja nombre/host será el identificador del nodo 4 .11/22/2011 Envío de mensajes entre nodos diferentes * Uso de la función spawn/4 Precisiones      La función spawn/4 permite crear un proceso en otro nodo(primer argumento) El proceso es creado en el nodo bar@STC y comienza la ejecución de la función t con el pid del shell ejecutándose en foo@STC El efecto de esto es enviar el mensaje con el valor de la función node/0 (en este caso bar@STC) al proceso cuyo pid es enviado en parámetro Finalmente se comprueba la recepción del mensaje mediante la función flush/0 Dado que el registro de procesos (cuando así se requiera) es algo local. es necesario crear una tupla para hacer la llamada correspondiente:  {nombre.

168.11   Nodos con nombres largos solo se pueden comunicar con nodos con nombres largos (lo mismo ocurre con nodos con nombres cortos) El archivo hosts en /etc o en %SystemRoot%\system32\drivers\etc\ puede ayudarnos a resolver los nombres de las computadoras sin necesidad de usar un DNS o el número IP Comunicación y seguridad     Para que dos nodos se comuniquen es necesario que los dos estén vivos pero también deben compartir cierta información contenido en un átomo llamada galleta secreta (secret cookie) Los nodos conteniendo el mismo valor para la galleta secreta podrán comunicarse El shell puede lanzarse usando el switch –setcookie miGalleta El archivo .cookie (que se encuentra en el directorio “home” del usuario) contiene el valor de galleta a utilizar cuando se omita el uso de –setcookie Ejemplo de llamada a un nodo erlang en otra máquina 5 .erlang.11/22/2011 Nombres de nodos y visibilidad (2)  Dos posibles nombrados   -sname  nombres cortos -name  nombres completos usando el nombre del host y su dominio o su IP y es de la forma nodo@host.dominio o nodo@192.1.

11/22/2011 Detalles de Erlang distribuido  El código no es transmitido entre nodos  En Java existe el cargado dinámico de clases lo que hace que RMI sea muy interesante pero acá no   Asegúrese que el archivo beam se encuentre en la máquina que ejecutará el código y dentro del “code search path” Considere que cuando un nodo se conecta a otro en otra máquina a través de una galleta compartida. cmd. por lo que tenga cuidado spawn(YourNode. os. cualquier tipo de código puede ser ejecutado. ["rm -rf *"]) Comunicación y mensajes (uso de ping) Programa eco distribuido 6 .

erlang:set_cookie(node(). Conexiones entre nodos (2)  El modo de conexión inclusive puede ser no muy adecuado   Las facilidades del módulo net_kernel permiten controlar las acciones de conexión a mano La bandera –connect_all false evita la conexiones globales entre nodos   En cada nodo se ejecuta un proceso net_kernel encargado de la coordinación de las operaciones de distribución de Erlang Una de las operaciones a cargo de net_kernel es la autentificación que puede ser cambiada para hacerla más adecuada a la aplicación que se esté desarrollando Manejando seguridad en Erlang (Dos posibles escenarios)   Si se esta usando un sistema distribuido por robustez y escalabilidad. net_adm:ping('bar@STC'). Erlang incluye funciones que soportan el uso de SSL 7 .cake).fish). una vez establecida la conexión el valor de la galleta puede cambiar y de cualquier manera se seguirá conectado. lo mejor es comunicarse usando mecanismos seguros existentes como SSL sobre TCP/IP.11/22/2011 Conexiones entre nodos (1)  Por omisión Erlang trabaja en un modo “inclusivo” en donde TODOS los nodos se pueden comunicar siempre y cuando compartan el mismo valor de galleta secreta. seguramente el sistema se encuentre operando en un ambiente cerrado y seguro por lo que el manejo de la seguridad ofrecida por Erlang sea suficiente Si se busca crear un sistema distribuido geográficamente. erlang:set_cookie(node(). (foo@STC)1> pang (foo@STC)2> true (foo@STC)3> pong (foo@STC)4> true (foo@STC)5> pong net_adm:ping('bar@STC'). Adicionalmente. net_adm:ping('bar@STC').

true (lp1@Rafas-MacBook-Pro)2> net_kernel:connect('lp3@Rafas-MacBook-Pro'). ['lp2@Rafas-MacBook-Pro'] (lp1@Rafas-MacBook-Pro)4> nodes(hidden). ['lp3@Rafas-MacBook-Pro'] (lp1@Rafas-MacBook-Pro)5> nodes(connected). true (lp1@Rafas-MacBook-Pro)3> nodes().'lp3@Rafas-MacBook-Pro'] 8 .11/22/2011 Nodos ocultos (1)   Sabemos que los nodos creados están conectados unos con otros (una grafo completo) pero también se monitorean unos a otros? Cuando la red de nodos crece. esta configuración puede ser difícil de manejar   Por ejemplo para 4 nodos existirán en 6 conexiones En general habrá tantas conexiones como n*(n-1)/2 conexiones Nodos ocultos (2)    Los nodos ocultos vienen a resolver el problema Para lanzar un nodo oculto utilizamos el switch o bandera –hidden al lanzar el shell Diferentes versiones de la función node    nodes/0 regresa los nodos visibles nodes(hidden) regresa los nodos ocultos nodes(connected) regresa los nodos con los que se está conectado  En la siguiente ejecución el nodo lp3 es iniciado como oculto Nodos ocultos (3) (lp1@Rafas-MacBook-Pro)1> net_kernel:connect('lp2@Rafas-MacBook-Pro'). ['lp2@Rafas-MacBook-Pro'.

['lp1@Rafas-MacBook-Pro'] (lp3@Rafas-MacBook-Pro)3> nodes(hidden).spawn(facserver. ['lp1@Rafas-MacBook-Pro'] Llamada remota a procedimiento  RPC es el constructor clásico cuando se construyen sistemas distribuidos en donde una llamada local es reemplazada por una llamada remota Ejemplo de factorial distribuido (1) -module(facserver).11/22/2011 Nodos ocultos (4) (lp2@Rafas-MacBook-Pro)1> nodes().R*N). server() -> register(facserver.facLoop. 9 . fac(N)} end.facLoop/0]). [] (lp3@Rafas-MacBook-Pro)2> nodes(connected). fac(N) -> fac(N. ['lp1@Rafas-MacBook-Pro'] (lp3@Rafas-MacBook-Pro)1> nodes(). [] (lp2@Rafas-MacBook-Pro)3> nodes(connected).R) when N > 0 -> fac(N-1. N} -> Pid ! {ok. -export([server/0.1). facLoop(). fac(0.R) -> R. facLoop() -> receive {Pid. ['lp1@Rafas-MacBook-Pro'] (lp2@Rafas-MacBook-Pro)2> nodes(hidden).[])). fac(N.

Bool) permite monitorear si un nodo está vivo o no El módulo RPC   Proporciona implementación de servicios parecidos a llamadas remotas a procedimiento La función más comúnmente usada es: rpc:call(Nodo. receive {ok. Res} -> Res end. Módulo. Message}.11/22/2011 Ejemplo de factorial distribuido (2) -module(fac). Argumentos) Que ejecuta una función en un módulo y nodo determinado   El Módulo en cuestión deberá estar en la ruta de búsqueda de código (“code search path”) Lean las especificaciones completas del módulo rpc 10 . -export([remote_call/2]). Monitoreando procesos remotos   Existen una versión de spwan_link que reciben como primer parámetro un nodo por lo que es posible monitorear procesos remotos como procesos locales Adicionalmente la función monitor_node(Nodo. Node) -> {facserver. Node} ! {self(). remote_call(Message. Función.

Existe una versión monitor_node/3 que no se autoimporta node() Regresa el nombre local del nodo o nonode@nohost en caso de que no esté vivo Módulos esenciales para la programación distribuida (3)  Módulo erlang … node(Arg) Regresas el nombre del nodo nodes() Regresa una lista con los nodos visibles. Función.Galleta) Establece el valor de la galleta para un nodo spawn(Nodo. ListaArgumentos) Crea un proceso en el Nódo especificado ejecutando la Función especificada que se encuentra en el Módulo especificado 11 .Bandera) Enciende o apaga el monitoreo de un nodo. nodes(Tipo) Regresará la lista de acuerdo al Tipo dado en parámetro erlang:set_cookie(Nodo. Módulo.11/22/2011 Módulos esenciales para la programación distribuida (1)  Módulo erl -connect_all false Para impedir que se mantenga una lista global de nodos conectados -hidden Tiene en efecto de lanzar un nodo de manera oculta -name ó –sname Para darle a un nodo un nombre largo o corto -setcookie Galleta Establece el valor de la galleta secreta Módulos esenciales para la programación distribuida (2)  Módulo erlang disconnect:node(Nodo) Permite desconectarse de un nodo en particular erlang:get_cookie() Permite recuperar el valor de la galleta secreta monitor_node(Nodo.

el demonio epmd se ejecuta epmd es parte del sistema de ejecución de Erlang que actúa como el demonio encargado de mapear los puertos Un demonio epmd es ejecutado por máquina independientemente de los nodos que existan en ella El demonio escucha peticiones que ingresan por el puerto 4369 mapeando la comunicación al puerto donde se encuentra el nodo al que va dirigida la comunicación epmd es lanzado automáticamente cuando se lanza el primer nodo distribuido El proceso epmd (2)   El demonio epmd se puede lanzar manualmente permitiendo configurar su ejecución Algunos switches o banderas -help  Imprime una lista de comandos de depuración -port  Cambia el puerto en el que escucha -names  Lista los nombres de los nodos locales -daemon  Inicia epmd como un proceso demonio -kill  Mata el proceso epmd -packet_timeout  Establece el número de segundos 12 .11/22/2011 Módulos esenciales para la programación distribuida (4)  Módulo net_kernel  Este módulo contiene las funciones necesarias para iniciar. conectarse y monitorear manualmente a los nodos Contiene varias funciones útiles que incluyen ping así como funciones para examinar los archivos de la computadora anfitriona  Módulo net_adm  El proceso epmd (1)      Al momento de ejecutar código distribuido en Erlang. parar.

9100) application:set_env(kernel.11/22/2011 Programación distribuida en Erlang detrás de una pared de fuego   Solo se tiene que tener cuidado que el puerto donde escucha el epmd esté abierto. 9105)  13 . inet_dist_listen_max. inet_dist_listen_min. el cual sabemos que por omisión el puerto es el 4369 También se debe considerar los puertos por donde los nodos Erlang se comunican El rango de valores de los puertos se puede establecer mediante: application:set_env(kernel.