Uploaded on

 

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
404
On Slideshare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
8
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Unidad 2 - La Comunicación en los Sistemas Distribuidos 2.1 comunicacion sod 2.1 Llamada a procedimiento remoto (RPC) En el anterior epígrafe hemos estudiado un modelo de interacción entre los procesos de un sistema distribuido que es el modelo cliente-servidor. Para implementarlo, el sistema dispone de dos llamadas al sistema, send y receive, que las aplicaciones utilizan de forma conveniente. Estas primitivas, a pesar de constituir la base de la construcción de los sistemas distribuidos, pertenecen a un nivel demasiado bajo como para programar de forma eficiente aplicaciones distribuidas. 2.1.1 La operación RPC básica La llamada a procedimiento remoto constituye un mecanismo que integra el concepto cliente-servidor con la programación convencional basada en llamadas a procedimientos. La idea surgió en 1984 y consiste en que el cliente se comunica con el servidor mediante una llamada ordinaria a un procedimiento. Esta llamada se denomina a procedimiento remoto porque el procedimiento invocado se encuentra en otro espacio de direccionamiento, en la misma o en distinta máquina que el cliente. La información se transporta en los parámetros de la llamada y el resultado es devuelto en el retorno de la llamada. El cliente no tiene que utilizar las primitivas send y receive como en el modelo cliente-servidor puro, de modo que la programación de aplicacio-nes distribuidas se hace más sencilla. 2.1.2 El paso de parámetros La función del cabo cliente es empaquetar los parámetros en un mensaje y enviarlo al cabo servidor. Este examina el código del procedimiento en una sentencia tipo switch e invoca el procedimiento de forma local. El resultado es de nuevo empaquetado en un mensaje y enviado al cabo cliente. Esta interacción, que parece directa, no es tan simple como aparenta ser. Mientras las arquitecturas del cliente y del servidor sean iguales no se presenta ningún problema especial. En un entorno distribuido, sin embargo, cada arquitectura tiene su propia representación de números, caracteres, etc. Por ejemplo, los mainframe IBM utilizan el código EBCDIC para los caracteres en lugar del código ASCII, como el IBM PC. Problemas similares ocurren con la representación de coma flotante o los enteros negativos (complemento a 1 o complemento a 2). Otro problema surge con la forma de almacenar un entero. La arquitectura PC mantiene una representación “little endian”, a saber, el byte menos significativo en el byte más bajo de memoria. La arquitectura SPARC utiliza un almacenamiento “big endian”, es decir, el byte más significativo en el byte más bajo de la memoria. Un 486 operando en modo protegido representa un entero con cuatro bytes, de modo que el 5 lo representa como 0005. Un mecanismo adicional de paso de parámetros es denominado de copia-restauración. Consiste en realizar una copia del parámetro en la pila. Si esta copia parámetro es modificada en el procedimiento, se restaura su nuevo valor a la variable original. Algunos compiladores de Ada utilizan este mecanismo en parámetros in out, si bien ello no está especificado en la definición del lenguaje. La estrategia de copia con restauración puede ser utilizada para pasar punteros a procedimientos remotos. Supongamos la invocación del procedimiento remoto cuenta = read(df, buf, nbytes); La implementación más directa consiste en copiar al buffer del mensaje local un vector de “nbytes” caracteres en lugar de buf, que es la referencia al vector. El mensaje es entonces enviado al cabo servidor. Ahora el buffer del mensaje se encuentra en el espacio de direccionamiento de este último, invocará la rutina de servicio read con la referencia al
  • 2. vector recibido en el mensaje, es decir de forma convencional por referencia. Ahora el mensaje es devuelto con su contenido actualizado a la rutina cabo del cliente, que restaura el vector del mensaje a su vector original. Para optimizar este mecanismo eludimos en el cabo cliente la copia del vector al mensaje en caso de lectura. En el caso de la escritura, prescindiremos de restaurarlo. Como vemos, es posible pasar punteros a procedimientos remotos siempre que sean referencias a estructuras sencillas como vectores. No obstante, no podemos enviar a procedimientos remotos referencias a estructuras de datos complejas como listas o árboles. 2.1.3 Especificación de interfase El servidor RPC puede ser considerado como un módulo u objeto que implementa unas operacio-nes sobre datos ocultos. El servidor da a conocer estas operaciones a los clientes mediante lo que se denomina su interface, constituida por las declaraciones de los métodos que soporta. Como sabemos, el objetivo del mecanismo RPC es lograr que un programa tenga acceso a los servicios de uno de estos módulos, aunque residan en otro espacio de direccionamiento, posiblemente remoto. La figura 2.8 muestra los componentes de una implementación RPC. La mitad rayada constituye el software adicional de empaquetamiento y desempaquetamiento de parámetros y primitivas de comunicación que debe ser ocultado al programador. Por brillante que sea la idea de la interacción cliente-servidor a través de RPC, si el programador debe encarar la construcción de los cabos, el progreso de los sistemas distribuidos se verá comprometido por la falta de uso en la práctica. Es preciso que la generación de cabos en el cliente y el servidor se realice de forma automática. Pues bien, la interfaz del servidor se utiliza como la base de esta generación automática de cabos. El primer paso es definir el interfaz, es decir, el conjunto de los prototipos de los procedimientos de servicio, mediante un lenguaje determinado, denominado lenguaje de interfase. La figura 2.8, a) muestra un ejemplo de servidor. La figura 2.8, b) su definición de interfaz. Un compilador especial toma como entrada el fichero escrito en el lenguaje de interfase y como salida genera el código objeto de los procedimientos que constituyen el cabo cliente, por una parte, y el cabo servidor, por la otra. El programa cliente se enlaza con estos procedimientos objeto para generar el ejecutable. En cuanto al servidor, los procedimientos de servicio, escritos por el programador, se compilan previamente a lenguaje objeto y, a continuación, se enlazan con los procedimientos cabo, entre los que figura el procedimiento principal del servidor RPC. 1. include <header.h> void main(void) { struct mensaje m1, m2; /* Mensajes entrante y saliente */ int r; while(1) { receive(FILE_SERVER, &m1); /* El servidor se bloquea esperando un mensaje */ switch(m1.opcode) { case CREATE: r = do_create(&m1, &m2); break; case READ: r = do_read(&m1, &m2); break; case WRITE: r = do_write(&m1, &m2); break; case DELETE: r = do_delete(&m1, &m2); break; case DELETE: r = E_BAD_OP; break; } m2.result = r; send(m1.source, &m2); }
  • 3. } a) 1. include <header.h> specification of file_server, version 3.1 long read(in char name[MAX_PATH], out char buf[BUF_SIZE], in long bytes, in long position); long write(in char name[MAX_PATH], in char buf[BUF_SIZE], in long bytes, in long position); int create(in char[MAX_PATH], in int mode); int delete(in char[MAX_PATH]); end; b) 2.1.4 Enlace dinámico No es conveniente que un servicio esté ligado a una máquina. A veces las máquinas no están operativas, de modo que los servicios se mueven a otra máquina. El cliente está interesado en el servicio, no en qué máquina ejecuta el servidor. Para solicitar un servicio, un cliente podría enviar un mensaje en una sentencia como la siguiente send(33.33.33.33@20, &mens); en el código fuente que implementa la llamada RPC. Esta solución es inflexible, puesto que, si dentro de la máquina 33.33.33.33 el servidor pasa a escuchar en otro puerto distinto del 20, el cliente debe ser recompilado. Lo mismo ocurre si el servidor cambia de máquina. En contraste, el cliente debería invocar el servicio por su nombre, sin hacer referencia a dirección alguna. La figura 2.8 b) muestra la especificación formal del servidor de ficheros 2.8 a). En la especificación formal del servidor intervienen el nombre del servidor y su número de versión. Ambos datos identifican un servidor. Un servidor con el mismo nombre y la misma versión, no obstante, pueden estar replicados en dos o más máquinas a fin de mejorar el servicio o propor-cionar tolerancia a fallos. El cliente debe solicitar un servicio invocando su nombre y versión, sin citar dirección alguna. El número de versión es conveniente a fin de que un servidor que evoluciona conserve su nombre. Un servidor puede evolucionar ofertando nuevos servicios, cancelando otros y modificando otros. A pesar de esta evolución, es preciso que clientes antiguos, desconocedores de los cambios, sigan obteniendo el mismo tipo de servicio. Es preciso compren-der, no obstante, que un servidor con el mismo nombre pero con número de versión distinto es un servidor diferente. Las ventajas de identificar al servidor por su nombre son evidentes, pero, ¿cómo el cliente localiza al servidor? ¿Quién le proporciona su dirección? Este es un problema al que algunos sistemas RPC, entre ellos Sun RPC, dan respuesta mediante lo que se llama el enlace dinámico, que no es sino averiguar la dirección del servidor en tiempo de ejecución. El enlace dinámico está basado en un tercer proceso denominado el enlazador. Cuando el servidor arranca, en su código de inicialización previo al bucle principal, envía un mensaje al enlazador a fin de registrarse como un proceso que presta un servicio. El enlazador es, al fin y al cabo, un registrador de servicios, un servidor de nombres. El servidor entrega su nombre, su número de versión y su dirección. Se dice que el servidor exporta su interfaz. No sería extraño que dos programadores diesen el mismo nombre a dos servidores distintos, de modo que, a pesar de que no aparezca, cada servidor RPC tiene asociado, además del nombre y la versión, un identificador numérico, generalmente de 32 bits, que también entrega en la operación de registro. Dos servidores distintos deben tener identificadores distintos (se entiende aquí servidor como programa, no como proceso). Si bien sería raro, es posible que dos programadores que terminan dos
  • 4. servidores RPC, coincidan en darles el mismo identificador. Lo que ocurra cuando ambos traten de registrarse depende de cada implementación particular del software RPC, pero es lógico pensar que el enlazador rechazaría la segunda petición de registro. 2.1.5 Semántica RPC en presencia de fallos El objetivo de la llamada a procedimiento remoto es conseguir la ejecución de procedimientos en otras máquinas sin cambiar la forma en que se invoca el procedimiento en el código fuente. Salvo algunas excepciones como que un procedimiento remoto no puede usar variables globales, el objetivo ha sido alcanzado plenamente. Mientras no se produzcan errores la transparencia de la llamada remota está conseguida, ya que el programador no necesita saber que la llamada que realiza es a un procedimiento remoto. Los problemas llegan cuando bien cliente o bien servidor dejan de operar correctamente, ya que las diferencias entre llamadas locales y remotas no son fáciles de enmascarar. Vamos a considerar cinco situaciones de fallo: 1. El cliente no es capaz de localizar al servidor. 2. El mensaje del cliente al servidor se pierde. 3. El mensaje de réplica de servidor a cliente se pierde. 4. El servidor se cae tras recibir el mensaje del cliente. 5. El cliente se cae tras recibir la réplica. El cliente no puede localizar al servidor Puede haber varias causas. Una es que el servidor se cae. Otra es que el servidor se actualiza y un cliente antiguo invoca una versión del servidor que ya no ejecuta. Una solución es que la llamada devuelva −1 como código de error. Sin embargo, −1 puede ser un resultado válido como en la llamada RPC de suma. Otro intento de solución es escribir un manejador de excepción (señales en C) para los errores producidos en las llamadas RPC. Sin embargo, esta solución acaba con la transparencia respecto a las llamadas locales. Lo mejor es recibir el resultado en parámetros de salida de la llamada RPC y que esta devuelva 0 en caso de ejecución con éxito y un código de error en otro caso. La petición del cliente se pierde Este caso tiene un tratamiento sencillo. El núcleo del cliente arranca un temporizador cuando envía el mensaje al servidor. Si al cabo de un plazo no ha llegado réplica o reconocimiento del servidor, el cliente da el mensaje por perdido y lo reenvía. Si todos los reenvíos se pierden, el kernel del cliente considera que el servidor no está activo y devuelve un error al cabo cliente, que lo pasa a la aplicación. Estamos en el caso anterior. La réplica del servidor se pierde Este problema es más complejo. Cuando en el caso anterior venció el plazo sin que llegase la respuesta del servidor, asumimos que se había perdido el mensaje enviado por el cliente. Pero existe la posibilidad de que el mensaje perdido fuese la réplica. De cualquier forma, establecimos que lo que había que hacer era el reenvío del mensaje. En el primer caso, el servidor recibe el mensaje reenviado por primera vez. Todo vuelve a funcionar correctamente. En el segundo caso el servidor recibe el mensaje por segunda vez. Sirve la petición dos veces, como si en el programa cliente hubiésemos invocado la llamada una segunda vez. En algunos casos, la repetición de una operación en el servidor no causa ningún daño. Por ejemplo, el leer los 20 primeros bytes de un fichero. Las peticiones que tienen esta propiedad se dicen que son idempotentes. Otras veces, la re-petición sí ocasiona perjuicios, como puede ser el añadir 20 bytes a ese fichero o retirar de una cuenta bancaria 500 millones de pesetas. La solución a este problema pasa por numerar las peticiones. Las retransmisiones llevan el mismo número de secuencia que la transmisión original. Entonces el kernel del servidor detecta que la réplica se ha perdido y la reenvía, sin operar sobre el servidor. Una versión distinta de esta solución es introducir en la cabecera de la petición un bit de retransmisión. El servidor se cae La figura 2.10 a) muestra la secuencia de eventos producidos en un servidor en el servicio de una petición. El sistema operativo del servidor recibe el paquete entrante con el mensaje, que entrega al cabo para que invoque la ejecución del procedimiento que sirve la petición. A continuación, el cabo pasa la réplica al sistema operativo que lo envía en un paquete al cliente. Ahora bien, tras haberse ejecutado el procedimiento de servicio, el servidor puede sufrir una caída que impide la emisión de la réplica al cliente. Es el caso b) de la figura. Por el contrario, la caída puede producirse tras la recepción del paquete, pero previamente a la ejecución del procedimiento de servicio. Es el caso c).
  • 5. Las consecuencias de los casos b) y c) es diferente. Supongamos que la operación remota es escribir un texto en la impresora. El servidor primero carga el texto en la memoria interna de la impresora y después escribe en un registro de la misma para iniciar la impresión. El servidor puede caerse antes de establecer el bit o después de establecer el bit. En el primer caso, la operación no será realizada. En el segundo caso, sí, ya que la impresora continúa su trabajo con independencia de que el servidor esté activo o no lo esté. Podemos pensar que este caso tiene la misma complejidad que la pérdida de la réplica, examina-da en el caso anterior. No es así. La pérdida de la réplica supone un reenvío de la solicitud de impresión. El núcleo del servidor se dará cuenta de que el mensaje tiene un número de secuencia repetido y enviará de nuevo la réplica si repetir la impresión. En contraste, la caída del servidor supone la pérdida del registro de los números de secuencia de mensajes del cliente. Por esta razón, tras un rearranque, el servidor no puede saber si la re-petición de impresión ha sido servida con anterioridad, de modo que volverá a ser servida. Si la caída se produjo en el caso c) la impresión no se hizo, de modo que reiniciar la operación es lo correcto. Sin embargo, si la caída se produjo en el caso b) reiniciar la operación supone repetirla. Lo peor del caso b) es que ni cliente ni servidor sabrán nunca si la operación se realizó con anterioridad o no. 2.1.6 Implementación de software RPC El éxito o el fracaso de un sistema operativo distribuido radica en sus prestaciones. Si un sistema es lento, no tiene éxito. Las prestaciones de un sistema operativo distribuido radican en gran parte en la velocidad de las comunicaciones, y esta velocidad depende fundamentalmente de la implementación del protocolo de comunicación más que en sus principios abstractos. En esta sección vamos a discutir la implementación de software RPC. Protocolos RPC En los sistemas comerciales actuales, el software RPC está implementado como una biblioteca de funciones que el programa de usuario invoca. Tanto el cabo cliente como el cabo servidor no son sino un conjunto de llamadas a funciones de la biblioteca RPC. Veamos el ejemplo de Sun RPC. El siguiente mandato UNIX es el que se utiliza para compilar el programa cliente rdate de la figura 2.9. # cc -o rdate rdate.c date_clnt.c -lrpclib donde se aprecia el enlace de la biblioteca de Sun RPC, rpclib. El mandato para generar el servidor RPC es similar. La aplicación de usuario rdate invoca funciones RPC del cabo que, a su vez, invocan las llamadas al sistema de comunicaciones del sistema operativo para enviar los mensajes al servidor RPC. Así, el software RPC puede entenderse como un nivel de servicio entre cliente o servidor y el sistema operativo, tal como ilustra la figura 2.11. Generalmente, las llamadas al sistema de comunicaciones de los sistemas UNIX están implementadas mediante la pila de protocolos TCP/IP, que forman parte del núcleo de UNIX. IP es el protocolo de nivel de red (nivel tres en la pila OSI). TCP es uno de los protocolos de transporte de la pila TCP/IPTCP es un protocolo del nivel de transporte (nivel cuatro en la pila OSI), orientado a conexión. La comunicación entre dos procesos mediante conexión se basa en establecer un circuito virtual entre ambas máquinas antes del hacer envío alguno. El establecimiento de una conexión es costoso en tiempo y recursos, pero garantiza la fiabilidad total de la comunicación. 2.2 Comunicación de grupos La comunicación RPC tiene dos partes, una, el cliente, dos, el servidor. Hay situaciones en que este modelo no es el idóneo en un sistema con un conjunto de servidores de ficheros replicados a fin de proporcionar tolerancia a fallos. Un programa cliente que hace una escritura a disco debe hacer llegar la petición simultáneamente a todos los servidores y no a uno de ellos únicamente. El problema puede solucionarse invocando tantas llamadas RPC como servidores existentes. Existe, sin embargo, otro paradigma de comunicación disponible para los sistemas distribuidos que es la comunicación de grupos, más apropiado en casos como este. 2.2.1 Introducción a la comunicación de grupos
  • 6. La característica principal de un grupo de procesos es que cuando se envía un mensaje al grupo, todos sus componentes lo reciben. Por otra parte, los grupos son dinámicos. Los grupos nacen y mueren y en cada grupo terminan algunos procesos y se incorporan otros. Por lo tanto es necesario un mecanismo de gestión de grupos. Un proceso puede pertenecer a más de un grupo y abandonar un grupo para unirse a otro. Un grupo es una abstracción cuyo propósito es evitar, en las llamadas de comunicación con grupos de procesos, parámetros molestos como el número de elementos en el grupo o la localización de cada proceso del grupo y proporcionar primitivas más potentes y transparentes, como el ejemplo anterior de envío de un mensaje a un conjunto de servidores de ficheros. El cliente no debería saber cuantos servidores están disponibles en cada momento ni en qué máquinas concretas han sido arrancados. La implementación de grupos depende mucho del hardware de comunicación disponible. En algunas redes, como ethernet, existen unas direcciones especiales en las que pueden escuchar más de una máquina. Para ello es necesario configurar el adaptador de red ethernet en cada máquina. Un único marco o enviado a esta dirección es leído por todas las máquinas que escuchan en ella. Estas direcciones se denominan multicasting. Si el nivel de enlace de la red soporta multicasting, como es el caso de ethernet, la implementación de grupos es sencilla. Basta asignar a cada grupo una dirección multicasting diferente. Existen redes que si bien no admiten multicasting, sí admiten difusión. Marcos ethernet con la dirección de destino 111…111 son recibidos por todas las máquinas de la red. La difusión puede ser utilizada para implementar grupos, pero es menos eficiente, porque el marco se envía a todas las máquinas, tanto las que pertenecen al grupo como las que no. De todas formas, el envío al grupo de procesos requiere de un solo paquete. Si el nivel de enlace no proporciona multicasting ni difusión, aún es posible la implementación de grupos. Para ello, el emisor debe enviar un paquete particular a cada miembro del grupo. Por supuesto, esta es la implementación menos eficiente. 2.2.2 Aspectos de diseño La comunicación de grupos comparte muchos aspectos de la comunicación estándar de paso de mensajes, tales como primitivas con buffer o sin buffer, bloqueantes o no bloqueantes, etc. No obstante, existen más posibilidades adicionales a elegir en la comunicación de grupos. En esta sección examinamos algunos de estos aspectos particulares en la comunicación de grupos. 2.2.2.1 Grupos cerrados frente a grupos abiertos Los protocolos que soportan comunicación de grupos pueden dividirse en dos categorías. Una es la de los grupos cerrados. En ellos sólo los miembros del grupo pueden enviarse mensajes entre sí. Procesos que no pertenecen al grupo no pueden enviar mensajes al grupo como tal, si bien, por supuesto, sí pueden enviar mensajes particulares a cada miembro del grupo a título particular. Otros protocolos soportan grupos abiertos. Un proceso que no pertenece a un grupo puede enviar mensajes a este grupo. Los grupos cerrados son utilizados típicamente en procesa-miento en paralelo, donde los procesos tienen su propio cometido y no interactúan con el mundo exterior. Los grupos abiertos son apropiados para problemas como el de los servidores replica-dos, donde un cliente envía una petición al grupo. Los miembros del grupo también necesitan hacer uso de la comunicación en grupo y no sólo un proceso externo, por ejemplo para decidir quién debe ejecutar una petición dada. 2.2.2.2 Grupos de iguales frente a grupos jerárquicos En algunos grupos un proceso es el jefe o coordinador y el resto trabajan para él. En otros, todos los procesos tienen la misma categoría y las decisiones se toman de forma colectiva. En el primer caso, cuando uno de los trabajadores o un cliente externo solicita una petición, esta es enviada al coordinador, que decide cuál de los trabajadores es el más apropiado para servirla. Cada una de estas organizaciones tiene sus ventajas y sus inconvenientes. Los grupos pares no tienen un único punto de fallo. Si un trabajador deja de existir, la carga se reparte en el resto. Sin embargo, incurren en el retraso que supone el ponerse de acuerdo para decidir quién sirve una petición. Los grupos jerárquicos tienen las propiedades opuestas. 2.2.2.3 Pertenencia a grupos
  • 7. Se necesita un método para crear, destruir y modificar los grupos. Una solución es introducir un proceso denominado el servidor de grupos. El servidor de grupos mantiene tablas con los grupos existentes y sus integrantes. Esta solución es eficiente y fácil de implementar. El problema es que el servidor de grupos es una técnica centralizadora y, como tal, constituye un único punto de fallo. La opción opuesta es la gestión distribuida. Un nuevo proceso que se incorpora al grupo puede enviar un mensaje al grupo y todos los procesos toman nota de su existencia. Cuando un proceso del grupo termina, envía un mensaje de adiós. Surge un problema cuando un proceso del grupo termina inesperadamente. El resto del grupo tiene que descubrirlo experimentalmente, ya que el proceso nunca responde a nada. Cuando todos los miembros lo han constatado, se le da de baja. 2.2.2.4 Direccionamiento de grupos Para dirigir un mensaje a un grupo, el grupo debe tener una dirección. Si el nivel de enlace de la red -en adelante, la red- soporta multicasting, se puede implementar una dirección de grupo como una dirección multicasting. Si la red soporta difusión, pero no multicasting, el mensaje debe ser recibido por todos los núcleos y extraer de él la dirección del grupo. Si ninguno de los procesos de la máquina es miembro del grupo, el mensaje es descartado. En otro caso, es pasado a todos los procesos que pertenecen al grupo. Si la red no soporta ni difusión ni multicasting, el núcleo de la máquina emisora tendrá que tener una lista de los procesos que pertenecen al grupo y enviar un mensaje a cada uno de los componentes del grupo. 2.2.2.5 Primitivas send y receive No es conveniente que los procesos de usuario puedan utilizar las primitivas send y recei-ve por separado. Según Tanenbaum, send y receive se corresponden en programación distribuida con la construcción “go to” en programación convencional. Su utilización provoca más trastornos que utilidad. Si RPC es la primitiva de comunicación usada por los procesos de usuario, la comunicación de grupo debiera poder construirse mediante RPC. El problema es tratar con una llamada a procedimiento que devuelve tantos valores como procesos tiene un grupo. No parece posible, de modo que una aproximación común es volver a las primitivas send y receive en los procesos de usuario. Si se permite send y receive a los procesos de usuario, se pueden aprovechar estas primitivas para realizar la comunicación de grupo. En el caso de la comunicación convencional cliente servidor, el primer parámetro de send es un número de puerto en la red y el segundo parámetro es el mensaje. Se puede utilizar send para la comunicación de grupos empleando como primer parámetro la dirección de un grupo de procesos en lugar de un puerto determinado. Así unifica-mos la comunicación punto a punto y la comunicación de grupos en una primitiva única. La implementación de send que haga el núcleo o la rutina de biblioteca puede ser una de las tres citadas en el apartado de direccionamiento de grupos. send puede ser con buffer o sin buffer, bloqueante o no bloqueante, fiable o no fiable, etc, igual que en la comunicación punto a punto. La comunicación de grupo no cambia las cosas. Enviar a un grupo obliga al núcleo del sistema que envía a hacer una comunicación multicasting a todos los miembros del grupo, pero ¿qué es recibir de un grupo? Puede entenderse que todos los miembros del grupo van a enviar una réplica diferente y por lo tanto un envío a un grupo debería continuar en el programa de usuario con tantas operaciones receive como miembros tuviese el grupo. Ello, no obstante, significa una pérdida de transparencia, ya que un proceso externo no debe conocer la estructura interna de un grupo. 2.2.2.6 Atomicidad de la difusión Una de las características de la comunicación de grupos es que un mensaje enviado a un grupo debe ser recibido por todos los miembros del grupo o por ninguno de ellos. A esta propiedad se la denomina la atomicidad de la difusión o simplemente la atomicidad. La atomicidad facilita en gran medida la programación de sistemas distribuidos. Supongamos, por ejemplo, una base de datos distribuida. Una base de datos distribuida puede tener una relación cuyos atributos estén repartidos en máquinas dispersas geográficamente. El acceso a una tupla significa enviar un mensaje a
  • 8. todas las máquinas. Supongamos la creación de una tupla de estas características. Si uno de los mensajes se pierde, la base de datos queda en un estado inconsistente. La tupla debe crearse en su totalidad o no crearse y la aplicación ser informada del éxito o del fracaso de la operación entera, no sólo un éxito parcial. Implementar la atomicidad de la difusión no es tan simple como parece. Por ejemplo, uno de los adaptadores de red tal vez acaba de recibir un paquete y antes de que esté preparado para recibir uno nuevo, llega el paquete de difusión, que no puede ser aceptado y simplemente se pierde. Todas las máquinas del grupo han recibido el paquete excepto una, lo que arruina la difusión completa. Para cerciorarse de que todo ha ido bien, el emisor de la difusión debe esperar las confirmaciones de los miembros del grupo. Si una falta, deberá repetir la difusión o reenviar el mensaje en particular. Puede ocurrir que antes de repetir la difusión o hacer el reenvío, el emisor de la difusión se caiga. En esta situación, el cliente debe rearrancar, pero nunca sabrá cuántos son los mensajes que realmente han sido enviados y cuántos los que han fallado. Algunos miembros del grupo han recibido el mensaje y otros no. Una situación inaceptable e ¿incorregible? No, queda alguna esperanza. Existe un algoritmo que demuestra que la atomicidad es posible. El emisor realiza la difusión, inicializa temporizadores y realiza los reenvíos necesarios. Cuando un miembro del grupo recibe un mensaje nuevo, envía el mensaje a todos los miembros del grupo -de nuevo utilizando temporizadores y retransmisiones si son necesarias-. Si el mensaje no es nuevo, simplemente es descartado. No importa cuantas máquinas caigan en el proceso de envíos y reenvíos, lo importante es que de los procesos supervivientes en el grupo todos han recibido el mensaje. 2.2.2.7 Ordenación de mensajes Para que la comunicación en grupo sea fácil de usar y comprender requiere de dos propieda-des. La primera es la atomicidad, examinada más arriba y la segunda es el orden de los mensajes. Supongamos cinco máquinas, cada una con un proceso. Los procesos 0, 1, 3 y 4 pertenecen a un grupo de procesos. Supongamos que los procesos 0 y 4 deciden enviar un mensaje al resto de los procesos del grupo. Supongamos que el proceso 0 lo ha decidido un instante de tiempo antes. La propiedad de orden temporal global exige que cada miembro del grupo reciba primero el mensaje del proceso 0 y después el mensaje del proceso 4. Una red local que soporte difusión garantiza el orden temporal global. Todos los mensajes del proceso 0 llegan al resto del grupo ya que el paquete con dirección difusión es recibido por todos los adaptadores de red de forma simultánea. Sólo después, cuando el mensaje ha sido enviado y deja libre el canal el proceso 4 puede emitir su paquete de difusión. Una red sin difusión no garantiza el orden temporal global, que debe implementar la difusión enviando cuatro mensajes consecutivos que pueden entrelazarse con los del proceso 4. Así, el proceso 1 puede recibir primero el mensaje del proceso 0 y después el del 4 y el proceso 3 puede recibir primero el mensaje del proceso 4 y después el del proceso 0. 2.2.2.8 Grupos solapados En el apartado anterior vimos el problema de la ordenación temporal global aplicada a un grupo dado. Dos procesos del mismo grupo enviaban simultáneamente un mensaje al grupo. Hemos mencionado previamente que un proceso puede pertenecer a más de un grupo, de manera que los grupos pueden solaparse. Este solapamiento produce un nuevo tipo de inconsistencia temporal. La figura 2.14 muestra el problema planteado. Los procesos A y D, en distinto grupo, envían simultáneamente un mensaje a su propio grupo. Como en el caso anterior supongamos que la red no proporciona difusión y esta se implementa mediante unicasting. El envío simultáneo es consitente si B y C reciben primero el mensaje del grupo 1 y después el mensaje del grupo 2 (o viceversa). Unicasting no puede garantizar esto, de modo que es posible el escenario de la figura 2.14. B recibe el mensaje dirigido al grupo 1 y después el mensaje al grupo 2. C, por el contrario, primero recibe el mensaje dirigido al grupo 2 y después el mensaje al grupo 1. Fig. 2.14 Cuatro procesos y cuatro mensajes. B y C toman los mensajes de A y D en diferente orden. Una comunicación de grupo que garantiza que esto no ocurre se dice que tiene la propiedad de orden temporal entre grupos solapados. La implementación del orden temporal entre grupos solapados es costosa y difícil de implementar, de modo que algunos sistemas distribuidos la implementan y otros no, actualmente la mayoría de ellos.
  • 9. 2.2.2.9 Escalabilidad Muchos algoritmos de comunicación de grupos funcionan bien siempre que los grupos sean pequeños y haya pocos grupos, pero ¿qué ocurre cuando cada grupo tiene muchos procesos y hay miles de grupos? Y ¿qué ocurre cuando los grupos se extienden geográficamente entre continen-tes? Para ellos es preciso sobrepasar los estrechos límites de la red local e introducir encaminado-res y muchas redes locales. La presencia de encaminadores afecta a las propiedades de la comunicación del sistema operativo distribuido, ya que están basadas en la suposición de ausencia de encaminadores. Un encaminador es básicamente una máquina que pertenece a dos o más redes. Su propósito es unir dos o más redes locales distantes geográficamente, de distinto nivel de enlace o ambas cosas a la vez, permitiendo que todas ellas compartan un mismo protocolo de nivel de red. En la definición de grupo nada impide que los procesos que forman el grupo se encuentren en una misma Inter-red pero en distintas redes locales. Cuando la comunicación de grupo se realiza mediante unicasting la presencia de gateways no es problemática. Cada mensaje enviado por el proceso emisor llega al proceso destinatario siguiendo los cauces convencionales del algoritmo utilizado por el protocolo de red. Consideremos un sistema operativo distribuido en el que las redes locales que abarca soportan multicasting, como ethernet. 3.1 Sincronización de relojes Los algoritmos distribuidos tienen las siguientes propiedades: 1. La información relevante está repartida entre múltiples máquinas 2. Los procesos toman decisiones basados únicamente en información local 3. Es preciso evitar un único punto de fallo 4. No existe un reloj común Los primeros tres aspectos dicen que es inaceptable recoger toda la información en un único punto. El último aspecto es que ahora nos interesa. En un sistema centralizado, el tiempo se solicita mediante una llamada al sistema, como la llamada UNIX time. Si un proceso A solicita el tiempo y poco después lo solicita el proceso B, B obtiene un tiempo posterior al de A, ya que ambos consultan el mismo reloj. En un sistema distribuido, en que A y B corren en máquinas distintas y consultan distintos relojes, si el reloj de A es ligeramente más lento que el de B, A puede conseguir un tiempo posterior al de B a pesar de habero solicitado antes. 3.1.1 Relojes lógicos Leslie Lamport, en 1978 ([Les78]), mostró que la sincronización de relojes para producir un patrón de tiempo común a más de una máquina es posible y presentó un algoritmo para lograrlo. Lamport afirmó que no es necesario disponer de un registro común absoluto del tiempo cuando los procesos no interactúan y, cuando lo hacen, tampoco es necesario en la mayoría de las aplicaciones. Para muchos casos, lo imporante es que los procesos que interactúan se pongan de acuerdo en el tiempo en que los eventos ocurren. En el ejemplo de make, lo importante es que pepo.c sea más antiguo que pepo.o, no el instante preciso de creación de ambos. Así, para ciertas clases de algoritmos, lo que importa es la consistencia interna de los relojes, no la exactitud particular de cada uno de ellos. Para estos algoritmos, es conveniente hablar de relojes lógicos. Cuando el objetivo es mantener todos los relojes dentro de un margen error dado respecto al tiempo absoluto, es conveniente hablar de relojes físicos. Lamport definió la relación ocurre-antes, a m b, leída “a ocurre antes que b”, y significa que a ocurre antes que b y todos los procesos están de acuerdo en ello. Lamport definió esta relación como sigue: 1. Si los eventos a y b ocurren en el mismo proceso y a ocurre antes que b, entonces a b. 2. Si a es el evento que consiste en el envío de un mensaje a otro proceso y b es el evento que consiste en la recepción del mensaje en otro proceso, entonces a b. 3. Si a e b y b c, entonces b e c.
  • 10. 3.1.2 Relojes físicos El día solar es el tiempo que transcurre desde que el sol alcanza su punto más alto en el horizonte hasta que vuelve a alcanzarlo. Un día tiene 24 horas, de modo que definimos el segundo solar como 1/(24*60*60) = 1/86400 de un día solar. En 1940 se descubrió que la duración del día no era constante. Estudios actuales sobre coral antiguo han llevado a los geólogos a pensar que hace 300 millones de años había 400 días en un año. No es que el año fuera más largo. Es que los días eran más cortos. La tierra rotaba sobre sí misma más rápido que en la actualidad. Además de esta tendencia a largo plazo, la tierra experimenta perturbaciones esporádicas en su tiempo de rotación debido a las turbulencias de su núcleo de hierro. Estas oscilaciones llevaron a los astrónomos a determinar la duración del segundo como la media de un gran número de ellas. Dividida esta cantidad por 86400 obtenemos el segundo solar medio. Con la invención del reloj atómico en 1948, la medida del tiempo pasó de ser responsabilidad de los astrónomos a ser responsabilidad de los físicos. Definieron el segundo atómico como el tiempo que tarda el isótopo 133 del cesio en realizar 9192631770 transiciones. Este número de transiciones fue escogido, por supuesto, porque son las que igualaban la duración del segundo solar medio el día que el segundo atómico fue introducido. El segundo atómico es más preciso que el segundo solar, pero no es absolutamente preciso. En el mundo existen actualmente unos 50 laboratorios que disponen de un reloj de 133Cs. Cada uno de ellos registra el número de ticks acumulados desde las cero horas del primero de enero de 1958. En París existe una organización que se llama la Oficina Internacional de la Hora que promedia los ticks de estos 50 laboratorios. Al resultado lo divide por 9192631770 para obtener el Tiempo Atómico Internacional (TAI). El TAI es extrordinariamente estable y está a disposición de cualquiera que lo solicite. Sin embargo, como el periodo de rotación de la tierra está aumentando continuamente, el segundo solar aumenta en la misma medida. Así, un día solar, que son 86400 segundos solares, tiene ahora 86400.003 segundos TAI. Usar el tiempo TAI es más exacto, pero llegará un momento que el mediodía no será a las 12, sino a las doce y cuarto. Los segundos TAI duran menos que los segundos solares. Para ello, cuando un reloj solar ha perdido 0.8 segundos respecto al tiempo TAI, por ejemplo, el tiempo es de 4.0 TAI y de 3.2 solar, se extingue ese segundo solar para que pase directamente de 3.2 a 4.0 y mantener la sincronía con el tiempo TAI. Esto da una medida del tiempo con intervalos irregulares, llamado el Tiempo Universal Coordinado (UTC), que es la base actual del registro del tiempo. Ha reemplazado al antiguo estándar de la medida del tiempo, el GMT (Greenwich Meridian Time), que es tiempo solar. Para proporcionar el tiempo UTC, una institución de Estados Unidos, el Instituto Nacional del Tiempo Estándar (NIST), mantiene una estación de radio de onda corta que radia un pulso cada vez que comienza un segundo UTC. La precisión de esta estación es de un milisegundo, pero el ruido atmosférico eleva este error en la práctica a 10 milisegundos. En Inglaterra y otros países existen estaciones similares. También satélites proporcionan el tiempo UTC, y lo hacen con una precisión de 0.5 milisegundos, veinte veces mayor que las estaciones de radio de onda corta. El costo de este servicio varía, según su exactitud, entre 100.000 pts y varios millones de pesetas según su precisión. Hay un medio más barato, que es obtenerlo del NIST por teléfono. Este es el método más inexacto, ya que hay que corregir el retraso de la señal en la línea y el modem. Concluyendo, podemos decir que el tiempo absoluto puede ser proporcionado al computador, pero a un precio alto y siempre con un margen de error no despreciable. Mas información: http://www.cstv.to.cnr.it/toi/uk/utctime.html
  • 11. 3.1.3 Algoritmos de sincronización de relojes La medida del tiempo en las máquinas se lleva a cabo mediante un oscilador de cristal. Un chip denominado temporizador recibe la señal periódica del oscilador e interrumpe la UCP cada cierto número de oscilaciones, previamente programado. Valores típicos oscilan entre 50 y 100 interrupciones por segundo a la UCP. Por preciso que sea un oscilador a cristal, siempre existe un margen de error que conlleva la discrepancia de la medida del tiempo de dos máquinas diferentes. En una red local, por ejemplo, ninguna máquina tiene el mismo registro del tiempo. Para disminuir la discrepancia entre relojes, se puede tener acceso a una estación de onda corta de las ya citadas. El caso general, sin embargo, es que este servicio no está disponible, y el problema que se plantea es, dado un conjunto de máquinas, mantener sus relojes lo más cercanos que sea posible mediante software. Se han propuesto para ello muchos algoritmos, todos ellos con el mismo principio, que ahora describimos. Se supone que cada máquina dispone de un temporizador que interrumpe a la UCP H veces por segundo. El núcleo dispone de una variable que es incrementada en la unidad por la rutina de interrupción del reloj. Esta variable registra el número de ticks recibidos desde la puesta en marcha del sistema, por ejemplo. Esta variable se considera el reloj del sistema y vamos a denominar el valor que almacena como C. Cuando el tiempo es t, el tiempo registrado por la máquina p es Cp(t). Idealmente Cp(t) debiera ser igual a t, para todo p y todo t. En otras palabras, dC/dt debiera ser idealmente 1. Teóricamente, un temporizador con H=60 interrumpe al reloj sesenta veces por segundo. En una hora interrumpe 60*60*60 = 216000 veces. En la práctica, se puede contar este número de interrupciones y descubrir que no son exactamente esas, sino que el dato varía entre 215998 y 216002 ticks en una hora, lo que representa un error relativo de aproximadamente 10–5. La precisión de un temporizador viene dada por su tasa de deriva máxima 0, de modo que si se dice que el reloj opera dentro de sus especificaciones. Dos relojes iguales dentro de sus especificaciones pueden generar una direferencia máxima en su medida del tiempo cuando la deriva toma en ellos el valor máximo y de signo opuesto. Así, partiendo ambos de cero, en un intervalo , el reloj uno toma un valor de y el reloj dos un valor de 0, obteniendo una diferencia máxima en la medida de 0. Si los diseñadores del sistema desean que nunca dos relojes muestren diferencias mayores a una constante 0, 0, de modo que 0, lo que significa que los relojes deben ser sincronizados cada 0 segundos. A continuación vamos a ver algunos algoritmos que llevan a cabo esta resincronización. 3.1.3.1 El algoritmo de Cristian Este algoritmo requiere que una de las máquinas disponga de un receptor de onda corta y el objetivo es lograr que todas las demás operen sincronizadas con ella. A esta máquina la vamos a llamar un servidor de tiempo. Periódicamente, y siempre antes de segundos, cada una de las máquinas envía un mensaje al servidor de tiempo solicitando el tiempo CUTC, que es servido tan rápido como es posible como indica la figura 3.5 XX falta XX. El algoritmo tiene dos problemas, uno más leve y otro más serio. El más serio es que un reloj nunca puede ser retrasado. Si el reloj de la máquina que solicita el tiempo es rápido, el tiempo CUTC recogido es menor y su reloj debe ser atrasado. Esto no se puede permitir porque muchas aplicaciones, como make, confían en la secuencia temporal de eventos en el sistema como la base de su operación. A un evento que ocurre después de otro, como la generación de un fichero objeto, no se le puede asignar un tiempo de creación o última modificación inferior al del programa fuente.
  • 12. La modificación del reloj debe realizarse gradualmente. Una forma de hacerlo es la siguiente. Supongamos que el temporizador interrumpe la UCP cien veces por segundo, lo que significa que un tick de reloj es un intervalo de tiempo de diez milisegundos. La rutina de interrupción incrementa un contador en el núcleo, el reloj, en una unidad, lo que equivale a sumar al tiempo diez milisegundos. Para retrasar el reloj un segundo se puede dejar de incrementar el contador una de cada cien interrupciones -por ejemplo, la décima-, lo que significa que cada segundo retrasamos el reloj diez milisegundos. Para retrasarlo un segundo necesitamos cien segundos. Para adelantar el reloj se puede utilizar esta misma técnica. Al cabo de 100 segundos, habremos adelantado el reloj un segundo. También se puede adelantar el reloj de una sóla vez añadiendo 100 ticks al reloj, ya que el adelantamiento del tiempo no causa problemas. El problema secundario es que desde que una máquina solicita el tiempo CUTC, la réplica del servidor de tiempo tarda en llegar una cantidad de tiempo no despreciable y, lo que es peor, que varía con la congestión de la red. El algoritmo de Cristian aborda este problema intentando medirlo. El cliente registra el tiempo local T0 en que envía el mensaje y el tiempo T1 en el que llega y estima que la réplica tardó en llegar (T1-T0)/2. Este tiempo que es local y, por ser pequeño, relativo exacto aunque el reloj se haya alejado sensiblemente del tiempo UTC. (T1-T0)/2 se suma al CUTC que trae el mensaje y el resulado es el CUTC que finalmente el cliente adopta. Para mejorar la exactitud se puede realizar un muestreo entre distintos tiempos de retorno de la petición de tiempo y realizar una media. Se aconseja descartar los valores que superan un umbral dado para evitar introducir en la estimación réplicas obtenidas en momentos de congestión. 3.1.3.2 El algoritmo de Berkeley Es el adoptado por UNIX BSD. Frente al algoritmo de Cristian, basado en un servidor pasivo que responde a las peticiones de clientes, el algoritmo de Berkeley toma una aproximación activa. Es útil cuando no se dispone del tiempo UTC, vía un receptor de onda u otro. Un demonio UNIX periódicamente realiza un escrutinio de las máquinas, aquella en la que reside incluida, a fin de obtener el valor de sus relojes. Realiza una media de todos ellos y la comunica a todas la máquinas para que avancen o retrasen sus relojes. 3.1.3.3 Algoritmos de promediado Los algoritmos anteriores tienen la desventaja de su aproximación centralizada y, por lo tanto, tienen un único punto de fallo. Presentamos a continuación un algoritmo descentralizado. Las máquinas dividen el tiempo en intervalos de longitud R, de modo que el comienzo del i-ésimo intervalo comienza en el instante T0+iR se prolonga hasta el instante T0+(i+1)R, donde T0 es un instante pasado previamente acordado. Cuando comienza uno de estos intervalos, cada máquina realiza una difusión del tiempo según su reloj. Debido a la deriba particular de cada reloj, dos difusiones no ocurren simultáneamente. Después de la difusión de su tiempo, cada máquina establece un temporizador y espera el mensaje correspondiente al broadcast del resto de las máquinas en un intervalo S. Cuando han llegado todos los mesajes, un algoritmo de promediado proporciona el nuevo tiempo. El algoritmo más simple es realizar la media aritmética de los tiempos. Una variación es descartar previamente los valores extremos a fin de protegernos frente a relojes defectuosos. Otra variación es estimar el tiempo de propagación de cada mensaje para añadirlo al tiempo que el mensaje transporta. Esta estimación puede llevarse a cabo a partir de un conocimiento previo de la topología de la red o realizando mediciones del tiempo de retorno de algunos mensajes de prueba. 3.1.4 El empleo de la sincronización de relojes
  • 13. Hasta hace poco tiempo no se ha presentado la necesidad de sincronizar los relojes de máquinas en una red de área ancha. Ahora es posible sincronizar relojes distribuidos a lo largo de toda la Internet en márgenes de precisión de unos pocos milisegundos respecto al tiempo UTC. La disponibilidad de algoritmos de bajo costo para mantener la sincronización de relojes ha incitado el desarrollo de algoritmos distribuidos que explotan esta circunstancia disminuyendo el número de mensajes implicados en las versiones que no la explotan. A continuación ilustramos el empleo de la sincronización de relojes en el problema de la consistencia de la caché de un sistema de ficheros distribuidos. La referencia [Lis93] contiene más ejemplos. Un ejemplo de la utilidad de algoritmos basados en el uso de relojes sincronizados está relacionado con la consistencia de la cache de disco en un sistema de ficheros distribuido. Razones de prestaciones exigen una caché en el cliente. Dos clientes operando sobre un mismo fichero mantienen cada uno de ellos una copia del fichero en su propia máquina. La inconsistencia de las cachés surge cuando uno de los clientes trata de escribir en el fichero. Tradicionalmente, cuando un cliente deseaba escribir un fichero de su caché solicitaba permiso al servidor. Inmediatamente, el servidor está obligado a solicitar permiso al proceso o procesos que están leyendo del fichero para que dejen de hacerlo (y lo descarten de la caché), y esperar a que todos los permisos lleguen antes de conceder el permiso de escritura, lo que introduce una fuerte sobrecarga en tiempo y ancho de banda en la red. La introducción de los relojes sincronizados agiliza este tipo de protocolos de los sistemas de ficheros distribuidos. La idea básica es que cuando un cliente solicita un fichero, el servidor le otorga una concesión en la que detalla el tiempo de expiración de la misma E. Como cliente y servidor tienen los tiempos sincronizados, el plazo es el mismo en ambos. Mientras dura la concesión, el cliente tiene la garantía de que opera sobre el fichero de forma consistente. Un cliente no necesita comunicar al servidor que ha terminado la operación de lectura. Si un cliente solicita la escritura de un fichero, el servidor debe pedir a los clientes lectores la terminación prematura de la concesión. ¿Qué ocurre cuando no hay respuesta por parte del cliente lector? El servidor no sabe si el cliente simplemente se ha caído. En este caso, el servidor no obtiene respuesta, lo que plantearía un problema en el algoritmo tradicional. Con los relojes sincronizados, simplemente espera a que cumpla el plazo de la concesión del fichero. 3.2 Exclusión mutua Cuando dos o más procesos comparten una estructura de datos, su lectura o actualización no debe ser simultánea. Para evitar la simultáneidad de acceso, y con ello la incosistencia de la estructura, el código de acceso y actualización de la misma se denomina región crítica y su ejecución es protegida mediante construcciones como semáforos, monitores, etc. En esta sección examinamos algunos ejemplos de cómo construir regiones críticas en sistemas distribuidos. 3.2.1 Un algoritmo centralizado La forma más directa de conseguir la exclusión mutua en un sistema distribuido es simular al mecanismo de los sistemas centralizados. Se requiere de un proceso que actúa como coordinador. Este registra las regiones críticas de los procesos. Cuando un proceso desea entrar en una región crítica envía un mensaje al coordinador con el número de la región crítica. Si ningún otro proceso está ejecutando la región crítica, el coordinador envía una réplica al proceso con la concesión de entrada, tal y como muestra la figura 3.5. Cuando la réplica llega, el proceso entra en la región crítica.
  • 14. Fig. 3.5 a) Solicitud y concesión de entrada en región crítica. b) La concesión se retrasa hasta mientras la región crítica esté en uso. c) Concesión tras ser liberada Supongamos que el proceso 3 de la figura desea entrar en la misma región crítica antes de que el proceso 2 salga. La petición llega al coordinador, que sabiendo que el proceso 2 está dentro, no envía réplica alguna al proceso 3, que permanece bloqueado esperándola -también se puede implementar la denegación mediante un mensaje-, pero lo registra en la cola de la región como solicitante. Cuando el proceso 2 sale de la región crítica lo comunica al coordinador mediante un mensaje de liberación. El coordinador procesa el mensaje determinando si existe en la cola de la región recién liberada algún proceso esperando. En nuestro caso, efectivamente lo hay. Es el proceso 3, que por fin recibe el mensaje de concesión de entrada. Este algoritmo garantiza la exclusión mutua. Primero, el coordinador sólo permite entrar en la misma a un proceso. Segundo, es justo, ya que las peticiones son atendidas en el orden en que llegan. Tercero, ningún proceso espera indefinidamente por la entrada. El esquema es fácil de implementar y es eficiente, ya que requiere tres mensajes para usar una región crítica. El defecto principal del algoritmo, como todos los algoritmos centralizados es la existencia de un único punto de fallo. 3.2.2 El algoritmo distribuido de Ricart y Agrawala Ricart y Agrawala presentaron en 1981 un algoritmo de exclusión mutua distribuido. Consideramos un conjunto de N procesos con una esctructura sencilla en la que alternan los cálculos fuera de la región crítica y dentro de la región crítica. Las condiciones del algoritmo son las siguientes: 1. Los procesos se comunican mediante mensajes de capacidad no nula. 2. Los mensajes pueden llegar a un proceso en cualquier punto de la ejecución, bien dentro o bien fuera de la región crítica. De cualquier modo una interrupción, excepción, manejador de señal, etc, se encarga de procesar la llegada del mensaje. 3. Se asume que la comunicación es fiable y los mensajes entre dos procesos son entregados en el orden en el que fueron enviados. 4. Es preciso una relación de orden total entre los eventos de todo el sistema. Consideramos que para que un proceso entre en la región crítica deben tener el permiso todos y cada uno del resto de los procesos, permiso que solicita enviando un mensaje a todos ellos, vía multicasting, difusión o uno a uno. El mensaje acarrea una etiqueta temporal que es el valor del reloj lógico local correspondiente a su envío. Cuando un proceso recibe un mensaje de solicitud de permiso, la acción que toma el proceso receptor es la siguiente: 1. Si el receptor no está en su región crítica y no desea entrar en ella, se dice que está en situación de permiso concedido (CONCEDIDO) y envía inmediatamente un mensaje de réplica al proceso que solitó el permiso. 2. Si el receptor está ejecutando en su región crítica, se dice que tiene el permiso (OTORGADO), no envía réplica al emisor y encola la petición. Como vemos, si un proceso no contesta significa que no concede el permiso de entrada. 3. Si el receptor desea también entrar en la región crítica, pero aún no lo ha conseguido se dice que está en estado de solicitud (SOLICITANDO), compara el reloj del mensaje entrante con el del mensaje que ha enviado al resto de los procesos para solicitar el permiso. El más bajo gana. Si gana el emisor del mensaje entrante, el receptor envía a este la réplica. Si gana el receptor, encola el mensaje y no envía réplica. Inicialización: estado:=CONCEDIDO;
  • 15. Para obtener el permiso: estado:=SOLICITANDO; multicast de solicitud de permiso al resto; T:=Reloj lógico del mensaje de petición; Wait until(Número de réplicas recibidas=n-1); estado:=OTORGADO; Cuando se recibe una petición <Ci, pi> en pj: if(estado=OTORGADO or (estado=SOLICITANDO and C.pj < C.pi) ) then Encola la petición de pi sin replicar else Replica inmediatamente a pi fi Para conceder el permiso tras abandonar la región crítica: estado=CONCEDIDO; Replica a todos las peticiones en la cola; Fig. 3.6 El algoritmo de Ricart y Agrawala En conjunto, el algoritmo es más lento, más complicado y menos robusto que el algoritmo centralizado, de modo que ¿porqué molestarse estudiándolo? Porque demuestra que un algoritmo distribuido, sin un control central, es posible, lo que estimula el estudio de soluciones distribuidas más avanzadas. 3.2.3 El algoritmo en anillo Esta basado en una disposición de los n procesos que están interesados en utilizar la región crítica en un anillo lógico. Se concede la entrada en la región crítica al proceso que obtiene el denominado testigo. El testigo es un mensaje que se pasa de proceso en proceso en un sentido único recorriendo el anillo. Cada proceso tiene la dirección del proceso al que pasa el testigo. Cuando un proceso recibe el testigo, si no está interesado en la región crítica, pasa es testigo a su vecino. Si necesita entrar en la región crítica, espera bloqueado la llegada del testigo, que es retenido y no es entregado al vecino sino cuando abandona la región crítica. Para obtener el testigo, como máximo se emplean n-1 mensajes. Una desventaja es que los mensajes se envían continuamente aun en el caso de que ningún proceso reclame el testigo. Otra es que este algoritmo tiene n puntos de fallo, si bien la recuperación es más fácil que en los casos anteriores. Si cada vez que se recibe el testigo se envía un mensaje de confirmación, es sencillo detectar la caída de un proceso y retirarlo del anillo. 3.3 Algoritmos de elección Una elección es un procedimiento cuya función es elegir un proceso en un grupo a fin de que este desempeñe un papel determinado, como puede ser centralizar peticiones de entrada en una región crítica, a modo de coordinador. Vamos a considerar que los procesos implicados en la elección son idénticos, sin que ninguno de ellos tenga una característica destacable como para ser el coordinador idóneo. Cada proceso tiene un identificador único como puede ser su dirección de red. En general, los algoritmos de
  • 16. elección intentan localizar al proceso con el identificador más alto para hacerlo coordinador. Para enviar los mensajes, los procesos necesitan conocer las direcciones de red de todo el grupo de procesos en busca de coordinador, de modo que la elección ya estaría hecha de antemano. El problema es que los procesos desconocen cuáles de ellos están aún activos y cuáles no. El requisito que debe cumplir una elección de coordinador es que esta sea única. Los algoritmos difieren unos de otros en el modo de conseguirlo. El algoritmo del matón Este algoritmo data de 1982 y es debido a García-Molina. Cuando un proceso se apercibe de que el coordinador no responde a sus mensajes, inicia una convocatoria de elección. Una elección se desarrolla como sigue: 1. P envía un mensaje de tipo ELECCION a todos los procesos con identificadores más altos. 2. Si ninguno de ellos responde, P gana la elección y se convierte en el coordinador. 3. En cuanto P recibe el mensaje de respuesta de alguno de ellos, renuncia a ser el coordinador y su trabajo ha terminado. Cada uno de estos procesos, tras enviar el mensaje, convocan una elección En cualquier momento, un proceso puede recibir un mensaje ELECTION de uno de los procesos con identificador inferior. La rutina que sirve el mensaje envía un mensaje de confirmación y toma el control iniciando una elección, a menos que ya esté celebrando una. Llega un momento en que todos los procesos renuncian y uno de ellos se convierte en el nuevo coordinador, hecho que anuncia al resto de los procesos mediante el envío de un mensaje. Si un proceso que inicialmente estaba caído se recupera, inicia una elección. Si es el de identificador más alto, ganará la elección y asumirá el papel de coordinador. Siempre gana el proceso de identifica-dor más grande, de ahí el nombre del algoritmo. En la figura 3.7 vemos el desarrollo de una elección en un grupo de ocho procesos numerados del 0 al 7, siendo este último el coordinador que, en un momento dado, deja de estar operativo. El proceso 4 es el primero en darse cuenta de que el coordinador no responde y convoca una elección, enviando un mensaje de tipo ELECCION a los procesos 5, 6 y 7, los dos primeros confirmando el mensaje. En cuanto el proceso 4 recibe la confirmación del proceso 5 da su trabajo por terminado. Sabe que él no será el coordinador, sino uno de los superiores que han confirmado. Los procesos 5 y 6 convocan elecciones de forma más o menos simultánea. El proceso cinco recibe confirmación del 6 y renuncia. El proceso 6 no recibe confirmación alguna, de modo que se erige en ganador, algo que anuncia al resto enviándoles un mensaje COORDINADOR. El proceso 4, que estaba esperando el resultado de la elección -aunque ya lo casi lo conocía- reanuda su trabajo, esta vez con un nuevo coordinador. 3.4 Transacciones atómicas El paradigma cliente-servidor proporciona una buena forma de estructurar el sistema y de desarrollar aplicaciones, pero necesita del concepto de transacción para controlar secuencias complejas de interacciones entre el cliente y el servidor. Sin transacciones no se puede conseguir que los sistemas distribuidos funcionen en las aplicaciones típicas de la vida real. Los conceptos de transacciones fueron concebidos para poder abordar la complejidad de las aplicaciones on-line en sistemas de un único procesador. Estos conceptos, ya veteranos, son hoy día incluso más críticos en la implementa-ción con éxito de sistemas masivamente distribuidos, que operan y fallan en formas mucho más complejas. Los sistemas de proceso de trasacciones fueron pioneros en conceptos de computación distribuida y computación tolerante a fallos. Ellos introdujeron los datos distribuidos en aras de la fiabilidad, disponibilidad y prestaciones. Ellos desarrollaron el almacenamiento tolerante a fallos y el proceso tolerante a fallos a fin de garantizar la disponibilidad de datos y aplicaciones. Y fueron ellos quienes desarrollaron el modelo cliente-servidor y las llamadas a procedimiento remoto para la computación distribuida. Y, lo más importante, las propiedades ACID de las transacciones han emergido como los conceptos unificadores de la computación distribuida ([Gra93]). Como puede apreciarse, no es posible obviar el tópico de las transacciones atómicas en un curso sobre sistemas distribuidos. En esta sección nos ocupamos de ellas, tratando algunos de sus múltiples aspectos.
  • 17. 3.4.1 Introducción a las transacciones atómicas Pensemos en una primitiva de sincronización como un semáforo. Subir o bajar un semáforno es una operación de muy bajo nivel que obliga al programador a tratar los detalles de la exclusión mutua, la gestión de la región crítica, la recuperación en caso de fallo, etc, cuando opera sobre datos compartidos. Lo que nos gustaría en un entorno de datos compartidos y con componentes suscepti-bles de fallo es disponer de primitivas de manipulación de datos de más alto nivel que permitan al programador: 1. Concentrarse en el problema, ignorando que los datos son accedidos de forma concurrente 2. Ignorar que un fallo puede dejar los datos en un estado inconsistente. Estas primitivas se utilizan ampliamente en los sistemas distribuidos (su finalidad es compartir datos y recursos y tienen más posibilidades de fallo) y se llaman transacciones atómicas. El uso de las transacciones se remonta a los años 60 cuando los datos se almacenaban en cintas magnéticas. Una base de datos residía en una cinta. que se llamaba el “fichero maestro”. Las actualizaciones residían en una o más cintas (por ejemplo las ventas diarias o semanales) llamadas “ficheros de movimientos”. Maestro y movimientos se montaban en el computador para producir un nuevo fichero maestro, que sería utilizado al día o a la semana siguiente con nuevos ficheros de movimientos. La ventaja de este método -no reconocida suficientemente en aquellos años- es que si el programa que llevaba a cabo las actualizaciones fallaba, se producía una caída en la alimentación eléctirica, etc y el proceso de actualización se interrumpía, siempre se podía descartar la nueva cinta que había quedado a medias y volver sobre el maestro y las actualizaciones para generar de nuevo el fichero maestro. Así, una actualización del maestro procedía correctamente hasta el final o no se modificaba en absoluto. Esta propiedad era una transacción atómica sobre el objeto “fichero maestro”. Consideremos ahora una aplicación bancaria que realiza una retirada de una cantidad de una cuenta y el ingreso correspondiente en otra cuenta distinta. Si el computador falla después de la retirada y antes del ingreso, el dinero se desvanece. Puede que ambas cuentas residan en distintas máquinas y el fallo se deba a una pérdida de la conexión telefónica entre ambas operaciones. Sería necesario agrupar ambas operaciones en una transacción atómica como en el ejemplo de la cinta magnética que garantizase que la operación se realiza completamente o no se realiza. La clave reside en volver al estado inicial de las cuentas si es que se ha producido un fallo en mitad del proceso. Esta habilidad es proporcionada por las transacciones atómicas. 3.4.2 Servicios transaccionales Conviene examinar la aplicación bancaria anterior en el contexto del modelo cliente-servidor. Cuando decimos que un servidor porporciona operaciones atómicas significa que el efecto de desarrollar una operación en beneficio del cliente: Está libre de interferencia de las operaciones realizadas en beneficio de otros clientes Bien la operación concluye completamente o no tiene efecto alguno si el servidor falla. Una transacción entre un cliente y un servidor es una secuencia de interacciones. El servidor bancario proporciona las operaciones Depósito, Retirada, Balance, Total Sucursal?. sobre una serie de objetos, en este caso cuentas: Depósito(Cuenta, Cantidad) Deposita la cantidad Cantidad en la cuenta Cuenta Retirada(Cuenta, Cantidad) Retira la cantidad Cantidad de la cuenta Cuenta
  • 18. Balance(Cuenta) Cantidad Devuelve el balance de la cuenta Cuenta Total Sucursal e Total Devuelve la suma de todos los balances Consideremos un cliente que quiere realizar una serie de operaciones sobre las cuentas A, B, C. La primera operación transfiere 100 pesetas de A a B. La segunda transfiere 200 pesetas de C a B: Transacción: T: Retirada(A, 100); Depósito(B, 100); Retirada(C, 200); Depósito(B, 200); End Transacción?(T) Como vemos, desde el punto de vista del cliente, una transacción es una secuencia de operaciones que se realizan en un sólo paso, llevando al servidor de un estado consistente a otro. El cliente no es consciente de que otros clientes pueden realizar operaciones sobre las cuentas A y B. A un servidor de este tipo se le conoce como servidor transaccional o que provee de un servicio transaccional. En un servicio transaccional, el cliente, cuando inicia una transacción con el servidor, emite la petición Abrir Transacción? y el servidor le devuelve un indentificador de transacción. Este indentificador será usado en las operaciones siguientes. El cliente notifica al servidor el final de la secuencia de operaciones mediante la primitiva Cierra Transacción?. Abrir Transacción n Trans Arranca en el servidor una nueva transacción y devuelve un único identificador de transacción o TID, que será usado como parámetro en el resto de las operaciones de la transacción Cerrar Transacción?(Trans) r (Compromiso, Aborto) Termina la transacción. Si devuelve un compromiso, indica que la transacción se ha comprometido (se ha realizado en su totalidad). Si devuelve un valor de Aborto, la transac-ción no se ha realizado. Abortar Transacción?(Trans) Aborta la transacción La transacción puede abortar por varias razones. Entre ellas la naturaleza misma de la transacción y su desarrollo, conflictos con otra transacción o el fallo de procesos o máquinas. La transacción puede ser abortada, tanto por el cliente como por el servidor. Cuando el servidor decide unilateralmente abortar la transacción en curso, la operación en curso devuelve un código de error como SERVER_ABORT. Veamos cual es el comportamiento de cliente y servidor en presencia de fallos: Fallo en el servidor Si un servidor transaccional falla inesperadamente, cuando vuelve a arrancar, aborta toda transacción no comprometida utilizando un procedimiento de recuperación para restaurar los valores de los items de datos provisionales a los valores definitivos producidos por la transacción comprometida más recientemente previa al fallo. Replica al cliente la operación solicitada con un valor SERVER_ABORT. Otra posibilidad es que el cliente dé un plazo de respuesta al servidor para cada operación emitida. Si el servidor se recupera dentro del plazo, continúa con la transacción en curso en lugar de abortarla. Fallo en el cliente Si un cliente falla inesperadamente en el desarrollo de una transacción, el servidor puede dar un plazo de expiración a la transacción. Si una nueva operación de la transacción no llega en ese plazo el servidor aborta la transacción e inicia el procedimiento de recuperación.
  • 19. 3.4.3 Propiedades de las transacciones atómicas Las transacciones tienen cuatro propiedades fundamentales que se conocen por el acrónimo ACID: Atomicidad, Consistencia, serializabilidad o aislamiento (“Isolation”) y Durabilidad. 3.4.3.1 Atomicidad La atomicidad garantiza que la transacción procede hasta que se completa o no se realiza en absoluto. Si se completa, esto ocurre en una acción indivisible e instantánea. Mientras una transacción está en progreso, otros procesos, estén o no estén implicados en transacciones, no pueden ver los estados intermedios. Por ejemplo, supongamos una transacción que se ocupa de añadir octetos a un fichero de 10 octetos. Mientras la transacción esta en curso, otro proceso debe ver un fichero de sólo 10 bytes. Cuando la transacción se compromete, el fichero instantánemente aparece con su nuevo tamaño. Un sistema de ficheros que garantiza este comportamiento es un sistema de ficheros transaccional. La mayoría de los sistemas de ficheros no son transaccionales. 3.4.3.2 Consistencia La propiedad de la consistencia obliga cumplir ciertos invariantes de los datos del servidor. Por ejemplo, como resultado de una transferencia interna, una sucursal bancaria debe mantener el mismo dinero en su saldo que antes de que la transacción se realice. La consistencia de los datos puede ser violada por el cliente si las operaciones que emite no son consistentes y por el servidor si no dispone de un adecuado mecanismo de control de concurrencia. Si las operaciones de forman una transacción T que emite un cliente son consistentes, el servidor garantiza que la consistencia de los datos que T comparte con otra transacción U no va ser violada por la concurrencia de las operaciones de U. 3.4.3.3 Serializabilidad La tercera propiedad dice que las transacciones deben ser aisladas. Aislada significa transacciones concurrentes en un servidor no interfieren las unas con las otras. Una forma de lograr el aislamiento es anular la concurrencia del servidor de modo que ejecute las transacciones de forma estrictamente secuencial, una tras otra. El objetivo de un servidor, sin embargo es maximizar sus prestaciones, algo que pasa por la atención concurrente al mayor número de transacciones posible. Esto significa que si un servidor está atendiendo a dos o más transacciones simultáneamente que operan sobre datos compartidos por los clientes -un fichero, por ejemplo-, el servidor transaccional debe garantizar que el resultado final de estos datos es aquel que produce una realización estrictamente secuencial de las transacciones. Esta realización, no obstante, es decidida arbitrariamente por el servidor. Supongamos que un servidor transaccional mantiene una variable x que es accedida por tres clientes. Las transacciones de los clientes en un momento dado son las siguientes: Proceso 1: Abrir Transacción; x := 0; x := x + 1; Cerrar Transacción; Proceso 2: Abrir Transacción; x := 0; x := x + 2; Cerrar Transacción; Proceso 3: Abrir Transacción; x := 0; x := x + 3; Cerrar Transacción; Las peticiones de las distintas transacciones llegan al servidor entrelazadas. A cada secuencia de ejecución de las peticiones por parte del servidor se le llama entrelazado o planificación. Si el servidor es transaccional, no todas las planificaciones son válidas. En la tabla que sigue vemos tres planificaciones posibles, donde el tiempo transcurre hacia la derecha: Planificación 1 x := 0; x := x + 1; x := 0; x := x + 2; x := 0; x := x + 3; legal Planificación 2 x := 0; x := 0; x := x + 1; x := x + 2; x := 0; x := x + 3; legal
  • 20. Planificación 3 x := 0; x := 0; x := x + 1; x := 0; x := x + 2; x := x + 3; ilegal tiempo En la planificación 1 las transacciones son ejecutadas de forma estrictamente secuencial, y el valor final es 3. Decimos que esta planificación ha sido serializada. La planificación 2 no es serializada, pero es legal por que, al final, x toma un valor que podría haber sido alcanzado por una planificación estrictamente secuencial. La planificación 3 es ilegal, ya que x termina con un valor de 5, valor que imposible alcanzar con una planificación serializada. Equivalencia serial Si un entrelazado de dos o más transacciones tiene el mismo efecto sobre los datos que alguna ejecución serializada de dichas transacciones decimos que el entrelazado es serialmente equivalente. La planificación 2 de la figura es serialmente equivalente. 3.4.3.4 Durabilidad Una transacción debe ser durable. Esta propiedad establece que si un servidor compromete una transacción -por ejemplo con una réplica a una primitiva Cerrar Transacción(Trans)que devuelva el valor Compromiso-, no importa lo que ocurra, los cambios son ya permanentes. Ningún fallo después del compromiso puede desacer los resultados o causar su desaparición, con la consiguiente confusión posterior en el cliente. 2.3 Bibliografía [Cou95] Coulouris A. et al., Distributed Systems, 2nd. Edition. Addison-Wesley, 1995. [Tan95] Tanenbaum, A., Distributed Operating Systems, Prentice-Hall, 1995. [Cou94] Coulouris, G., Distributed Systems, Concepts and Design, Second Edition, Addison-Wesley, 1994. [Gra93] Gray, J., Reuter, A., Transaction Processing, Concepts and Techniques, Morgan Kaufmann Publishers, 1993. [Lam78] Lamport, L., “Time, Clocks, and the Ordering of Events in a Distributed System”, Communications of the ACM, Number 7, Volume 21, July, 1978. [Lis93] Liskov, B., “Practical uses of syncronized clocks in distributed systems”, Distributed Computing, No. 6, pp. 211–219, 1993. 2.1.1. Comunicación con los clientes-Servidor (Socket) Origen de los socket tuvo lugar en una variante del sistema operativo Unix conocida como BSD Unix. En la universidad de Berkeley, en los inicios del Internet, pronto se hizo evidente que los programadores necesitarían un medio sencillo y eficaz para escribir programas capaces de intercomunicarse entre sí. Esta necesidad dio origen a la primera especificación e implementación de sockets. Cliente-Servidor es el modelo que actualmente domina el ámbito de comunicación, ya que descentraliza los procesos y los recursos. Es un Sistema donde el cliente es una aplicación, en un equipo, que solicita un determinado servicio y existe un software, en otro equipo, que lo proporciona.
  • 21. Los servicios pueden ser; a)Ejecución de un programa. b)Acceso a una Base 2.1.2 comunicacion con rpc RCP (REMOTE PROCEDURE CALL) El mecanismo general para las aplicaciones cliente-servidor se proporciona por el paquete Remote Procedure Call (RPC). RPC fue desarrollado por Sun Microsystems y es una colección de herramientas y funciones de biblioteca. Aplicaciones importantes construidas sobre RPC son NIS, Sistema de Información de Red y NFS, Sistema de Ficheros de Red. Un servidor RPC consiste en una colección de procedimientos que un cliente puede solicitar por el envío de una petición RPC al servidor junto con los parámetros del procedimiento. El servidor invocará el procedimiento indicado en nombre del cliente, entregando el valor de retorno, si hay alguno. Para ser independiente de la máquina, todos los datos intercambiados entre el cliente y el servidor se convierten al formato External Data Representation (XDR) por el emisor, y son reconvertidos a la representación local por el receptor. RPC confía en sockets estandard UDP y TCP para transportar los datos en formato XDR hacia el host remoto. Sun amablemente a puesto RPC en el dominio público; se describe en una serie de RFCs. La comunicación entre servidores RPC y clientes es un tanto peculiar. Un servidor RPC ofrece una o más colecciones de procedimientos; cada conjunto se llama un programa y es idenficado de forma única por un número de programa. Una lista que relaciona nombres de servicio con números de programa se mantiene usualmente en /etc/rpc. En esta figura, la llamada remota toma 10 pasos, en el primero de los cuales el programa cliente (o procedimiento) llama al procedimiento stub enlazado en su propio espacio de direcciones. Los parámetros pueden pasarse de la manera usual y hasta aquí el cliente no nota nada inusual en esta llamada ya que es una llamada local normal. El stub cliente reúne luego los parámetros y los empaqueta en un mensaje. Esta operación se conoce como reunión de argumentos (parameter marshalling). Después que se ha construido el mensaje, se lo pasa a la capa de transporte para su transmisión (paso 2). En un sistema LAN con un servicio sin conexiones, la entidad de transporte probablemente sólo le agrega al mensaje un encabezamiento y lo coloca en la subred sin mayor trabajo (paso 3). En una WAN, la transmisión real puede ser más complicada. Cuando el mensaje llega al servidor, la entidad de transporte lo pasa al stub del servidor (paso 4), que desempaqueta los parámetros. El stub servidor llama luego al procedimiento servidor (paso 5), pasándole los parámetros de manera estándar. El procedimiento servidor no tiene forma de saber que está siendo activado remotamente, debido a que se lo llama desde un procedimiento local que cumple con todas las reglas estándares. Únicamente el stub sabe que está ocurriendo algo particular. Después que ha completado su trabajo, el procedimiento servidor retorna (paso 6) de la misma forma en que retornan otros procedimientos cuando terminan y, desde luego, puede retornar un resultado a un llamador. El stub servidor empaqueta luego el resultado en un mensaje y lo entrega a la interfaz con transporte (paso 7), posiblemente mediante una llamada al sistema, al igual que en el paso 2. Después que la respuesta retorna a la máquina cliente (paso 8), la misma se entrega al stub cliente (paso 9) que desempaqueta las respuestas. Finalmente, el stub cliente retorna a su llamador, el procedimiento cliente y cualquier valor devuelto por el servidor en el paso 6, se entrega al cliente en el paso 10. El propósito de todo el mecanismo de la Fig.1 es darle al cliente (procedimiento cliente) la ilusión de que está haciendo una llamada a un procedimiento local. Dado el éxito de la ilusión, ya que el cliente no puede saber que el
  • 22. servidor es remoto, se dice que el mecanismo es transparente. Sin embargo, una inspección más de cerca revela algunas dificultades en alcanzar la total transparencia. 2.1.3 comunicacion en grupo La comunicación se clasifica deacuerdo al numero de usuarios alos que se le a enviado el mensaje. -BROADCAST O DIFUSION FORZADA un nodo emite todos los escuchan y solo contesta a quien va dirigido el mensaje -MULTICAST se entrega el msj a todos los anfitriones HOST que están compuestos de ciertas características. -UNICAST o POINTCAST un nodo emite y otro recibe, solo escucha aquel a quien se dirigió el msj. Una clasificación adicional es la realizada en base a grupos -LISTAS DE DESTINARIOS se tiene una lista de aquellos alos que se les enviara el mensaje. -IDENTIFICADOR DE GRUPO se forman grupos y el msj es dirigido solo a los miembros de ese grupo. -PREDICADOR DE PERTENENCIA se envía y otro recibe, solo escucha aquel a quien se dirigió el mensaje. 2.1.4 tolerancia a fallos La difusión de los sistemas distribuidos incrementa la demanda de sistemas que esencialmente nunca fallen [25, Tanenbaum]. Los sistemas tolerantes a fallos requerirán cada vez más una considerable redundancia en hardware, comunicaciones, software, datos, etc. La réplica de archivos sería un requisito esencial. También debería contemplarse la posibilidad de que los sistemas funcionen aún con la carencia de parte de los datos. Los tiempos de fallo aceptables por los usuarios serán cada vez menores. 2.2 sincronizacion sistemas distribuidos En sistemas con una única CPU las regiones críticas, la exclusión mutua y otros problemas de sincronización son resueltos generalmente utilizando métodos como semáforos y monitores. Estos métodos no se ajustan para ser usados en sistemas distribuidos ya que invariablemente se basan en la existencia de una memoria compartida. No es posible reunir toda la información sobre el sistema en un punto y que luego algún proceso la examine y tome las decisiones. En general los algoritmos distribuidos tienen las siguientes propiedades: 1)- la información relevante está repartida entre muchas máquinas 2)- los procesos toman decisiones basadas solamente en la información local disponible 3) - debería poder evitarse un solo punto que falle en el sistema 4)- no existe un reloj común u otro tiempo global exacto
  • 23. Si para asignar un recurso de E/S un proceso debe recolectar información de todos los procesos para tomar la decisión esto implica una gran carga para este proceso y su caída afectaría en mucho al sistema. Idealmente, un sistema distribuido debería ser más confiable que las máquinas individuales. Alcanzar la sincronización sin la centralización requiere hacer cosas en forma distinta a los sistemas operativos tradicionales. 2.2.1 relojes fisicos El algoritmo de Lamport proporciona un orden de eventos sin ambigüedades, pero [25, Tanenbaum]: Los valores de tiempo asignados a los eventos no tienen porqué ser cercanos a los tiempos reales en los que ocurren. En ciertos sistemas (ej.: sistemas de tiempo real ), es importante la hora real del reloj: Se precisan relojes físicos externos (más de uno). Se deben sincronizar: Con los relojes del mundo real. Entre sí. La medición del tiempo real con alta precisión no es sencilla. Desde antiguo el tiempo se ha medido astronómicamente. Se considera el día solar al intervalo entre dos tránsitos consecutivos del sol, donde el tránsito del sol es el evento en que el sol alcanza su punto aparentemente más alto en el cielo. El segundo solar se define como 1 / 86.400 de un día solar. Como el período de rotación de la tierra no es constante, se considera el segundo solar promedio de un gran número de días. Los físicos definieron al segundo como el tiempo que tarda el átomo de cesio 133 para hacer 9.192.631.770 transiciones: Se tomó este número para que el segundo atómico coincida con el segundo solar promedio de 1958. La Oficina Internacional de la Hora en París (BIH) recibe las indicaciones de cerca de 50 relojes atómicos en el mundo y calcula el tiempo atómico internacional (TAI). Como consecuencia de que el día solar promedio (DSP) es cada vez mayor, un día TAI es 3 mseg menor que un DSP: La BIH introduce segundos de salto para hacer las correcciones necesarias para que permanezcan en fase: El sistema de tiempo basado en los segundos TAI. El movimiento aparente del sol. Surge el tiempo coordenado universal (UTC). El Instituto Nacional del Tiempo Estándar (NIST) de EE. UU. y de otros países: Operan estaciones de radio de onda corta o satélites de comunicaciones. Transmiten pulsos UTC con cierta regularidad establecida (cada segundo, cada 0,5 mseg, etc.). Se deben conocer con precisión la posición relativa del emisor y del receptor: Se debe compensar el retraso de propagación de la señal. Si la señal se recibe por módem también se debe compensar por la ruta de la señal y la velocidad del módem. Se dificulta la obtención del tiempo con una precisión extremadamente alta. 2.2.2 relojes logicos Las computadoras poseen un circuito para el registro del tiempo conocido como dispositivo reloj [25, Tanenbaum]. Es un cronómetro consistente en un cristal de cuarzo de precisión sometido a una tensión eléctrica que: • Oscila con una frecuencia bien definida que depende de: o Al forma en que se corte el cristal. o El tipo de cristal. o La magnitud de la tensión. • A cada cristal se le asocian dos registros:
  • 24. o Registro contador. o Registro mantenedor. • Cada oscilación del cristal decrementa en “1” al contador. • Cuando el contador llega a “0”: o Se genera una interrupción. o El contador se vuelve a cargar mediante el registro mantenedor. • Se puede programar un cronómetro para que genere una interrupción “x” veces por segundo. • Cada interrupción se denomina marca de reloj. Para una computadora y un reloj: • No interesan pequeños desfasajes del reloj porque: o Todos los procesos de la máquina usan el mismo reloj y tendrán consistencia interna. o Importan los tiempos relativos. Para varias computadoras con sus respectivos relojes: • Es imposible garantizar que los cristales de computadoras distintas oscilen con la misma frecuencia. • Habrá una pérdida de sincronía en los relojes (de software), es decir que tendrán valores distintos al ser leidos. La diferencia entre los valores del tiempo se llama distorsión del reloj y podría generar fallas en los programas dependientes del tiempo. Lamport demostró que la sincronización de relojes es posible y presentó un algoritmo para lograrlo. Lamport señaló que la sincronización de relojes no tiene que ser absoluta: • Si 2 procesos no interactúan no es necesario que sus relojes estén sincronizados. • Generalmente lo importante no es que los procesos estén de acuerdo en la hora, pero sí importa que coincidan en el orden en que ocurren los eventos. 2.2.3 usos de la sincroninizacion manejo de cache comunicacion en grupo exclusion mutua eleccion transacciones atomicas e interbloqueo memoria cache En los sistemas de archivos convencionales, el fundamento para la memoria caché es la reducción de la E/S de disco (lo que aumenta el rendimiento), en un SAD el objetivo es reducir el tráfico en la red. Esquema Básico, el concepto de memoria caché es sencillo, si los datos necesarios para satisfacer la solicitud de acceso no se encuentran en la memoria cache, se trae una copia de servicio al usuario y los accesos se llevan a cabo con la copia de memoria caché. La idea es conservar allí los bloques de disco de acceso mas reciente, para así manejar localmente los accesos repetidos a la misma información y no aumentar el tráfico de la red. Se utiliza una política de reemplazo (por ejemplo, la de utilización menos reciente) para limitar el tamaño de la memoria caché. Políticas de Actualización, la política empleada para escribir los bloques de datos modificados en la copia maestra del servidor tiene un efecto decisivo sobre la
  • 25. confiabilidad y el rendimiento del sistema. La política mas sencilla consiste en escribir los datos directamente en el disco tan pronto se coloquen en una memoria caché. La ventaja de la escritura directa es su confiabilidad, ya que se pierde poca información si un sistema cliente falla. Sin embargo, esta política requiere que cada acceso de escritura espere hasta que se envíe la información al servidor, por lo que representa una escritura de escaso rendimiento. La memoria caché con escritura directa equivale a usar el servicio remoto para accesos de escritura y explotar la memoria cache únicamente para accesos de lectura. NFS proporciona el acceso de escritura directa. Consistencia, una maquina cliente se enfrenta al problema de decidir si una copia de datos en memoria caché local es consistente con la copia maestra ( y por tanto, puede usarse). Si la maquina cliente determina que sus datos en memoria caché están desfasados, ya no pueden servir para los accesos y hay que colocar en la memoria caché una copia actualizada de los datos. Existen dos enfoques para verificar la validez de los datos en memoria caché ..: Enfoque iniciado por el cliente, el cliente inicia una comprobación de validez, en la cual se pone en contacto con el servidor y comprueban si los datos locales son consistentes con la copia maestra. Enfoque iniciado por el servidor, el servidor anota, para cada cliente, las partes de los archivos que coloca en memoria cache, y cuando detecta una inconsistencia, debe reaccionar. Una posible fuente inconsistencia ocurre cuando dos clientes, que trabajan en modos conflictivos, colocan en memoria caché un archivo. Comunicación en grupos (Algoritmos Para la Sincronización de Relojes) Si una máquina tiene un receptor de UTC, todas las máquinas deben sincronizarse con ella. Si ninguna máquina tiene un receptor de UTC: • Cada máquina lleva el registro de su propio tiempo. • Se debe mantener el tiempo de todas las máquinas tan cercano como sea posible. Se supone que cada máquina tiene un cronómetro que provoca una interrupción “h” veces por segundo. Cuando el cronómetro se detiene, el manejador de interrupciones añade “1” a un reloj en software. El reloj en software mantiene un registro del número de marcas (interrupciones) a partir de cierta fecha acordada antes; al valor de este reloj se lo llama “C”. Algoritmo de Cristian Es adecuado para sistemas en los que: • Una máquina tiene un receptor UTC, por lo que se la llama despachador del tiempo. • El objetivo es sincronizar todas las máquinas con ella. Cada máquina envía un mensaje al servidor para solicitar el tiempo actual, periódicamente, en un tiempo no mayor que è prontamente con un mensaje que contiene el tiempo actual “CUTC”. Cuando el emisor obtiene la respuesta puede hacer que su tiempo sea “CUTC”. Un gran problema es que el tiempo no puede correr hacia atrás: • “CUTC” no puede ser menor que el tiempo actual “C” del emisor. • La atención del requerimiento en el servidor de tiempos requiere un tiempo del manejador de interrupciones. • También se debe considerar el tiempo de transmisión. El cambio del reloj se debe introducir de manera global: • Si el cronómetro genera 100 interrupciones por segundo: Cada interrupción añade 10 mseg al tiempo. Para atrasar solo agregaría 9 mseg. Para adelantar agregaría 11 mseg. La corrección por el tiempo del servidor y el tiempo de transmisión se hace midiendo en el emisor: • El tiempo inicial (envío) “T0”. • El tiempo final (recepción) “T1”. • Ambos tiempos se miden con el mismo reloj. El tiempo de propagación del mensaje será (T1 - T0) / 2. Si el tiempo del servidor para manejar la interrupción y procesar el mensaje es “I”: • El tiempo de propagación será (T1 - T0 - I) / 2. Para mejorar la precisión: • Se toman varias mediciones. • Se descartan los valores extremos. • Se promedia el resto. El tiempo de propagación se suma al tiempo del servidor para sincronizar al emisor cuando éste recibe la respuesta. Algoritmo de Berkeley
  • 26. En el algoritmo de Cristian el servidor de tiempo es pasivo. En el algoritmo de Berkeley el servidor de tiempo: • Es activo. • Realiza un muestreo periódico de todas las máquinas para preguntarles el tiempo. • Con las respuestas: Calcula un tiempo promedio. Indica a las demás máquinas que avancen su reloj o disminuyan la velocidad del mismo hasta lograr la disminución requerida. Es adecuado cuando no se dispone de un receptor UTC. Algoritmos con Promedio Los anteriores son algoritmos centralizados. Una clase de algoritmos descentralizados divide el tiempo en intervalos de resincronización de longitud fija: • El i -ésimo intervalo: Inicia en “T0 + i R” y va hasta “T0 + (i + 1) R”. “T0” es un momento ya acordado en el pasado. “R” es un parámetro del sistema. Al inicio de cada intervalo cada máquina transmite el tiempo actual según su reloj. Debido a la diferente velocidad de los relojes las transmisiones no serán simultáneas. Luego de que una máquina transmite su hora, inicializa un cronómetro local para reunir las demás transmisiones que lleguen en cierto intervalo “S”. Cuando recibe todas las transmisiones se ejecuta un algoritmo para calcular una nueva hora para los relojes. Una variante es promediar los valores de todas las demás máquinas. Otra variante es descartar los valores extremos antes de promediar (los “m” mayores y los “m” menores). Una mejora al algoritmo considera la corrección por tiempos de propagación. Varias Fuentes Externas de Tiempo Los sistemas que requieren una sincronización muy precisa con UTC se pueden equipar con varios receptores de UTC. Las distintas fuentes de tiempo generaran distintos rangos (intervalos de tiempo) donde “caerán” los respectivos UTC, por lo que es necesaria una sincronización. Como la transmisión no es instantánea se genera una cierta incertidumbre en el tiempo. Cuando un procesador obtiene todos los rangos de UTC: • Verifica si alguno de ellos es ajeno a los demás y de serlo lo descarta por ser un valor extremo. • Calcula la intersección (en el tiempo) de los demás rangos. • La intersección determina un intervalo cuyo punto medio será el UTC y la hora del reloj interno. Se deben compensar los retrasos de transmisión y las diferencias de velocidades de los relojes. Se debe asegurar que el tiempo no corra hacia atrás. Se debe resincronizar periódicamente desde las fuentes externas de UTC. Exclusión Mutua Cuando un proceso debe leer o actualizar ciertas estructuras de datos compartidas: • Primero ingresa a una región crítica para lograr la exclusión mutua y garantizar que ningún otro proceso utilizará las estructuras de datos al mismo tiempo. En sistemas monoprocesadores las regiones críticas se protegen con semáforos, monitores y similares. En sistemas distribuidos la cuestión es más compleja. Un Algoritmo Centralizado La forma más directa de lograr la exclusión mutua en un sistema distribuido es simular a la forma en que se lleva a cabo en un sistema monoprocesador. Se elige un proceso coordinador. Cuando un proceso desea ingresar a una región crítica: • Envía un mensaje de solicitud al coordinador: Indicando la región crítica. Solicitando permiso de acceso. • Si ningún otro proceso está en ese momento en esa región crítica: El coordinador envía una respuesta otorgando el permiso.
  • 27. • Cuando llega la respuesta el proceso solicitante entra a la región crítica. Si un proceso pide permiso para entrar a una región crítica ya asignada a otro proceso: • El coordinador no otorga el permiso y encola el pedido. Cuando un proceso sale de la región crítica envía un mensaje al coordinador para liberar su acceso exclusivo: • El coordinador extrae el primer elemento de la cola de solicitudes diferidas y envía a ese proceso un mensaje otorgando el permiso, con lo cual el proceso queda habilitado para acceder a la región crítica solicitada. Es un esquema sencillo, justo y con pocos mensajes de control. La limitante es que el coordinador puede ser un cuello de botella y puede fallar y bloquear a los procesos que esperan una respuesta de habilitación de acceso. Un Algoritmo Distribuido El objetivo es no tener un único punto de fallo (el coordinador central). Un ej. es el algoritmo de Lamport mejorado por Ricart y Agrawala. Se requiere un orden total de todos los eventos en el sistema para saber cuál ocurrió primero. Cuando un proceso desea entrar a una región crítica: • Construye un mensaje con el nombre de la región crítica, su número de proceso y la hora actual. • Envía el mensaje a todos los demás procesos y de manera conceptual a él mismo. • Se supone que cada mensaje tiene un reconocimiento. Si el receptor no está en la región crítica y no desea entrar a ella, envía de regreso un mensaje o.k. al emisor. Si el receptor ya está en la región crítica no responde y encola la solicitud. Si el receptor desea entrar a la región crítica pero aún no lo logró, compara: • La marca de tiempo del mensaje recibido con, • La marca contenida en el mensaje que envió a cada uno. • La menor de las marcas gana. • Si el mensaje recibido es menor el receptor envía un o.k. • Si su propio mensaje tiene una marca menor el receptor no envía nada y encola el pedido. Luego de enviar las solicitudes un proceso: • Espera hasta que alguien más obtiene el permiso. • Cuando llegan todos los permisos puede entrar a la región crítica. Cuando un proceso sale de la región crítica: • Envía mensajes o.k. a todos los procesos en su cola. • Elimina a todos los elementos de la cola. La exclusión mutua queda garantizada sin bloqueo ni inanición. El número de mensajes necesarios por entrada es “2(n - 1)”, siendo “n” el número total de procesos en el sistema. No existe un único punto de fallo sino “n”: • Si cualquier proceso falla no responderá a las solicitudes. • La falta de respuesta se interpretará como negación de acceso: o Se bloquearán los siguientes intentos de los demás procesos por entrar a todas las regiones críticas. Se incrementa la probabilidad de fallo en “n” veces y también el tráfico en la red. Se puede solucionar el bloqueo si: • El emisor espera y sigue intentando hasta que regresa una respuesta o, • El emisor concluye que el destinatario está fuera de servicio. Otro problema es que: • Se utilizará una primitiva de comunicación en grupo o, • Cada proceso debe mantener la lista de miembros del grupo, incluyendo los procesos que ingresan, los que salen y los que fallan. • Se complica para gran número de procesos. Un importante problema adicional es que: • Todos los procesos participan en todas las decisiones referentes a las entradas en las regiones críticas. • Se sobrecarga el sistema. Una mejora consiste en permitir que un proceso entre a una región crítica con el permiso de una mayoría simple de los demás procesos (en vez de todos): • Luego de que un proceso otorgó el permiso a otro para entrar a una región crítica, no puede otorgar el mismo permiso a otro proceso hasta que el primero libere su permiso. Algoritmos de Elección Son los algoritmos para la elección de un proceso coordinador, iniciador, secuenciador, etc.. El objetivo de un algoritmo de elección es garantizar que iniciada una elección ésta concluya con el acuerdo de todos los procesos con respecto a la identidad del nuevo coordinador. Transacciones Atómicas Las técnicas de sincronización ya vistas son de bajo nivel: El programador debe enfrentarse directamente con los detalles de: La exclusión mutua. El manejo de las regiones críticas. La prevención de bloqueos. La recuperación de fallas.
  • 28. Se precisan técnicas de abstracción de mayor nivel que: Oculten estos aspectos técnicos. Permitan a los programadores concentrarse en los algoritmos y la forma en que los procesos trabajan juntos en paralelo. Tal abstracción la llamaremos transacción atómica, transacción o acción atómica. La principal propiedad de la transacción atómica es el “todo o nada”: O se hace todo lo que se tenía que hacer como una unidad o no se hace nada. Ejemplo: Un cliente llama al Banco mediante una PC con un módem para: Retirar dinero de una cuenta. Depositar el dinero en otra cuenta. La operación tiene dos etapas. Si la conexión telefónica falla luego de la primer etapa pero antes de la segunda: Habrá un retiro pero no un depósito. La solución consiste en agrupar las dos operaciones en una transacción atómica: Las dos operaciones terminarían o no terminaría ninguna. Se debe regresar al estado inicial si la transacción no puede concluir. El Modelo de Transacción Supondremos que: • El sistema consta de varios procesos independientes que pueden fallar aleatoriamente. El software subyacente maneja transparentemente los errores de comunicación. 2.3 NOMINACION CARACTERISTICAS Y ESTRUCTURAS. La nominación es una correspondencia entre objetos de datos lógicos y físicos. Por ejemplo, los usuarios tratan con objetos de datos lógicos representados por nombre de archivos, mientras que el sistema manipula bloques de datos físicos almacenados en las pistas de los discos. Generalmente un usuario se refiere a un archivo utilizando un nombre , el cual se transforma en un identificador numérico de bajo nivel, que a su vez se corresponde con bloques. Esta correspondencia multinivel ofrece a los usuarios la abstracción de un archivo, que oculta los detalles de cómo y donde se almacena el archivo en disco. En un SAD transparente se agrega una nueva dimensión de abstracción ..: la ocultación de la ubicación de los archivos de la red. En un sistema de archivos convencionales la función de nominación produce como resultado un intervalo de direcciones en disco, en un SAD este intervalo crece para incluir la máquina especifica en cuyo disco se almacena el archivo. Si se extiende un poco mas el tratamiento de los archivos como abstracciones, llegamos a la posibilidad de replicas de archivos. Dado un nombre de archivo, la correspondencia devuelve un conjunto de posiciones de las replicas de este archivo. En esta abstracción se ocultan tanto la experiencia de copias como su ubicación. Estructuras de Nominación ..: Existen dos conceptos que hay que distinguir en relación con al correspondencia de nombres en un SAD. Transparencia de Nominación, El nombre de archivo no revela ningún indicio sobre de la ubicación del almacenamiento físico del archivo.
  • 29. Independencia de Ubicación, No es necesario modificar el nombre de un archivo cuando cambia su ubicación en el almacenamiento físico. Esquema de Nominación ..: Hay tres enfoques principales para los esquemas de nominación en un SAD. En el enfoque mas sencillo, los archivos se nombran con una combinación del nombre de su anfitrión y su nombre local , lo que garantiza un nombre único dentro de todo el sistema. Por ejemplo, en Ibis, un archivo se identifica de manera única con el Nombre Anfitrión Local, donde nombre local es una ruta semejante a las de UNIX. El segundo enfoque popularizado por el sistema de archivos de red (NFS, Network File System) de sun, ofrece una forma de unir directorios remotos a directorios locales, lo que da la apariencia a un árbol de directorios coherentes. El tercer enfoque es la estructura mas compleja y difícil de mantener en la NFS, ya que cualquier directorio se puede unir a cualquier árbol de direcciones locales y la jerarquía resultante puede estar poco estructurada. 2.3.2 TIPOS DE NOMBRES DE USUARIO Y DE SISTEMAS Servidor de nombres En un sistema distribuido, se usa algún nombre para hacer referencia a algún recurso como nodos de procesamiento (computadoras), puertos, servicios y usuarios. Los nombres son útiles al momento en que se desea establecer una comunicación o compartir recursos en un sistema distribuido. A continuación se listan algunos tipos de nombres: Identificadores de puertos y procesos. Nombres textuales de servicios. Identificadores de recursos. Nombres de archivos. Direcciones físicas y lógicas de redes. Muchos de los nombres usados en un sistema distribuido se refieren a un servicio en particular; por ejemplo, un cliente (usuario o proceso) usa tal nombre para solicitar un determinado servicio para ejecutar alguna operación sobre un objeto o recurso con un nombre propio. A la asociación entre un nombre y un objeto se llama liga o conexión. Cada objeto en un sistema tiene ciertos atributos. Por ejemplo, los servicios y las computadoras tienen direcciones físicas; los usuarios cuentan con direcciones de correo electrónico, números telefónicos y direcciones de sus computadoras personales, agregando llaves de acceso, directorios de trabajo, etc. En general, los valores de los atributos o son valores primitivos tales como enteros o son en sí nombres, o una dirección de Internet como 221.230.321.111. Servicio de nombres. Un servicio de nombres administra una base de datos con las ligas que guardan entre sí un conjunto de nombres textuales (legibles a primera vista por humanos) y atributos de objetos tales como computadoras y usuarios. La operación que se presenta más comúnmente en un servicio de nombres es la resolución de un nombre; operación que consiste en encontrar sus atributos en la base de datos. En sistemas distribuidos, el uso de nombres para propósitos de comunicación no es del todo suficiente, por que los procesos de comunicación van de una computadora a otra, y es necesario el conocimiento de su ubicación. Esto nos lleva al problema de los nombres en un sistema de comunicaciones. Existen tres conceptos básicos en esta área: El nombre de un objeto, por ejemplo un recurso o servidor; especifica lo que busca un proceso. Una dirección especifica dónde se encuentra el objeto. Una ruta especifica cómo llegar ahí.
  • 30. Por lo regular, los nombres no consisten en simples cadenas, sino que también se forman de varios componentes llamados contextos; por ejemplo, Sistemas de encriptación Sistemas convencionales Sistemas modernos Sistemas de llave pública Sistemas de llave privada Sistemas convencionales de encriptación. Este tipo de encriptación se basa en la sustitución de cifras, en la cual, cada caracter en un texto claro o base es sustituido por otro caracter. Existen varias técnicas que a continuación se discuten: Cifra Caesar. En éste método, cada letra del texto original se transforma en la tercer letra siguiente en el alfabeto o tabla de códigos. Por ejemplo, el texto "CASA" es transformado en "FDVD", de acuerdo al equivalente en la tabla de códigos ASCII. Sustitución simple. En este método, cualquier permutación de letras puede ser identificado al lenguaje Español o Inglés y elimina la relación posicional de la Cifra Caesar, debido a que cada permutación de letras es una llave, hay 26! (>1026) llaves en una cifra como ésta, lo que hace muy costosa una búsqueda exhaustiva. Sin embargo, la cifra por sustitución simple preserva la frecuencia de sustitución de las letras de un alfabeto porque se ejecuta la misma sustitución en todas las ocurrencias de una letra, y puede usarse un análisis estadístico para desencriptar la cifra. Cifra polialfabética. La cifra polialfabética usa una secuencia periódica de n letras de sustitución, es decir; el método actúa con n sustituciones alfabéticas periódicamente. Este método puede tener un mayor impacto si se escoge apropiadamente la sustitución. Una forma de aplicar este método es usar la Cifra Caesar con diferentes llaves. Por ejemplo, se puede tener la secuencia de enteros 11, 19, 4, 22, 9, 25 y se obtendría el texto cifrado agregando repetidamente cada entero al texto original. Sistemas modernos de encriptación Los métodos de criptografía moderna van más allá de los métodos tradicionales y usan información representada en forma binaria (el texto original -plain text- y el texto cifra -cipher text- se mantienen en forma binaria). Generalmente, en estos métodos se conocen las técnicas de encriptación y desencriptación, pero la llave requerida para desencriptar el texto cifra se mantiene en secreto. Los esquemas de criptografía moderna se basan en el principio de la búsqueda exhaustiva, aunque se conozca el mecanismo de desencriptación, el procedimiento de desencriptación es tan intensivo computacionalmente, que tomaría un tiempo prohibitivo para encontrar la llave. Método de llave privada 2.3.3 RESOLUCION Y DISTRIBUCION En la estructura anterior se basan prácticamente la mayoría de los sistemas operativos actuales. Otra forma de ver este tipo de sistema es la denominada de anillos concéntricos o "rings" (Ver Fig. 4). En el sistema de anillos, cada uno tiene una apertura, conocida como puerta o trampa (trap), por donde pueden entrar las llamadas de las capas inferiores. De esta forma, las zonas más internas del sistema operativo o núcleo del sistema estarán más protegidas de accesos indeseados desde las capas más externas. Las capas más internas serán, por tanto, más privilegiadas que las externas. 1.3 Máquina Virtual. Se trata de un tipo de sistemas operativos que presentan una interface a cada proceso, mostrando una máquina que parece idéntica a la máquina real subyacente. Estos sistemas operativos separan dos conceptos que suelen estar unidos en el resto de sistemas: la multiprogramación y la máquina extendida. El objetivo de los sistemas operativos de máquina virtual es el de integrar distintos sistemas operativos dando la sensación de ser variasmáquinas diferentes.
  • 31. El núcleo de estos sistemas operativos se denomina monitor virtual y tiene como misión llevar a cabo la multiprogramación, presentando a los niveles superiores tantas máquinas virtuales como se soliciten. Estas máquinas virtuales no son máquinas extendidas, sino una réplica de la máquina real, de manera que en cada una de ellas se pueda ejecutar un sistema operativo diferente, que será el que ofrezca la máquina extendida al usuario (Ver Fig. 5). 1.4 Cliente-servidor ( Microkernel) El tipo más reciente de sistemas operativos es el denominado Cliente-servidor, que puede ser ejecutado en la mayoría de las computadoras, ya sean grandes o pequeñas. Este sistema sirve para toda clase de aplicaciones por tanto, es de propósito general y cumple con las mismas actividades que los sistemas operativos convencionales. El núcleo tiene como misión establecer la comunicación entre los clientes y los servidores. Los procesos pueden ser tanto servidores como clientes. Por ejemplo, un programa de aplicación normal es un cliente que llama al servidor correspondiente para acceder a un archivo o realizar una operación de entrada/salida sobre un dispositivo concreto. A su vez, un proceso cliente puede actuar como servidor para otro." [Alcal92]. Este paradigma ofrece gran flexibilidad en cuanto a los servicios posibles en el sistema final, ya que el núcleo provee solamente funciones muy básicas de memoria, entrada/salida, archivos y procesos, dejando a los servidores proveer la mayoría que el usuario final o programador puede usar. Estos servidores deben tener mecanismos de seguridad y protección que, a su vez, serán filtrados por el núcleo que controla el hardware. 2 Sistemas Operativos por Servicios Esta clasificación es la más comúnmente usada y conocida desde el punto de vista del usuario final. Esta clasificación se comprende fácilmente con el cuadro sinóptico que a continuación se muestra en la Fig. 6. 2.3.4 SERVIDORES Y AGENTES DE NOMBRES En la actualidad, la ICANN está formalmente organizada como una corporación sin fines de lucro y de utilidad pública. Está administrada por una Junta de Directores, que está compuesta por seis representantes de las organizaciones de apoyo, sub- grupos que se ocupan de las secciones específicas de las políticas de ICANN en virtud de la competencia, ocho representantes independientes del interés público general, seleccionados a través de un Comité de Nominaciones que representa a todas las circunscripciones de la ICANN, y el Presidente y Director Ejecutivo, nombrado por el resto de la Junta. En la actualidad hay tres organizaciones de apoyo: la GNSO (Generic Names Supporting Organization) se ocupa de la formulación de políticas sobre dominios genéricos de nivel superior, ccNSO (Country Code Names Supporting Organization) se ocupa de la elaboración de políticas relativas a códigos de países en dominios de nivel superior, la ASO (Address Supporting Organization) se ocupa de la formulación de políticas en direcciones IP. ICANN también se basa en algunos comités consultivos para recibir asesoramiento sobre los intereses y necesidades de los interesados que no participen directamente en las organizaciones de apoyo. Entre ellos figuran el Comité Asesor Gubernamental (GAC), que está integrado por representantes de un gran número de gobiernos nacionales de todo el mundo; el ALAC (At-Large Advisory Comité), que está integrado por representantes de organizaciones de los distintos usuarios de Internet de todo el mundo; el sistema DNS y TLG (Technical Liaison Group) compuesto por representantes de otras organizaciones técnicas internacionales de Internet. 2.3.5 MAPEO DE DIRECCIONES
  • 32. Para poder ejecutar instrucciones, si no sabemos en qué parte de la memoria estarán cargadas, debemos tener un mecanismo de traducción de direcciones virtuales a reales. Para ello, se necesitan dos cosas. Primero, el compilador manejará una dirección base más un desplazamiento al referirse a las instrucciones. Segundo, el sistema operativo asignará como dirección base el número de página, al paginar al proceso. De esta manera, puede buscarse el inicio de una página en memoria, sumarle el desplazamiento y así obtener la dirección real de una instrucción. Nótese que en el diagrama se tiene una tabla de proceso y ahí mismo se maneja la dirección inicial de la tabla de páginas. En algunos sistemas operativos, estas dos tablas se manejan por separado. La traducción de direcciones virtuales para segmentos se maneja de manera similar. Existe un esquema adicional, paginación/segmentación, que es la combinación de ambos. La memoria se divide en marcos de página, idealmente más pequeños que el tamaño del marco de página en un sistema de paginación tradicional. Cada segmento está compuesto por cierto número de páginas. Es decir, el tamaño del segmento es un múltiplo del tamaño de página. Este esquema pretende sacar ventaja de los beneficios de los otros dos. Este mismo mecanismo de traducción de direcciones virtuales puede aplicarse en paginación/segmentación. Recordemos que este mapeo debe efectuarse siempre, instrucción por instrucción ejecutada. Por ello, entre más rápido sea el mecanismo, mejor. Existe una manera de mejorar dicho mecanismo mediante hardware. Una memoria asociativa es muy cara, pero permite buscar en toda la memoria en un mismo pulso de reloj. Implementando memoria asociativa, podemos traducir direcciones para páginas o segmentos. Sin embargo, el utilizar memoria asociativa implica que el número de marcos de página y/o el número de segmentos, se ve limitado por el tamaño de la memoria asociativa. Es decir, no puede haber más marcos de página que número de celdas en la memoria asociativa. Por ello, hay sistemas operativos que manejan una combinación de ambos. Se cargan a memoria las páginas/segmentos más utilizados, y la traducción se utiliza de manera normal. Solamente en aquellos casos en los que no encontrara la página/segmento en la memoria asociativa, efectuaría la traducción directa. Para esa instrucción, haría un doble mapeo. Sin embargo, el principio de localidad nos asegura que esto no sucederá con frecuencia. 2.3.6 MAPEO DE RUTAS El “Technology Roadmapping” o mapeo de rutas tecnológicas, es un método específicamente desarrollado para la realización de estudios de Prospectiva Tecnológica. El modelo se basa en las directrices dictadas por las necesidades del mercado ayudando a identificar, seleccionar y desarrollar con posterioridad las alternativas de tecnología necesarias para satisfacer un conjunto de necesidades de un producto. Se trata de una prospectiva por objetivos que, entre otras funciones, ayuda a identificar necesidades y tecnologías, proporciona información necesaria en la toma de decisiones, identifica tecnologías críticas o vacíos en tecnología que deben llenarse para poder desarrollar productos con desempeños específicos y analiza el proceso a través del tiempo. 5.1. QUE ES EL ROADMAP?
  • 33. El Roadmap o “Mapeo de rutas” describe un ambiente futuro, los objetivos que pueden llegar a obtenerse con ese ambiente y los planes para lograr los objetivos planteados a través del tiempo. Explicita una estructura, o arquitectura, como una vía para el entendimiento de cómo las partes de un complejo sistema tecnológico encajan, interactúan y evolucionan. Así mismo, articula aplicaciones, desafíos tecnológicos y soluciones tecnológicas en forma conjunta y ayuda a establecer las prioridades para la consecución de los objetivos. QUE ES EL ROADMAPPING? La mejor hoja de ruta es creada a partir de un trabajo en equipo, recibiendo las visiones y el conocimiento de un grupo de personas que llevan a cabo el plan de mapeo de rutas. El proceso de Roadmapping ayuda al equipo a reunir diversas perspectivas sobre todos los aspectos del ambiente y del plan. Así mismo ayuda al equipo a construir un consenso para llevar a cabo el plan de acción. El mapeo de rutas también es la base para la descripción de los objetivos. ESTRUCTURA DEL ROADMAPPING El mapeo de rutas explicita campos de acción y permite trazar directrices para el planteamiento de acciones orientadas a responder o desarrollar completamente un conjunto de preguntas: “Por qué – Qué – Cómo - Cuándo” elementos importantes para poder desarrollar planes y proyectos de acción en la dirección de los objetivos planteados y alcanzar las metas buscadas. La siguiente figura describe las cuatro partes de la arquitectura con base en un mapeo de rutas. El mapeo de rutas puede ser construido comenzando con la definición de las principales necesidades del mercado para luego definir las tecnologías necesarias. (Prospectiva por entradas del mercado). Recíprocamente, al mapeo también puede comenzar con la definición de tecnologías claves y proseguir con los requerimientos del mercado que pueden ser satisfechos con esas tecnologías. (Prospectiva por entradas de tecnologías) 2.3.7 MODELO DE TERRY Estudio del rendimiento de la factibilidad de nombramiento, el modelo de Terry 4.8.1 Terry el modelo para estudiar actuación Los mensajes remitentes entre los procesos y objetos soportados por un sistema operativo precisa la presentación para el sistema operativo de los nombres de los objetos que los procesos quieren ganar acceso a. El problema es cómo localizar objetos nombrados. Esto está directamente conectado a la gerencia del espacio de nombre y las estructuras de la facilidad de nombramiento. Como ha visto, acto de servidores de nombre como agentes obligatorios distribuidos que amarran el nombre de un objeto para una cierta cantidad de sus propiedades, incluyendo la posición del objeto. Algunos servidores de nombre pueden almacenar información acerca de los objetos particulares. Tales servidores de nombre se llaman las autoridades que nombra o servidores
  • 34. autoritarios de nombre para eso objetan. El problema es cómo distribuir servidores de nombre, esto es, que de las estructuras de una facilidad de nombramiento es el mejor. Los criterios diferentes pueden ser tomados en cuenta al desarrollar la facilidad de nombramiento para sistemas de cómputo distribuidos. En la etapa de análisis de la estructura de facilidad de nombramiento, usaremos la mayor parte de importante de esos criterios, a saber actuación. Este criterio es importante para un ambiente distribuido porque que hay usualmente un número de redes interconectadas (lo mismo es cierto en caso de una red de área local conectando un número grande de computadoras personales y / o los puestos de trabajo, y los servidores diferentes), lo cual insinúa que el costo de comunicación entre clientes y servidores de nombre es el cuello de botella principal en localizar recursos remotos. En este caso, la actuación de averiguaciones del servidor de nombre es dominada por el número de servidores de nombre que deben ser a los que se ganó acceso y el costo de ganar acceso a esos los servidores de nombre. Los factores que afectan la eficiencia con la cual el espacio de nombre puede ser manejado y el costo de recuperar información del servidor de nombre son: + El di denota el costo de ejecutar una averiguación en NS, éste costado depende de tales factores como el tamaño global de la base de datos mantenida por NSi, y la clase de instalaciones de la base de datos utilizaron. Se asume que se compone con el paso del tiempo. + El cui es el costo de comunicar con NSi de cliente u, depende del sitio en el cual el cliente ejecuta, Este costo depende de tales factores como el número de portales de acceso atravesados, y la velocidad de líneas de transmisión. + El CUi especifica el costo completo de ganar acceso al servidor de nombre, NSi, remotamente de cliente u, y sea expresada por la siguiente fórmula: El costo de recuperar la información del servidor de nombre acerca de un set de denominado así es que urce s depende de posición del cliente relativo a servidores diversos de nombre y la mezcla remisiva del cliente y puede ser expresado por la fórmula: Donde Luk representa el coste total de poner en duda la información en partición de la base de datos dk, incluir el costo de localizar los datos deseados. Porque estamos interesados en el costo de recuperar la entrada del servidor de nombre de un objeto individual, ignoraremos los patrones de acceso del cliente en E (Lu) ‘ concentrándose sólo en Luk ‘ 4.8.2 Structures de la facilidad de nombramiento Las siguientes estructuras básicas de facilidad de nombramiento para los sistemas operativos distribuidos han sido identificadas por Terry (1984) e Indulska y Goscinski (1989): (1) una facilidad centralizada de nombramiento (2) una facilidad replegada de nombramiento (3) una facilidad descentralizada de nombramiento (4) una facilidad distribuida de nombramiento (5) una facilidad jerárquica de nombramiento. Una cierta cantidad de estas estructuras y sus modificaciones son ilustradas en Fig.7.29. Las estructuras de facilidad Fig. 7.29 Nombre. El sistema (5) centralizado, – (6) - el sistema replegado, (7) el sistema descentralizado con división en los tipos del objeto, (1) completamente distribuyó sistema (2) recursos locales conocidos en cada nodo y el mensaje emitido por radio pasando para servidores del recurso en cada nodo, (3) distribuyó sistema (4) recursos
  • 35. locales conocidos en cada nodo, sistema con creces distribuido dirección del recurso determinó por una función de hashing que se definió sobre el set de identificadores del recurso, jerárquico -. Ahora, describiremos estas estructuras de facilidad de nombramiento enfatizando evaluación de rendimiento. La presentación de estos temas se basa en la actuación que el modelo desarrolló por Terry, y también por Indulska y Goscinski. Las instalaciones centralizadas de nombramiento Una facilidad centralizada de nombramiento es implementada usando un servidor solo de nombre, lo cual mantiene una mesa o base de datos con tal que el nombre necesario para ocuparse de mapeos. Este sistema maneja un espacio plano de nombre donde los nombres son cadenas de caracteres no exhibiendo estructura. La base de datos del servidor de nombre es aumentada registrando servicios, va en procesión, pone a babor (los buzones) y otros detalles pertinentes que quieren ser públicamente sabidos. Los directorios del archivo pueden ser considerados como una causa especial de servicio de nombre. En este caso, Sk = NS. El servidor de nombre contiene que la colección completa de información aproximadamente toda nombró objetos en el ambiente distribuido. El costo de recuperación es simplemente Lk = C, dónde la C especifica el coste máximo de ganar acceso a servidor de nombre NS remotamente por la u más lejana del cliente. La ventaja de esta estructura de nombramiento es su simplicidad, y la evitación de cualquier problemas de incongruencia que se identificó en algunos sistemas con más que un servidor. Las desventajas son fiabilidad de punto bajo del sistema enteramente distribuido, y el tráfico grande los retrasos aéreos y largos en ganar acceso al servidor y antes de iniciar una transmisión orientada en servicio requerida. Los sistemas replegados de nombramiento Una facilidad replegada de nombramiento maneja un espacio plano de nombre también. Cada nodo de la computadora (el sitio) del sistema distribuido mantiene una copia de la base de datos con tal que los mapeos del nombre a la dirección necesarios para el sistema entero. En este caso, Sk = { NS1. . . , NSN } ‘ Porque cada servidor de nombre contiene una” colección completa ‘ De información aproximadamente toda nombró objetos (los recursos) del sistema distribuido, cualquier cliente puede interrogar el servidor de nombre físicamente más cercano, implícito aquí N Smain” que éste significa que el costo de recuperación es simplemente cañería maestra Lk = C. Este sistema tiene las siguientes ventajas: Es muy rápido, que no tiene retrasos de levantes obligatorios de operación, el número de mensajes de orientes obligatorio es cero, y tiene fiabilidad alta. El problema mantienen consistencia entre copias, nombran problemas de materialización (si un proceso muere, entonces o un servicio se vuelve agotado) y requisitos grandes de memoria de cada nodo. La entrada de la base de datos de nombre orientó descentralizó sistemas Una entrada de la base de datos de nombre orientó descentralizó sistema también maneja un espacio plano de nombre, pero cada entrada del servidor de nombre es almacenada en algún sitio arbitrario. En este caso, Sk = { NS ¡ }. Tal solución para una estructura de facilidad de nombramiento insinúa que el almacenamiento y los problemas de consistencia, mencionadas en el acercamiento previo, es evitado. Ésta es la ventaja principal de esta estructura. El inconveniente de este sistema localiza los datos deseados, porque eso arruine necesite interrogar cada servidor de nombre. Por término medio, la mitad de servidores de
  • 36. nombre deben ser a los que se ganó acceso para recuperar información del objeto. Dado que los saques de nombre son puestos en duda en la ordenación numérica, la recuperación costada es como sigue: Este sistema es valioso en términos de búsquedas del servidor de nombre. Una modificación simple del citado anteriormente sistema es la facilidad distribuida de nombramiento. En este sistema cada nodo de la computadora (el sitio) mantiene una base de datos con tal que la dirección - nombre necesaria haciendo mapas para sus propios objetos locales (los procesos, los puertos, los servicios, los recursos). Este sistema requiere difundir en la red el nombre de un objeto pedido. Ninguno de los sistemas descritos anteriormente son muy prácticos para sistemas distribuidos grandes. La situación puede ser mejorada añadiendo estructura para el nombre de un objeto. Esta estructura debería reflejar la autoridad de la gerencia para el nombre. Los sistemas descentralizados de nombramiento Una facilidad descentralizada de nombramiento es implementada usando un número de servidores de nombre operando en los dominios estrictamente definidos. La estructura se agrega para el nombre de un objeto (resource’s) para reflejar la autoridad de la gerencia para el nombre. La siguiente convención de nombramiento puede ser usada: _ el servidor (1) correcto de @ nombre de _ nombre, donde _ el servidor de nombre identifica el servidor de nombre esto es responsable para información directiva acerca del objeto, y _ el nombre (2) correcto sin ambigüedades identifica el objeto en el contexto de la autoridad que nombra. Si los servidores de nombre son sin ambigüedades nombrados luego el nombre completo _ servidor correcto de @ nombre de _ nombre es globalmente inequívoco. La gerencia efectiva de tal espacio de nombre siguiendo esta convención de nombramiento requiere que cada servidor de nombre sabe la posición de otros servidores de nombre. Hay avances diferentes para descentralizar un espacio de nombre: La partición de discos (1) geográfica (el reconocimiento médico): Si el sistema está compuesto de redes de área local múltiples conectadas de por ahí cruzan s y portales de acceso, entonces es natural tener un servidor de nombre para cada red; Y La partición de discos (2) organizativa (funcional): La partición del sistema entero en los dominios puede estar hecha con base en organizaciones. Básicamente dividieron en partes nombrando sistemas individuales mapeo existe entre particiones de la base de datos y servidores de nombre, esto es, = la N de kilobyte y Sk = { NSk }. Tal estructura requiere dos accesos para obtener la información acerca de un objeto dado (el recurso): Uno para hallar la autoridad que nombra y uno para ganar acceso a los datos. Sólo un acceso es menester cuando la información deseada de nombramiento es almacenada en el servidor primario de nombre, N Smain. El costo de búsqueda es expresado por la fórmula: Organizacionalmente dividieron en partes nombrando sistemas las particiones de la base de datos corresponda a las organizaciones en vez de servidores de nombre. Cada servidor de nombre puede ser la autoridad para algún subconjunto de las
  • 37. organizaciones. En este caso los nombres toman la forma @ organización correcta de _ nombre en la cual la autoridad para asignar nombres es explícitamente reconocida. En este caso el servicio de nombre puede ser con holgura uso reconfigurado del beca la asignación de objeto nombres es independiente de la asignación de la responsabilidad para mantener información acerca de los objetos. Consideremos los costos de búsqueda. Suponga, por el momento, que los datos de cada organización están bajo la dirección de un servidor solo de nombre al igual que con un espacio de nombre físicamente subdividido, Sk = { NSJ. Para eficazmente ganar acceso a información acerca de un objeto dado, cada servidor de nombre debería saber cuál servidor de nombre tiene responsabilidad para cada orgaiización. Basadas en esta estructura, las averiguaciones del servidor de nombre pueden ser tramitadas en pasos dobles como en sistemas de nombramiento físicamente subdivididos. El costo de búsqueda es expresado como sigue: Dos recuperaciones de la base de datos son siempre precisadas desde que un servidor de nombre no puede determinar de todos modos es la autoridad para los datos deseados sin consultar la base de datos local. Si el servidor primario de nombre puede recuperar y puede devolver la entrada del servidor de nombre directamente al descubrir que es el sitio de almacenamiento para los datos deseados, entonces luego Una de las ventajas más importantes de un espacio de nombre de organizacional-Partición es la facilidad con la cual la información replegada de nombramiento puede ser acomodada. Esto quiere decir que la base de datos del servidor de nombre puede a medias ser redundante. Del punto de la gerencia de vista, la copia soportadora requiere que el algoritmo de búsqueda describió arriba esté extendido de tal manera en lo que se refiere a reconocer varios servidores autoritarios de nombre para cada organización en vez de uno responsable solo. Como consecuencia, cada servidor de nombre debería saber la colección completa de servidores autoritarios de nombre para cada organización, Sk. Un ejemplo de un sistema basado en este acercamiento es el sistema Grapevine (Birrell Et Al. 1982). El costo de búsqueda del servidor de nombre viene bien