Subsecciones

2.4 SISTEMAS DISTRIBUIDOS

2.4.1 Concepto de sistema distribuido y sistema operativo distribuido

Un sistema distribuido es un conjunto de ordenadores o procesadores independientes que cara al usuario funcionan como uno solo. Está formado por varios componentes, relativamente pequeños e independientes, que cooperan estrechamente para dar un servicio único.

Un sistema operativo distribuido es el encargado de cumplir lo anterior. Hay un particionado y cooperación entre todos los componentes, ninguno sobrevive solo, el propio kernel está distribuido por las máquinas. El hardware no da ninguna facilidad, es el software el que determina que un sistema sea distribuido o no. El usuario no sabe dónde se están ejecutando los procesos ni dónde están los recursos. Llevar a la práctica la idea de un kernel global distribuido es muy difícil, pues podría haber inconsistencias de datos en el kernel, además se necesita al menos el kernel mínimo para enviar y recibir información y un mecanismo robusto de comunicación y eficiente para evitar latencias demasiado elevadas.

Lo que se han desarrollado hasta ahora son los llamados sistemas operativos en red. En estos sistemas cada máquina tiene su propio kernel. Los sistemas están conectados por una red y se puede hacer remote login en ellos, en todo momento el usuario sabe donde se encuentran todos los recursos (ficheros, procesos, etc.). No es un sistema distribuido por lo que no tiene las ventajas que se verán en el siguiente apartado.

Actualmente se está caminando desde los sistemas operativos en red a los sistemas distribuidos, aunque aún no se han cumplido los objetivos de un sistema distribuido completamente tenemos ya algunos avances. Por ejemplo ya hay grandes avances en sistemas de ficheros para conseguir que exista un solo directorio raíz al igual que la existencia de una ubicación automática por parte del sistema de los ficheros. Se puede implementar un balanceo de la capacidad y redundancia en los datos para minimizar el impacto de posibles caídas de nodos.

Un cluster openMosix ya implementa una migración de procesos, que a ojos del usuario es transparente. El cluster se usa como un gran computador donde se ejecutan los procesos en todos sus nodos. La ubicación de los procesos la elige el sistema operativo o el usuario, en un intento de balancear la carga.

2.4.2 Necesidad de sistemas distribuidos

En un sistema operativo distribuido se cumplen todas los criterios de transparencia, con todas las ventajas que esto supone. Aparte también se deben tener en consideración las siguientes características:
  1. Economía: la relación precio-rendimiento es mayor que en los sistemas centralizados sobretodo cuando lo que se busca son altas prestaciones.

  2. Velocidad: llega un momento en el que no se puede encontrar un sistema centralizado suficientemente potente, con los sistemas distribuidos siempre se podrá encontrar un sistema más potente uniendo más nodos. Se han hecho comparativas y los sistemas distribuidos especializados en cómputo han ganado a los mayores mainframes.

  3. Distribución de máquinas: podemos tener unas máquinas inherentemente distribuidas por el tipo de trabajo que realizan.

  4. Alta disponibilidad: cuando una máquina falla no tiene que caer todo el sistema sino que este se recupera de las caídas y sigue funcionando con quizás algo menos de velocidad.

  5. Escalabilidad: puede empezarse un cluster con unas pocas máquinas y según la carga aumenta, añadir más nodos. No hace falta tirar las máquinas antiguas ni inversiones iniciales elevadas para tener máquinas suficientemente potentes.
    Figura: Sistemas distribuidos. Escalabilidad de servicios en una empresa
    Image escalabilidad_servicios
  6. Comunicación: los ordenadores necesariamente estarán comunicados, para el correcto y eficaz funcionamiento del cluster se crean unas nuevas funcionalidades avanzadas de comunicación. Estas nuevas primitivas de comunicación pueden ser usadas por los programas y por los usuarios para mejorar sus comunicaciones con otras máquinas.

  7. Sistema de ficheros con raíz única: este sistema de ficheros hace que la administración sea más sencilla (no hay que administrar varios discos independientemente) y deja a cargo del sistema varias de las tareas.

  8. Capacidad de comunicación de procesos y de intercambio de datos universal: permite enviar señales a cualquier proceso del cluster, asimismo permite trabajar conjuntamente con cualquier proceso e intercambiar datos. Por lo tanto será posible tener todos los procesos trabajando en un mismo trabajo.

2.4.3 Desventajas: el problema de la transparencia

La principal desventaja de estos sistemas es la complejidad que implica su creación. Básicamente se tienen todos los problemas que se puedan tener en un nodo particular pero escalados. Vamos a ver los problemas que ocurren al intentar implantar las ventajas que hemos visto en el apartado anterior. Los puntos 1, 2 y 3 no tienen problemas de implantación porque son inherentes a los sistemas distribuidos. Como se expone en el anterior apartado otras de las ventajas de los sistemas distribuidos es que cumple con todos los criterios de transparencia. Pero conseguir estos criterios implica ciertos mecanismos que debemos implementar:
  1. Transparencia de acceso.

    Implica tener que mantener el viejo sistema para el nuevo cluster, por ejemplo mantener un árbol de directorios usual para manejar todos los dispositivos de almacenamiento del cluster. No tenemos que romper las APIs para introducir las nuevas funcionalidades.

  2. Transparencia de localización.

    A nivel más bajo tenemos que implantar una forma de conocer donde se encuentran los recursos, tradicionalmente se han usado servidores centralizados que lo sabían todo, ahora ya se va consiguie ndo que esta información se distribuya por la red.

  3. Transparencia de concurrencia.

    Esto que no es excesivamente complicado en un sistema local, se ha convertido en un quebradero de cabeza en un sistema distribuido. Se han desarrollado varios métodos para conseguirlo. El mayor problema es la desincronización de los relojes pues es muy complejo que todos los relojes hardware lleven exactamente la misma temporización por tanto algunos ordenadores ven los acontecimientos como futuros o pasados respecto a otros ordenadores. Este tema se tratará con más profundidad en el capítulo de sistemas operativos.

  4. Transparencia de replicación.

    Básicamente el problema es que el sistema sepa que esas réplicas están ahíy mantenerlas coherentes y sincronizadas. También tiene que activar los mecanismos necesarios cuando ocurra un error en un nodo.

  5. Transparencia de fallos.

    Aunque haya fallos el sistema seguirá funcionando. Las aplicaciones y los usuarios no sabrán nada de estos fallos o intentarán ser mínimamente afectados, como mucho, el sistema funcionará más lentamente. Este punto está muy relacionado con la transparencia de replicación.

  6. Transparencia de migración.

    Tenemos que solucionar problemas sobre las decisione s que tomamos para migrar un proceso, hay que tener en cuenta las políticas de migración, ubicación, etc. Además tenemos que ver otros aspectos prácticos como si al nodo que vamos encontraremos los recursos que necesitamos, etc. La aplicación no tiene que saber que fue migrada.

  7. Transparencia para los usuarios.

    Implica una buena capa de software que de una apariencia similar a capas inferiores distintas.

  8. Transparencia para programas.

    La más compleja. Implica que los programas no tienen porque usar llamadas al sistema nuevas para tener ventaja del cluster. Mosix hace esto muy inteligentemente tomando la natural división en procesos de los programas para migrarlos de forma transparentemente.

2.4.4 La tendencia a lo distribuido

Existen varios métodos para intentar distribuir a nivel de aplicación, son métodos que abstraen las capas inferiores y hacen la vida más fácil a los programadores de las aplicaciones, que no se tendrán que preocupar sobre las peculiaridades de las capas inferiores consiguiéndose una mayor efectividad en la programación. Las tecnologías que se verán, en este orden, son:

RPC: Remote Procedure Calls.
RMI: Remote Method Invocation.
CORBA: Estándar de comunicación de objetos.
Bonobo: Abstracción sobre CORBA de GNOME.
KDE: Desktop Enviroment. Veremos: KIO, XMLRPC, DCOP.
SOAP: Simple Object Access Protocol.

RPC.-

El concepto de RPC o llamada a procedimiento remoto ha sido explotado desde hace ya varias décadas, de hecho, existen varias implementaciones creadas por distintos grupos e incluso varios protocolos. El concepto de llamada a procedimiento remoto no es otra que la que su propio nombre indica, es decir, se pretende ejecutar funciones o procedimientos en otras máquinas distintas a la nuestra y que el resultado retorne a nuestra máquina, todo ello de manera transparente. Hasta aquí el concepto de llamada a procedimiento remoto parece bastante asequible. El problema surge como siempre a la hora de implementarlo, codificarlo y tener en cuenta consideraciones de sistema.

Para empezar se deben tener en cuenta cosas como que tipo de protocolo se va a utilizar en capas inferiores. Puede ser conectivo, perfecto para olvidarse de las retransmisiones y fallos o no conectivos y aprovechar al máximo la capacidad de la red. También hay que prestar atención al formato de representación entre distintas máquinas de un mismo sistema, como podrían ser ASCII, EBCDIC o Little Endian y Big Endian, y en otros muchos problemas que implican las llamadas a procedimientos remotos2.17.

Por último (como colofón de las pegas de los sistemas implementados de los RPC) está el que generalmente no son tan transparentes como debieran. En el caso ideal, se supone que, el programador no debe saber si los procedimientos de una biblioteca son locales o remotos, ni necesitar de ningún tipo de interface para poder llamar a dichos procedimientos. Esto no se cumple, no sólo en el caso de RPC, sino en prácticamente cualquier sistema distribuido.

El RPC por excelencia es el RPC diseñado e implementado por Sun Microsystems cuya versión 2 esta especificada y tipificada en el RFC 1831. En esta RFC se puede leer no sólo el modelo de llamada a procedimiento remoto, sino también ejemplos de programación de RPC, semánticas de transporte, sistema de autenticación y modelo de programación en general de esta implementación. Dicha implementación utiliza como modelo de comunicación IP/UDP ya que la mayoría de las aplicaciones suelen estar en una LAN y por tanto se obtiene más efectividad que con TCP. Se utiliza también XDR para hacer compatible entre varios formatos de representación. Los programas requieren de librerías y funciones especiales y al mismo tiempo se requiere rpcportmapper instalado como demonio para efectuar las transacciones. Existen varias referencias acerca de como podría implementarse un sistema distribuido de este tipo en el libro Sistemas Operativos Distribuidos de Andrew S. Tanembaum.

¿Por qué no utilizar RPC en sistemas distribuidos o clusters? Existen diversas causas, unas con más peso que otras. Por norma general el modelo RPC suele ser bastante lento a pesar de utilizar UDP, por ejemplo en lo que se refiere al checksum, cambio de referencias en memoria, traducción XDR, rellenado de cabeceras y otras tantas operaciones que hacen que dicho sistema sea compatible en un entorno de trabajo hetereogéneo.

Es decir, en entornos de trabajo en los cuales no se requiere de confiabilidad, autenticación (y seguridad en general), eficiencia, y consistencia; la solución RPC es aceptable. En el caso de los clusters, suele implementarse con unos requerimientos de sistema bastante exigentes en lo que se requiere a eficiencia, y es mejor considerada una macro en el programa que utilizar todo un sistema como puede ser XDR. Generalmente los sistemas distribuidos suelen basar su desarrollo en nuevas implementaciones o modelos, que no tienen por que ser el de RPC, y no utilizan RPC debido a la poca eficiencia que este reporta y a la mala fama en seguridad que este posee.




RMI.-

También desarrollado por Sun para Java, mucha gente considera a RMI el sucesor de RPC.

RMI es un concepto confuso, tiene dos aceptaciones:

RMI es un mecanismo que permite invocar un método de un objeto que no existe en el espacio de direccionamiento de la propia aplicación, este otro espacio de direcciones puede encontrarse en la propia máquina o en otra diferente. Básicamente podemos aplicar lo explicado en RPC pero teniendo en cuenta que este mecanismo es orientado a objetos. Comparando con el siguiente punto CORBA, aunque básicamente ambos métodos son un RPC para lenguajes orientados a objetos, CORBA es un estandard e independiente del lenguaje, RMI sólo es para Java. CORBA incluye muchos otros mecanismos en su estándar (lo que le hace ser una implementación más lenta y pesada) que no son parte de RMI. Tampoco existe el concepto de ORB (Object Request Broker) en RMI. Java RMI ha estado evolucionando y convirtiéndose en más compatible con CORBA, en particular hay ahora una nueva forma de RMI llamada RMI/IIOP (RMI sobre IIOP) que usa IIOP (Internet Inter-ORB Protocol de CORBA como protocolo de bajo nivel para las comunicaciones RMI. Por supuesto podemos imaginar las consecuencias para el rendimiento.

Hay 3 procesos que participan en que la invocación de métodos remotos se haga efectiva:

Hay dos tipos de clases que pueden ser usadas en Java RMI.




CORBA.-

Es un estándar desarrollado por una fundación creada por distintas empresas llamada OMG (Object Management Group) para poder hacer fácilmente programación distribuida, reutilización de objetos y de código ya hecho. CORBA cumple correctamente estos objetivos, para ello la estructura de CORBA cuenta de un lenguaje estandar llamado IDL (Interfaz Definition Language) que sirve para determinar los interfaces entre objetos, la implementación de los objetos se hace con cualquier lenguaje que tenga un compilador capaz de enlazar IDL.

CORBA es un middleware entre el sistema operativo y las aplicaciones usuario, entre ese middleware se encuentra el ORB encargado de hacer las llamadas entre objetos. En resumidas cuentas, CORBA es un nivel más de abstracción.

-- Ventajas:

--Desventajas:

Aunque haya más ventajas que inconvenientes estos últimos son más relevantes puesto que no podemos suponer que los procesos con los que trabajemos vayan a estar desarrollados en CORBA, además CORBA no nos soluciona el problema de migrar procesos y si lo hiciera sería extremadamente lento.

Aún se podría pensar en usar CORBA para envío de mensajes, pero la sobrecarga que genera no merece la pena. CORBA es muy potente para aplicaciones distribuidas o no de nueva creación y seguramente se le pudieran añadir funciones de balanceo de carga, pero para que nuestra solución sea más general es preferible no usar CORBA y tratar todo a nivel de proceso, sin abstracciones mayores. Aunque el estándar CORBA no añade estas capacidades de balanceo, implementación es específicas si que tienen reconfiguración dinámica, por ejemplo, Dinamic TAO.




Bonobo.-

Abstracción por encima de CORBA desarrollada por el proyecto GNOME.

Bonobo es un conjunto de interfaces CORBA, algunos implementados por objetos contenedores y otros por los objetos que serán contenidos (por ejemplo cuando pulsamos sobre un pdf y este se abre en nuestro propio navegador, el navegador es el contenedor y el programa lector de pdf el contenido). Bonobo es también una implementación por defecto de estos interfaces CORBA que es exportado en forma de API C para evitar a la mayoría de los programadores de preocuparse por tener que codificar directamente los interfaces CORBA.

Aunque no lo hemos mostrado en el punto anterior la programación en CORBA es ciertamente compleja, por tanto dentro del esfuerzo del proyecto GNOME para incorporar CORBA se ha desarrollado una librería de un nivel más alto llamada Bonobo (el nombre es de ciertos monos en vías de extinción que sirven para ilustrar la teoría de conexión de componentes). Otro de estos desarrollos fue ORBit que es un ORB pero con la particularidad de estar altamente mejorado en velocidad, siendo el más rápido existente (casi el doble que su más cercano competidor Omniorb) y de los que menos memoria necesita.

A parte de ORBit tenemos Gnorba que facilita en algo algunas tareas de ORBit y es más específico de GNOME, por ejemplo permite la integración del bucle principal de ORBit con el bucle principal de Gtk+, añade seguridad a las comunicaciones y un método estándar para acceder al servicio de nombres de GNOME. Para permitir acceso a un objeto en concreto se dispone la información en GOAD (GNOME Object Activation Directory) donde tenemos el id del objeto, las interfaces que exporta y como crear un ejemplar, gracias a esto se pueden usar métodos a través de la red.

Bonobo se creó para intentar mantener las aplicaciones con poca complejidad para que a los nuevos programadores les cueste poco saber cómo funciona el código y sea más fácil el mantenimiento y desarrollo. Usando todas las facilidades de CORBA que es usado para la capa de comunicación y para unir todos los componentes Bonobo entre sí. Cada componente tiene su interfaz (definido en términos de las interfaces CORBA) que exporta, ahíes donde cualquier otro componente puede conseguir información o unirse al componente.

El interface CORBA se introduce en un objeto GTK+, esto quiere decir que los objetos GTK+ son la implementación del interface IDL. Las implementaciones contienen ciertas acciones por defecto para no molestar al programador con detalles de CORBA, pero se dan unos métodos para cambiar este comportamiento.




KDE.-

En este apartado vamos a ver tres tecnologías que utiliza KDE a partir de sus versiones 2.0 y posteriores:

  1. KIO: entrada y salida , transparencia de red.
  2. XML-RPC: manejo de programas remotamente.
  3. DCOP: comunicación entre componentes Kparts.

Estas tres tecnologías permiten acercarnos a un proceso distribuido y a una transparencia de red enormes. KDE es muy buen ejemplo de cómo se intenta cumplir algunos de los objetivos de los sistemas distribuidos, y cómo usuarios que somos de este entorno podemos decir que esta tecnología hace el día a día más sencillo.

SOAP.-

Hoy en día lo que se le pide a un sistema que use RPC o RMI es que sea confiable, robusto, que tenga APIs desarrolladas para varios lenguajes, interoperabilidad entre lenguajes, plataformas y modelos de componentes.

Desafortunadamente no hay un único sistema que tenga todas esas características. El formato de los datos y el protocolo usado para intercambiarlos es un factor determinante en el grado de interoperabilidad que pueden alcanzar las aplicaciones.

XML(eXtensible Markup Language) se está convirtiendo en un estandar para representar datos en un formato independiente de la plataforma. XML es un lenguaje fácil de general y de leer. HTTP (HyperText Transfer Protocol) también se está convirtiendo en un protocolo muy usado gracias a las aplicaciones web, que está soportado por todos los sistemas.

Las peticiones/respuesta de HTTP se pasan a través de firewall y son manejadas de forma segura, todo lo contrario que una ejecución de una llamada RPC o RMI.

Por lo tanto XML sobre HTTP parece una forma bastante inteligente para las aplicaciones distribuidas de comunicarse entre ellas. SOAP hace exactamente eso.

Representando RPCs de forma independiente a la plataforma, abre la posibilidad de implementar otros protocolos específicos de arquitectura en SOAP. Por ejemplo Microsoft parece querer usar SOAP como protocolo intermedio de intercambio al que otros protocolos pueden ser fácilmente traducidos, para potenciar el uso de sus componentes COM.

RPC en SOAP son interacciones cliente servidor sobre HTTP donde la petición/resp uesta se hacen de acuerdo con las reglas SOAP. Para elegir el objeto se usa el URI (Universal Resource Identifier) que es propio de HTTP o la cabecera SOAPAction que indica el nombre del interface. Se especifica una convención de la llamada remota , que determina la representa ción y el formato de las llamadas y respuestas. Una llamada es un dato compuesto con varios campos, uno por cada parámetro. Un mensaje de retorno es un valor de retorno y unos parámetros.


miKeL a.k.a.mc2 2004-09-06