2. Estado del arte de los sistemas distribuidos Siguiente: 3. JavaGroups como herramienta Subir: Memoria Proyecto Fin de Anterior: 1. Introducción Subsecciones 2.1 2.2 2.3 2.4 Introducción Propiedades Campos de aplicación Comunicación y sincronización 2.4.1 Mecanismo de paso de mensajes 2.4.2 Llamada remota a procedimiento 2.4.3 Protocolos de radiado 2.4.4 Comunicación en grupo 2.5 Tolerancia a fallos 2.5.1 Semánticas de fallo 2.5.2 Replicación activa 2.5.3 Replicación mediante primario y respaldos 2.6 Herramientas para comunicación en grupo 2.6.1 Sistemas Monolíticos 2.6.1.1 Isis 2.6.1.2 Phoenix 2.6.1.3 RMP 2.6.1.4 Totem 2.6.1.5 Spread 2.6.2 Sistemas Modulares 2.6.2.1 Maestro/Ensamble 2.6.2.2 Appia 2.6.2.3 JavaGroups 2.6.3 Comparativa 2. Estado del arte de los sistemas distribuidos En el inicio de la era de la informática, las computadoras eran grandes y caras. Debido a su escasez y coste, sólo estaban en funcionamiento unas pocas en todo el mundo. A partir de los años 70, surgen los primeros miniordenadores (apareció el PC), que competirían con los grandes ordenadores tanto en prestaciones como en precio, con lo que se extendió su uso. Los grandes sistemas centralizados fueron dejando paso a sistemas mucho más descentralizados, formados por varios ordenadores. Pronto surgió la necesidad de interconenectar los equipos, y se desarrollaron las redes de área local (LAN), como Ethernet o Token Ring. En la actualidad, Internet es la red de mayor tamaño y la más usada, manteniendo un impresionante ritmo de crecimiento. Este crecimiento ha motivado durante los últimos años una mayor demanda de servicios por parte de los usuarios. Aunque los actuales sistemas en red solucionan parte de las necesidades actuales de comunicación entre computadoras, tienen importantes limitaciones, y no permiten desarrollar gran cantidad de aplicaciones, principalemente aquellas que por sus características, requieren estar disponibles de forma ininterrumpida. Es en estos casos dónde los sistemas distribuidos incorporan, además, tolerancia a fallos. http://www.iuma.ulpgc.es/users/lhdez/inves/pfcs/memoria-ivan/node2.html#SECTION00210000000000000000[20/02/2014 12:40:29 p.m.] 2. Estado del arte de los sistemas distribuidos 2.1 Introducción Existen varias definiciones de un sistema distribuido, una de ellas es [9] [19]: ``Un sistema de computación distribuido consta de múltiples procesadores autónomos que no comparten memoria principal, sino que cooperan a través de una red de comunicaciones que los interconecta'' (ver figura 2.1). El término sistema operativo distribuido [9] [19] define una capa que hace transparente a los usuarios la localización de los elementos que forman parte del sistema. Los sistemas centralizados tienen un punto de fallo único (hay un único computador en el que se ejecutan todas las aplicaciones). En los sistemas distribuidos, los elementos que lo componen están dispersos y, por lo tanto, tienen probabilidades de fallo independientes. Esta característica puede utilizarse para preveer la aparición de fallos parciales y posibilitar su tratamiento (otro computador puede sustituir al que ha fallado). De esta forma, el sistema distribuido permite la construcción de sistemas que operan de forma continua. Figura 2.1: Sistema distribuido Los sistemas distribuidos necesitan de un soporte de comunicaciones. Este servicio de comunicaciones debe ser fiable y con un rendimiento aceptable. Además, en los sistemas distribuidos aparecen los problemas clásicos de los sistemas concurrentes: recusos compartidos, sincronización, etc. En este capítulo se realiza una aproximación a estos sistemas, haciendo hincapié en los mecanismos de comunicación necesarios para el desarrollo de aplicaciones distribuidas y justificando el paradigma de grupo como propuesta válida para la implementación de aplicaciones distribuidas. 2.2 Propiedades Los sistemas distribuidos deben intentar proporcionar transparencia, eficiencia, flexibilidad, escalabilidad y fiabilidad [9]. Sin embargo, estos aspectos son, en parte, contrarios y, por lo tanto, al diseñar un sistema distribuido se debe intentar cumplir de manera aceptable con cada uno de ellos: http://www.iuma.ulpgc.es/users/lhdez/inves/pfcs/memoria-ivan/node2.html#SECTION00210000000000000000[20/02/2014 12:40:29 p.m.] 2. Estado del arte de los sistemas distribuidos Transparencia. El concepto de transparencia en un sistema distribuido, va ligado a la idea de que todo el sistema funcione de forma similar en todos los puntos de la red, independientemente de la posición del usuario. Es labor del sistema operativo establecer los mecanismos que oculten la naturaleza distribuida del sistema y que permitan trabajar a los usuarios como si de un único equipo se tratara. Eficiencia. La idea base de los sistemas distribuidos es obtener sistemas que, estando formados por un conjunto de ordenadores, sean mucho más rápidos que cualquiera de estos ordenadores por separado. En la práctica, esto es una utopía. El coste asociado a la comunicación de las distintas máquinas que componen el sistema distribuido hace que sus prestaciones disminuyan de forma considerable. Para lograr que un sistema como este sea eficiente hay que poner en práctica la idea de ejecutar un programa en un único procesador del sistema y, entonces, distribuir las tareas a realizar por éste en varios procesadores; necesitándose, por tanto, nuevas herramientas que permitan desarrollar aplicaciones de este tipo. Flexibilidad. Un campo en constante desarrollo como es el diseño de un sistema operativo distribuido, debe estar abierto a cambios y actualizaciones constantes que mejoren su funcionamiento. Esta necesidad ha generado dos posibles arquitecturas para el núcleo del sistema operativo: el núcleo monolítico y el micronúcleo. Las diferencias fundamentales entre ambos son los servicios que ofrece. Mientras el núcleo monolítico ofrece todas las funciones básicas del sistema, el micronúcleo incorpora solamente las fundamentales; como son, control y comunicación entre procesos, y gestión de la memoria. El resto de servicios se cargan dinámicamente en función de las demandas del usuario. Escalabilidad. Un sistema operativo distribuido debería funcionar de igual forma tanto para unos pocos ordenadores como para un conjunto enorme de ellos. Igualmente, debería no ser determinante el tipo de red utilizada (LAN o WAN) ni las distancias físicas entre los equipos que la conforman. Aunque esto sería lo deseable; en la práctica, no ocurre. Del mismo modo, el tipo de red condiciona tremendamente el rendimiento del sistema; por tanto, puede que lo que funcione para un tipo de red, para otro requiera un nuevo diseño. Fiabilidad. Una de las ventajas claras que ofrece la idea de un sistema distribuido, es que el funcionamiento del sistema no debe estar ligado a ciertas máquinas, sino que cualquier equipo pueda suplir a otro en caso de que uno se estropee o falle. La forma más evidente de lograr la fiabilidad de todo el sistema es el uso de redundancia, es decir, la información no debe estar almacenada en una sola máquina, sino en un conjunto de ellas. 2.3 Campos de aplicación En relación con los campos de aplicación de este tipo de sistemas; podemos distinguir, por un lado, aquellos donde la distribución es fundamentalmente un medio para conseguir un fin y, por otro, aquellos donde es un problema en sí misma. En los primeros, el uso de soluciones distribuidas pretende alcanzar las siguientes metas: Computación masivamente paralela, de propósito general y de alta velocidad. Tolerancia a fallos (confianza, disponibilidad). Respuesta a demandas con requisitos de tiempo real. En los segundos, son los propios requisitos de la aplicación los que fuerzan a evolucionar hacia soluciones distribuidas: Bases de datos distribuidas. Es necesario acceder a los datos desde lugares geográficamente http://www.iuma.ulpgc.es/users/lhdez/inves/pfcs/memoria-ivan/node2.html#SECTION00210000000000000000[20/02/2014 12:40:29 p.m.] 2. Estado del arte de los sistemas distribuidos dispersos y, además, puede ser también conveniente (e incluso imprescindible) almacenarlos en varios lugares diferentes manteniendo la consistencia de los mismos. Fabricación automatizada. Es necesaria la colaboración de muchos procesadores para coordinar las tareas a desempeñar. Supervisión remota y control. Los puntos (sensores, actuadores, nodos) donde se toman las decisiones de control pueden estar diseminados en diferentes partes de un sistema distribuido. Toma de decisiones coordinada. Hay muchas aplicaciones donde es necesario que varios procesadores participen en la toma de decisiones, por ejemplo, porque cada uno de ellos tiene una parte relevante de los datos y es necesario fusionarlos en cualquier momento. Los sistemas distribuidos necesitan obligatoriamente un soporte de comunicaciones. Este servicio de comunicaciones debe ser fiable y presentar un rendimiento aceptable. Además, en los sistemas distribuidos aparecen los problemas clásicos de los sistemas concurrentes: recursos compartidos y sincronización, entre otros. En las siguientes secciones se van a analizar estas características así como describir mecanismos que permiten explotar la posibilidad de tolerar fallos en los sistemas distribuidos. 2.4 Comunicación y sincronización El proceso es el concepto básico para expresar concurrencia, tanto en un sistema centralizado como en uno distribuido. Con la introducción de los procesos se permite dividir el software en módulos, cada uno de los cuales expresa una actividad lógicamente concurrente con el resto. Este modelo permite mayor simplicidad y más fácil comprensión del software utilizado, frente al comportamiento, muchas veces confuso, de un programa secuencial que trata de expresar un comportamiento concurrente. El modelo de proceso resulta incompleto si no se proporcionan mecanismos para la comunicación entre procesos. Esto es debido a que, normalmente, en todo sistema concurrente, existen interacciones entre sus diferentes actividades concurrentes. La diferencia más importante entre un sistema distribuido y uno centralizado es precisamente cómo se realiza la comunicación entre procesos. En un sistema centralizado, las interacciones entre procesos se hacen sobre memoria compartida, [9] mientras que en un sistema distribuido se necesita intercambio de mensajes. Los mecanismos a estudiar son entonces: el paso de mensajes punto a punto [2] [9] y la llamada remota a procedimiento [2] [9]. Una variante de los mensajes punto a punto son los buzones. Estos se usan para enviar o recibir mensajes, permitiendo no sólo desacoplar emisor y receptor sino, también, tener múltiples emisores y receptores. En un sistema distribuido, un emisor también debería poder referenciar, al mismo tiempo, a un conjunto de receptores ya que la información contenida en un mensaje puede ser necesaria en más de un punto del sistema distribuido. Por tanto, la comunicación con grupos de procesos es otro tipo de interacción que conviene analizar y solucionar. Un grupo [5] [9] [15] es un conjunto de objetos que comparten una semántica de aplicación común, así como el mismo identificador de grupo y/o dirección de comunicación. Cada grupo es visto como un ente lógico individual, que no deja ver a los usuarios su estructura interna ni las interacciones entre sus miembros. Si se pretende una definición más cercana a la implementación, podría ser esta: un grupo de procesos es un conjunto de puntos extremos de comunicación (por ejemplo sockets de UNIX) que se pueden referenciar como un único ente. Los grupos de procesos son una herramienta natural para programar un sistema distribuido, y su importancia ha ido incrementándose en entornos de programación distribuida a lo largo del tiempo. Sin embargo, aún no hay un modelo que unifique las semánticas más apropiadas que deben cumplir las interacciones de los miembros de estos grupos (tipos de primitivas de comunicación, notificación de la entrada y salida de los procesos que forman un grupo, entre otras). http://www.iuma.ulpgc.es/users/lhdez/inves/pfcs/memoria-ivan/node2.html#SECTION00210000000000000000[20/02/2014 12:40:29 p.m.] 2. Estado del arte de los sistemas distribuidos 2.4.1 Mecanismo de paso de mensajes El mecanismo de paso de mensajes punto a punto [2] [9] se define como una forma de comunicación en la que el usuario es explícitamente consciente del uso de mensajes en la comunicación mediante envíos y recepciones. Este tipo de interacción empezó a tener gran auge con la llegada de las arquitecturas multiprocesadores y distribuidas. Dicho mecanismo de comunicación entre procesos se ha desarrollado en el campo de los sistemas distribuidos de forma casi independiente al desarrollo de las redes de ordenadores. La Organización Internacional de Normalización (ISO) propone un conjunto de protocolos de comunicación para la interconexión de sistemas abiertos (OSI) y define un modelo de referencia compuesto por siete niveles: nivel físico, nivel de enlace de datos, nivel de red, nivel de transporte, nivel de sesión, nivel de presentación y nivel de aplicación. El objetivo de los cuatro primeros niveles es ofrecer comunicación fiable entre dos puntos extremos. Los tres últimos niveles se refieren a los modos de interacción, representación de datos y servicios adicionales que se ofrecen a los usuarios. Sin embargo, estos protocolos no consideran el ámbito y las necesidades de los sistemas distribuidos puesto que: Un sistema distribuido normalmente se organiza en torno a una red local. Estas redes son altamente fiables y no necesitan un control de errores de transmisión tan exhaustivo. Las interacciones dentro del sistema distribuido generalmente intercambian datos de pequeña longitud. La redundancia que se incluye para implementar los protocolos ISO es muy grande en proporción a los datos de usuario. Los protocolos de paso de mensajes permiten tolerar los fallos introducidos por la red, bien reintentando en caso de fallos transitorios, o bien reencaminando los mensajes en caso de fallos permanentes. Sin embargo, la detección de errores no es suficiente: además de considerar pérdidas de mensajes, corrupción de datos, duplicaciones y llegada de mensajes fuera de secuencia (en orden no FIFO), un sistema distribuido también necesita tratar con particiones de red, [9] caídas de equipos y entregas no causales entre otros. Estos fallos no siempre se pueden corregir con retransmisiones (es difícil diferenciar entre la partición de la red y la caída de un conjunto de servidores). No se tienen en cuenta las demandas de ciertos tipos de aplicaciones distribuidas que necesitan servicio de comunicación con grupos de procesos. Un diseño eficiente de los mecanismos de interacción entre procesos sólo se puede conseguir analizando cómo y para qué se utilizan. 2.4.2 Llamada remota a procedimiento La llamada remota a procedimiento (Remote Call Procedure, RPC) [2] [9] proporciona un nivel de abstracción más alto que el mecanismo de paso de mensajes, facilitando así la programación de aplicaciones distribuidas. Estas llamadas permiten al flujo de control de un proceso, que se ejecuta en un nodo del sistema, ejecutar de forma transparente una operación (procedimiento) que se encuentra en otro nodo (remoto). El diseño inicial de la aplicación es semejante al de una aplicación centralizada. Entonces se decide qué procedimientos se ejecutarán en la máquina remota y, utilizando herramientas automáticas, se construyen dos procedimientos suplentes: uno en el lado del cliente (stub) y otro en el lado del servidor (skeleton). Son estos procedimientos suplentes los que se encargan de que, al realizar una llamada localmente, la misma sea transmitida a través de la red para su ejecución remota (ver figura 2.2). De esta forma, el proceso cliente ejecuta un procedimiento remoto sin reparar en cómo se lleva a cabo la comunicación a través de la red. La única limitación en la RPC es que todos los parámetros que se utilicen en las llamadas han de ser pasados por valor, y no por referencia, ya que ambos procedimientos http://www.iuma.ulpgc.es/users/lhdez/inves/pfcs/memoria-ivan/node2.html#SECTION00210000000000000000[20/02/2014 12:40:29 p.m.] 2. Estado del arte de los sistemas distribuidos se ejecutan en espacios de memoria disjuntos. Sin embargo, para que estos parámetros puedan ser enviados a través de la red es necesario que los mismos sean serializables, es decir, han de poder ser convertidos en una corriente de bytes. Figura 2.2: Llamada remota a procedimiento 2.4.3 Protocolos de radiado El simple intercambio de mensajes entre un emisor y un receptor, no es siempre un buen modelo de comunicación para un sistema distribuido. En muchas situaciones es más útil disponer de primitivas que permitan enviar datos desde un emisor a un grupo de procesos, dado que este tipo de comunicación es muy habitual en estos sistemas (por ejemplo, para conseguir tolerancia a fallos, reparto de carga o mejora de la velocidad de respuesta). En estos casos es más apropiado pensar en términos de radiado [9] [15] (de mensajes) y no, del tradicional unienvío. El radiado de mensajes [9] [15] es una herramienta que permite simplificar el diseño de varios aspectos de un sistema distribuido: Tolerancia a fallos. Para que un servicio siga funcionando correctamente en presencia de fallos pueden replicarse los servidores que lo proporcionan (servidores replicados). En ese caso, el servicio puede permanecer disponible incluso cuando varios de los procesos que lo proporcionan dejen de funcionar. Cuando los clientes desean hacer uso de él, radian los mensajes al grupo de servidores replicados y esperan la respuesta de uno cualquiera de ellos (o de todos, o de ninguno). Localización de objetos. Cuando un proceso necesita encontrar un objeto, puede simplemente realizar un radiado a todos los procesos donde cree que pueda estar. Esta técnica se usa, por ejemplo, en el Sistema V para localizar ficheros (radiando el mensaje a todos los servidores de ficheros) y en Amoeba para localizar servidores. Replicación de datos. En muchos casos puede servir para mejorar la eficiencia de un sistema. Por ejemplo, se pueden mantener copias de una base de datos en varios servidores. Para actualizar un registro se realiza un radiado a todos los servidores (los datos deben permanecer consistentes). Notificación múltiple. Con un radiado puede notificarse una información a todo un grupo de procesos. Por ejemplo, se les puede avisar así de que un proceso ha muerto, para que tomen las medidas oportunas. La programación de sistemas distribuidos resulta más sencilla si se dispone de un soporte de comunicación que entienda de grupos de procesos y que asegure una serie de propiedades en la entrega de los mensajes: [9] Radiado fiable. Este tipo de radiado debe cumplir las propiedades de: Validez. Si un proceso correcto (proceso que se comporta de acuerdo a su especificación) radia el mensaje , entonces a todos los procesos correctos eventualmente se les entrega http://www.iuma.ulpgc.es/users/lhdez/inves/pfcs/memoria-ivan/node2.html#SECTION00210000000000000000[20/02/2014 12:40:29 p.m.] 2. Estado del arte de los sistemas distribuidos . Evita la solución trivial de un radiado que nunca entrega mensajes. Consenso. Si a un proceso correcto se le entrega un mensaje procesos correctos se les entrega . Integridad. Todo proceso entrega el mismo mensaje otro se lo envió. , entonces a todos los como mucho una vez, y sólo si algún Radiado FIFO. Es un radiado fiable que garantiza que si un proceso radia antes de radiar a un proceso correcto se le entrega , entonces a se le entregó antes de que se le ,y . entregase Radiado causal. Es un radiado fiable que respeta el orden causal (definido por Lamport). Es decir, si el radiado de precede causalmente al radiado de , y a un proceso correcto se le entrega , entonces a se le entregó antes de que se le entregase . Radiado atómico. Es un radiado fiable que ofrece entrega ordenada. Es decir, si al proceso correcto y al proceso correcto se les entregan el mensaje y el mensaje , entonces a se le entrega antes que si y sólo si a se le entrega antes que . Radiado uniforme. Es un radiado fiable que cumple la propiedad de uniformidad. Según la característica de consenso asociada a los radiados fiables, se permite que a un proceso fallido se le entregue el mensaje , y a los procesos correctos no se les entregue el mensaje . Para evitar esto se define la entrega uniforme: si a algún proceso (correcto o fallido) se le entrega el mensaje , entonces a todos los procesos correctos eventualmente se les entrega el mensaje . 2.4.4 Comunicación en grupo La mayor parte de aplicaciones distribuidas está basada en el paradigma cliente/servidor. Para resolver esta interacción utilizando grupos de procesos, se necesitan sistemas de comunicación en los que un proceso pueda enviar mensajes a varios procesos (comunicación ), recibir sus respuestas (comunicación ) e, incluso, que un conjunto de procesos pueda enviar mensajes a otro grupo (comunicación ). El desarrollo de estos tipos de comunicación, conocidos como radiados, [9] [15] está íntimamente relacionado con los grupos de procesos. [9] [15] Podemos considerar a un grupo como un conjunto de procesos con una semántica común. La propiedad fundamental que deben cumplir es que cuando se envía un mensaje, todos los miembros lo reciben. De esta forma se puede conseguir la coordinación de los distintos miembros que forman un grupo. http://www.iuma.ulpgc.es/users/lhdez/inves/pfcs/memoria-ivan/node2.html#SECTION00210000000000000000[20/02/2014 12:40:29 p.m.] 2. Estado del arte de los sistemas distribuidos Figura 2.3: Grupos abiertos y grupos cerrados Los sistemas que soportan comunicación con grupos pueden dividirse en dos categorías: grupos cerrados y grupos abiertos (ver figura 2.3). En los primeros sólo se permite la comunicación entre los miembros del grupo, mientras que en los segundos, los procesos que no pertenecen al grupo pueden interactuar con él. Los grupos cerrados suelen utilizarse, en general, para el procesamiento en paralelo, donde cada uno de los miembros tiene su propio objetivo y no interactúa con el ``mundo exterior''. En cambio, los grupos abiertos están pensados para el desarrollo de aplicaciones tipo cliente/servidor, donde los procesos interactúan con el grupo para solicitar servicios. También podemos clasificar los grupos de procesos atendiendo al papel que desempeñan los miembros que los componen: grupos de iguales y grupos jerárquicos (ver figura 2.4). Si en un grupo no existe una distinción entre los procesos que lo forman, y las decisiones se toman de forma colectiva, se dice que se trata de un grupo de iguales. En cambio, si se establecen relaciones de jerarquía en un grupo, donde unos procesos tienen una mayor capacidad de decisión que otros, se habla de grupos jerárquicos. Cada una de estas organizaciones grupales tiene sus ventajas y desventajas. En los grupos jerárquicos, si fallan los procesos que toman decisiones, se puede producir una descoordinación del resto de los miembros durante el tiempo que esta situación permanezca. En el grupo de iguales no se produce este efecto; si falla uno de sus miembros se podrá seguir trabajando (con un grupo más reducido). Figura 2.4: Grupos de iguales y grupos jerárquicos Cada grupo de procesos tiene asociada una membresía que define su composición. Si esta membresía puede variar durante la ejecución de la aplicación, estamos hablando de grupos dinámicos, mientras que si su composición (o membresía) no varía, o sólo lo hace si falla alguno de sus miembros, se denominan como grupos estáticos. 2.5 Tolerancia a fallos http://www.iuma.ulpgc.es/users/lhdez/inves/pfcs/memoria-ivan/node2.html#SECTION00210000000000000000[20/02/2014 12:40:29 p.m.] 2. Estado del arte de los sistemas distribuidos Un sistema distribuido es una colección de nodos autónomos de computación que se pueden comunicar unos con otros y que colaboran en un objetivo o tarea común. Cuando un nodo falla o cuando el subsistema de comunicaciones que permite que los nodos se comuniquen falla, los nodos se han de adaptar a las nuevas condiciones, para que puedan seguir cooperando. En los sistemas tolerantes a fallo, [8] [9] [12] [14] [16] los fallos que se pueden tolerar son aquéllos que está previsto que pueden ocurrir. El primer paso necesario para que un sistema pueda recuperarse de un fallo, es detectarlo. El siguiente paso es llevar al sistema a un estado consistente, para ello, es necesario que las acciones realizadas antes del fallo mantengan la consistencia. La clave para tolerar fallos es la replicación, [8] [9] [12] [14] [16] es decir, que varios elementos del sistema puedan dar el mismo servicio. A continuación se definen los modelos de fallo más frecuentes en la literatura, y las soluciones para conseguir la tolerancia a fallos. 2.5.1 Semánticas de fallo Los sistemas de computación constan de multitud de componentes hardware y software que pueden fallar (debido a un error de diseño, al envejecimiento de los materiales o a un evento externo). En muchos sistemas, estos fallos pueden llegar a producir inconsistencias y, por lo tanto, la no disponibilidad del servicio que estaban ofreciendo. Existen sistemas que se diseñan para tolerar fallos. Estos sistemas (sistemas tolerantes a fallos) hacen transparente al usuario los modos de fallos previstos en el sistema. A continuación se hace una taxonomía de los modos de fallo: [9] Fallo de tipo crash. En este modo, el fallo de un proceso consiste en una parada prematura, es decir, un proceso actúa en el sistema correctamente y, en un momento dado, deja de estar operativo. Derivaciones de este modo de fallo son: Fallo silencioso. Cuando un proceso falla, deja de interactuar con el resto del sistema. Fallo parada. Cuando un proceso falla, avisa de ello a todos los procesos del sistema y luego se para. Fallo de omisión. Este modo contiene al fallo de tipo crash y, además, en él se contemplan omisiones en los mensajes que se envían o reciben. Es equivalente a decir que, además de fallar un proceso, el servicio de comunicación puede perder mensajes. Fallo de temporización. En los sistemas de tiempo real no sólo es importante que los resultados obtenidos sean correctos, sino que además deben haberse conseguido dentro de unos requisitos temporales. Un fallo de temporización, además de contener el modo de fallo de omisión, aparece cuando un proceso se ejecuta más rápida o lentamente de lo definido en su especificación. Si se asocia al servicio de comunicación, es equivalente a decir que la red transporta los mensajes más rápida o más lentamente de lo que dice su especificación. Fallo arbitrario. También conocido como fallo bizantino o malicioso, es un modo de fallo que define un comportamiento no determinista de los procesos. En este modo se engloban todos los modos de fallo anteriores. Los elementos del sistema pueden no respetar su especificación en cualquier momento. Cuando se quiere construir un sistema tolerante a fallos, habitualmente se consideran dos alternativas. La primera consiste en ejecutar sistemas software sobre hardware especializado tolerante a fallos (CPU y memoria principal replicadas, discos espejo, varios buses y rutas de datos, entre otros.) pero; debido a razones económicas, fundamentalmente, la segunda aproximación está ganando impulso y es la de usar hardware estándar para soportar tolerancia a fallos, replicando ese hardware y manteniendo esa http://www.iuma.ulpgc.es/users/lhdez/inves/pfcs/memoria-ivan/node2.html#SECTION00210000000000000000[20/02/2014 12:40:29 p.m.] 2. Estado del arte de los sistemas distribuidos replicación a nivel software. De esta forma se consigue un sistema distribuido tolerante a fallos. Los protocolos que gestionan las réplicas pueden dividirse en dos clases: los que usan replicación activa y los que siguen el modelo de primario y respaldo. 2.5.2 Replicación activa La replicación activa (conocida también como replicación mediante máquina de estados) [9] [14] es un método general para construir un sistema tolerante a fallos mediante la replicación de sus elementos y la coordinación de las comunicaciones entre ellos. Una máquina de estados está compuesta por un conjunto de variables (estado) y un conjunto de operaciones que modifican o consultan el valor de esas variables. Cada operación se realiza mediante un programa determinista, [9] y su funcionamiento es atómico repecto al de otras. Las operaciones también producir resultados de salida. Cuando un cliente quiere ejecutar un servicio de la máquina de estados, le hace una petición, indicando qué operación debe ejecutar. El resultado puede ser la activación de un actuador o la respuesta a algún cliente que la estaba esperando. Es necesario también que las peticiones que recibe una máquina de estados sean atendidas de una en una, en un orden que ha de ser consistente con la causalidad potencial entre ellas. La propiedad fundamental que caracteriza una máquina de estados es que los resultados de salida que produce están completamente determinados por la secuencia de peticiones que recibe, con independencia del momento en que las recibe y de cualquier otra actividad del sistema. Una gran ventaja de este enfoque consiste en que casi cualquier sistema puede descomponerse en clientes y máquinas de estados, por lo que puede ser utilizado en gran parte de los casos. Para conseguir una versión tolerante a t fallos de una máquina de estados podemos replicarla, colocando cada réplica en un nodo diferente de la red. Si todas las réplicas comienzan en el mismo estado, y reciben la misma secuencia de peticiones, todas harán lo mismo, y producirán los mismos resultados. El número de réplicas que son necesarias para tolerar t fallos depende del modelo de fallo que se considere. Si son fallos bizantinos, hacen falta como mínimo 2t + 1, y para obtener resultados correctos basta con tomar los que producen la mayoría de las réplicas. Si se considera que sólo puede haber falloparada, basta con t + 1 réplicas. En otras palabras, la clave para conseguir máquinas de estados replicadas tolerantes a fallos está en garantizar la coordinación entre las réplicas (todas reciben y procesan la misma secuencia de peticiones). Este requisito puede a su vez descomponerse en dos: concenso [9] [14] (todas las réplicas correctas reciben el mismo conjunto de peticiones) y orden [9] [14] (todas las réplicas correctas procesan las peticiones que reciben en el mismo orden). Los algoritmos de comunicación que satisfacen el requisito de acuerdo (concenso) deben conseguir que un emisor pueda enviar un mensaje a los receptores cumpliendo dos condiciones: todos los receptores correctos están de acuerdo en el mensaje que reciben y, si el emisor es correcto, lo que cada receptor correcto recibe es lo que envió el emisor. Los que garantizan estas dos condiciones se llaman protocolos de radiado fiables, protocolos de acuerdo bizantino o, simplemente, protocolos de concenso [5] [9] [13]. El requisito de orden suele satisfacerse añadiendo información de orden a los mensajes. Esta información puede ser añadida por uno de los receptores (que luego la distribuye a los demás), o por los emisores, mediante el uso de algún tipo de reloj lógico (generalmente, combinado con cierto acuerdo entre los receptores). Consideremos un objeto x, y la invocación de la operación [x op(arg) ] por parte del cliente (Figura 2.5): http://www.iuma.ulpgc.es/users/lhdez/inves/pfcs/memoria-ivan/node2.html#SECTION00210000000000000000[20/02/2014 12:40:29 p.m.] 2. Estado del arte de los sistemas distribuidos 1. La petición se envía a todas las réplicas de x. 2. Cada réplica procesa la petición, actualiza su estado, y envía la respuesta [x ok(res) ] al cliente . 3. El cliente espera hasta que recibe la primera respuesta, o hasta que recibe todas las respuestas. Si las réplicas no se comportan de manera maliciosa (es decir, no se producen fallos bizantinos), entonces el proceso cliente espera sólo por la primera respuesta. En caso contrario, será necesario disponer al menos de 2f + 1 réplicas para tolerar hasta f posibles fallos. En esta situación, el cliente espera a recibir sólo f + 1 respuestas idénticas. Figura 2.5: Replicación activa 2.5.3 Replicación mediante primario y respaldos En los sistemas que usan este enfoque para lograr tolerancia a fallos, los emisores envían mensajes sólo al proceso marcado como primario. Si éste falla, uno de los respaldos toma su lugar. Los clientes deben darse cuenta de estas caídas y actualizar el primario para poder enviar sus mensajes al proceso adecuado. Más formalmente, para que un protocolo pueda ser considerado del tipo primario-respaldos, deben cumplir las siguientes condiciones: [8] [9] [14] [16] Existe un predicado que se puede aplicar al estado de cada servidor. En cualquier momento, como mucho un servidor satisface ese predicado. El que lo satisface es denominado primario. Todo cliente mantiene información sobre la identidad de un servidor, al que realiza sus peticiones. Este servidor, si es el primario, encola las peticiones y las atiende de una en una. Si una petición llega a un servidor que no es el primario, se descarta. El servicio replicado aparece, en su conjunto, como un servidor que, en el peor de los casos, no responde durante un número limitado de períodos finitos de tiempo. Las tres primeras propiedades definen cómo debe ser el protocolo entre los clientes y el servicio y la cuarta indica en qué condiciones el servicio debe satisfacer las peticiones. Consideremos una vez más la invocación de la operación [x op(arg) ] por parte del cliente . En ausencia de fallo del servidor primario, la petición se maneja de la siguiente forma (Figura 2.6): 1. El proceso 2. envía la petición x op(arg) a la réplica primaria . recibe y ejecuta la petición. Una vez ejecutada la operación solicitada, envía a las réplicas de respaldo la petición que se recibió del cliente para que éstas actualicen su estado. http://www.iuma.ulpgc.es/users/lhdez/inves/pfcs/memoria-ivan/node2.html#SECTION00210000000000000000[20/02/2014 12:40:29 p.m.] 2. Estado del arte de los sistemas distribuidos 3. Cuando al cliente recibe un reconocimiento desde todos los servidores de reserva, la respuesta es enviada . Figura 2.6: Replicación pasiva 2.6 Herramientas para comunicación en grupo La comunicación en grupo asume un papel importantísimo a la hora de crear sistemas distribuidos tolerantes a fallos. Ello es así puesto que para poder ofrecer tolerancia a fallos a una aplicación determinada, no es suficiente con replicar dicha aplicación, sino que además es necesario disponer de un sistema que facilite la comunicación entre tales réplicas. [3] [5] [6] [7] [9] [15] En un modelo de comunicación con grupos dinámicos, los procesos podrán unirse o abandonar el grupo cuando lo deseen, haciendo que la membresía pueda cambiar a lo largo del tiempo. Al conjunto de procesos que forman parte de un grupo se le conoce con el nombre de vista. Existirá por tanto un servicio de membresía que se ocupará de mantener actualizada la vista en cada uno de los miembros del grupo. Las herramientas software para comunicación con grupos utilizan una arquitectura conocida con el nombre de 3T (three-tier). En este modelo los clientes (client-tier) interactuan con una capa intermedia (middle-tier) que se encarga de enviar las peticiones a los servidores replicados (end-tier), manteniendo en todo momento la consistencia. Para lograrlo, la capa intermedia anida dos componentes básicos, el secuenciador y el manejador de replicación activa, que se encargan de garantizar que todas las réplicas reciben y ejecutan las peticiones de los clientes en el mismo orden en que fueron enviadas. Las herramientas para comunicación con grupos [3] [5] [6] [7] [9] [15] proporcionan un conjunto de servicios y primitivas que ayudan a los desarrolladores a construir sistemas de alta disponibilidad utilizando replicación software. En un sistema de este tipo se distinguen dos bloques fundamentales, (i) la API y (ii) el núcleo del sistema (figura 2.7). http://www.iuma.ulpgc.es/users/lhdez/inves/pfcs/memoria-ivan/node2.html#SECTION00210000000000000000[20/02/2014 12:40:29 p.m.] 2. Estado del arte de los sistemas distribuidos Figura 2.7: Arquitectura de las herramientas para comunicación de grupo El primer bloque lo constituye un conjunto de interfaces que permiten a la aplicación utilizar los servicios ofrecidos por la herramienta para comunicación de grupo; el segundo bloque implementa tales servicios. Ambos bloques pueden ser implementados usando diferentes lenguajes de programación. En caso de considerar herramientas de comunicación con grupos escritas en Java, es importante tener en cuenta como puede afectar al rendimiento la localización de la Máquina Virtual (JVM). Si sólo la API está escrita en Java, entonces la JVM estará ubicada bajo este bloque, permitiendo al núcleo intercambiar mensajes a través de la red utilizando llamadas nativas al sistema. Por el contrario, si el núcleo también está escrito en Java, la comunicación con la red habrá de realizarse a través de la JVM, lo cuál puede afectar negativamente al rendimiento. Otro factor importante a la hora de elegir una herramienta de comunicación con grupos es su capacidad para adaptarse a las necesidades del usuario, pudiendo tener sistemas monolíticos y sistemas modulares. En un sistema monolítico no se permite al usuario adaptar el sistema, sin embargo, en un sistema modular el usuario es libre para adapar el sistema a sus necesidades configurando la pila de protocolos de la forma que considere más oportuna. 2.6.1 Sistemas Monolíticos De entre los sistemas monolíticos más conocidos se han elegido para su presentación Isis, Phoenix, RMP, Totem y Spread. 2.6.1.1 Isis Isis [15] fué el primer sistema propuesto para comunicación en grupo (figura 2.8). Las capas principales que constituyen este sistema son: La capa Membership es la responsable de mantener la membresía de grupo. Maneja las peticiones de unión al grupo (joins) y las peticiones para abandonar el grupo (leaves). Además, excluye de la membresía todos aquellos procesos sospechosos de haber fallado. La capa de membresía de grupo (Membership) necesita ser extendida con una capa (View Synchrony) que ofrezca la posibilidad de radiar los mensajes a los miembros del grupo. Finalmente, la capa Atomic Broadcast asegura que los mensajes son entregados en el mismo orden por todos los procesos. 2.6.1.2 Phoenix Phoenix [15] es una variación de la arquitectura de Isis (figura 2.8). Los servicios de membresía (Membership) y sincronía de vistas (View Synchrony) se agrupan en una sola capa, al tiempo que se http://www.iuma.ulpgc.es/users/lhdez/inves/pfcs/memoria-ivan/node2.html#SECTION00210000000000000000[20/02/2014 12:40:29 p.m.] 2. Estado del arte de los sistemas distribuidos introduce una nueva capa base para resolver el problema del concenso (Concensus). La principal limitación de Isis era proporcionar el servicio de membresía al nivel de procesador. En caso de particionado de la red, conducía al servicio a eliminar todos los procesos sobre los procesadores que no estaban en la partición primaria. Phoenix solventa este inconveniente al proporcionar el servicio de membresía a nivel de procesos, permitiendo la computación en todas las particiones. Figura 2.8: Arquitecturas ISIS y PHOENIX 2.6.1.3 RMP En RMP, [15] la capa de membresía está dividida en dos partes: membresía libre de fallos (Fault-free Membership) y membresía tolerante a fallos (Fault-tolerant Membership). (Figura 2.9) La membresía libre de fallos maneja los joins/leaves en ausencia de fallos usando la capa inferior (Atomic Broadcast). De esta forma se consigue asegurar la sincronía de las vistas, sin embargo, el protocolo de radiado atómico se bloquea en caso de que un proceso falle. Cuando esto ocurra, el papel de la capa de membresía tolerante a fallos es evitar este bloqueo excluyendo los procesos sospechosos de haber fallado. 2.6.1.4 Totem Totem [15] utiliza un algoritmo de radiado atómico basado en la rotación de un testigo. La ordenación total es proporcionada por la capa intermedia de la arquitectura que se muestra en la figura 2.9. El protocolo de membresía de la capa más baja, aparte de detectar fallos y gestionar vistas, recupera el testigo y los mensajes que no hayan podido ser entregados cuando ocurren fallos. La capa superior (Recovery) completa el servicio de membresía, asegurando la sincronía de las vistas. Figura 2.9: Arquitecturas RMP y Totem http://www.iuma.ulpgc.es/users/lhdez/inves/pfcs/memoria-ivan/node2.html#SECTION00210000000000000000[20/02/2014 12:40:29 p.m.] 2. Estado del arte de los sistemas distribuidos 2.6.1.5 Spread Spread [3] se basa en una arquitectura cliente-demonio (el demonio representa el núcleo del sistema). El cliente se conecta al demonio por medio de una API predefinida, y envia mensajes a otros miembros del grupo. La API y el núcleo residen en distintos procesos, que pueden estar ubicados en la misma o en distintas máquinas. El demonio está escrito en C, mientras que la API está disponible en C++, Java y otros lenguajes. 2.6.2 Sistemas Modulares Respecto a los sistemas modulares, se describen las características de Maestro/Ensamble, Appia y JavaGroups. 2.6.2.1 Maestro/Ensamble Ensemble [3] esta basado en el concepto de pila de protocolos adaptable con objeto de solventar la degradación en el rendimiento que ofrecen los sistemas monolíticos. A su vez, Maestro [3] es una interfaz para Ensemble escrito en C++. Ejecuta Ensemble en un hilo separado, haciendo que tanto la API como el núcleo residan en el mismo proceso, compartiendo el mismo espacio de direcciones. 2.6.2.2 Appia Al igual que Ensemble, Appia [3] se basa en el concepto de pila de protocolos adaptable, pero a diferencia de Ensemble, permite no sólo utilizar los protocolos que mejor se adapten a las necesidades del usuario sino también añadir protocolos adicionales y eventos para comunicación entre los mismos. No hay una separación clara entre la API y el núcleo del sistema, estando ambos escritos completamente en Java. 2.6.2.3 JavaGroups JavaGroups es una herramienta escrita completamete en Java (con objeto de explotar al máximo los beneficios de este lenguaje). Se puede considerar como API, puesto que es facilmente integrable con cualquier otra herramienta para comunicación en grupo. Tanto la aplicación como el núcleo se ejecutan en el mismo proceso. 2.6.3 Comparativa En la figura 2.10 se muestra una comparativa de las distintas herramientas en base al lenguaje de programación que se utiliza, colocación de la JVM y diseño del núcleo. Figura 2.10: Clasificación de algunas herramientas de comunicación de grupo http://www.iuma.ulpgc.es/users/lhdez/inves/pfcs/memoria-ivan/node2.html#SECTION00210000000000000000[20/02/2014 12:40:29 p.m.] 2. Estado del arte de los sistemas distribuidos Siguiente: 3. JavaGroups como herramienta Subir: Memoria Proyecto Fin de Anterior: 1. Introducción Luis Hernandez 2004-09-28 http://www.iuma.ulpgc.es/users/lhdez/inves/pfcs/memoria-ivan/node2.html#SECTION00210000000000000000[20/02/2014 12:40:29 p.m.]