Conceptos Clave en Sistemas Distribuidos: Sockets, MPI, Interbloqueos y Consistencia


Middleware y Sistemas Distribuidos

El Middleware es un software específico que proporciona una capa a las aplicaciones distribuidas para que no tengan que lidiar con la heterogeneidad de un sistema distribuido. Facilita el desarrollo y la portabilidad de aplicaciones, proporciona interoperabilidad y, en ocasiones, asume funciones del sistema operativo.

Aspectos Comunes de los Sistemas Distribuidos

  • No existe reloj físico común.
  • No se comparten niveles de memoria.
  • Acoplamiento entre nodos.
  • Posible separación geográfica.
  • Heterogeneidad.
  • Funcionamiento autónomo y concurrente.

Protocolos Necesarios para un Sistema Distribuido

  • Resumen del estado global (snapshot)
  • Exclusión mutua
  • Detección de terminación
  • Detección de interbloqueos
  • Consenso
  • Replicación

Filosofías de Diseño de los Sistemas Distribuidos

Existen dos enfoques principales:

  1. Apenas modificar los sistemas operativos locales y trabajar con ellos en red, dejando toda la responsabilidad de resolver problemas a un middleware.
  2. Proponer un sistema operativo distribuido que contenga todas las funciones necesarias (mediante parches o modificaciones del kernel).

Tipos de Implementación en Sistemas Monolíticos

Implementación por Capas

Las capas están ordenadas de más cerca del hardware a más cerca del usuario/aplicaciones. En este tipo de implementación, cada capa confía en la que tiene debajo, sin tener que conocerla. Su principal problema es el rendimiento. Ejemplo: UNIX.

Implementación Basada en Microkernel

Se elimina del kernel del sistema operativo lo no esencial, reduciéndolo a un microkernel. Son fáciles de modificar, extender y son portables. Ejemplos: Windows NT o QNX.

Implementación Modular

Aprovechan las propiedades de los lenguajes de programación orientada a objetos. Es parecido al microkernel, pero sin paso de mensajes; aquí el kernel enlaza módulos con otros módulos. Los modelos se agrupan por funcionalidad sin un orden estricto (a diferencia del sistema por capas). Ejemplo: Linux.

Sockets y MPI: Comunicación en Sistemas Distribuidos

Sockets: ¿Para qué sirven?

Un socket es un hilo existente en el nodo cliente (que inicia la conexión) y en el servidor, que permite que los datos se transfieran hacia el proceso involucrado en la comunicación desde la tarjeta de red. Sirven para transferir información entre el cliente y el servidor.

MPI (Message Passing Interface)

MPI es un modelo de comunicación donde diferentes procesos se pueden comunicar de manera explícita a través de la red de comunicaciones en la arquitectura, siendo el paso de mensajes mediante primitivas de envío y recepción de mensajes. Es un estándar de facto en librerías de paso de mensajes (C, C++ y Fortran). Ejemplos de versiones: MPICH, STAMPI.

Tipos de Primitivas MPI (Funciones)

  • Funciones para gestión del entorno MPI: MPI_Init, MPI_Size, MPI_Rank, MPI_Finalize.
  • Funciones de comunicación punto a punto bloqueantes: MPI_Send y MPI_Recv.
  • Funciones de comunicación punto a punto no bloqueantes: MPI_Isend y MPI_Irecv.
  • Funciones de comunicación colectivas (todas bloqueantes): broadcast, scatter, gather, reduction.
  • Funciones para gestión y definición de tipos de datos.

El comunicador define grupos de tareas, como MPI_COMM_WORLD.

También se manejan etiquetas para clasificar los temas de los mensajes, como MPI_ANY_TAG.

Diferencia entre Funciones Bloqueantes y No Bloqueantes

  • Las no bloqueantes permiten solapar cómputo con comunicaciones.
  • Una vez invocada la función de envío o recepción, se retorna al programa sin que la primitiva de comunicación se complete.
  • En las funciones bloqueantes no se continúa con la comunicación hasta que el envío o recepción se complete.

Detección de Interbloqueos (Deadlocks)

Existen tres estrategias para lidiar con los interbloqueos en sistemas distribuidos:

  • Prevención: Se evita el interbloqueo haciendo que cada proceso reserve o asigne todos los recursos que necesita simultáneamente. No hay esperas.
  • Evitación: Se asigna un recurso a un proceso solo si se comprueba en tiempo real que la asignación no provoca interbloqueo. Para saberlo, se necesitan snapshots del estado global.
  • Detección: Es la estrategia más utilizada. Se monitoriza en tiempo real la aparición de interbloqueos. Si se detecta alguno, se resuelve abortando un proceso o retirándole el permiso para que utilice el recurso. Es la más complicada, pero la más eficiente, y tiene dos propiedades:
    • Progreso: Capacidad para detectar en tiempo real interbloqueos en el sistema.
    • Seguridad: Asegurar realmente que si detecta un interbloqueo, este es real.

La detección de interbloqueos trabaja con grafos llamados WFG (Wait-For Graph).

Existe interbloqueo cuando hay un ciclo dirigido en el grafo.

Tipos de Detección de Interbloqueos

  • Path-pushing
  • Edge-chasing
  • Por difusión
  • Basado en estado global

Consenso en Sistemas Distribuidos

Cuando los procesos necesitan llegar a un acuerdo sobre un aspecto, es un problema complejo de resolver y depende de variables como: comunicación asíncrona, tipos de canales de comunicación, modelo de fallos, y posibilidad de autenticar la comunicación.

Construcción del Espacio de Memoria Compartida Distribuida (DSM)

Tipos de DSM

  • Page-based DSM: Cualquier página del espacio de direcciones puede ubicarse en cualquiera de las memorias físicas del sistema. El DOS (Sistema Operativo Distribuido) captura los accesos y traduce los mensajes para mover los bloques de información, trabajando con interrupciones en los procesadores. Se usan cachés para las páginas que solo se leen e invalidación para escritura.
  • Shared-variable DSM: No se comparte todo el espacio de direcciones de memoria, solo se marcan las direcciones y estructuras compartidas. Además, no requiere mucho trabajo del DOS, permitiendo trabajar más compiladores y librerías.
  • Shared-objects DSM: En el modelo anterior se depende de que el programador marque las variables y estructuras compartidas. Aquí se hace una abstracción que permite que cualquier proceso pueda invocar a cualquier objeto en el espacio de objetos compartidos, independientemente de su ubicación.

Problemas a Resolver en la Memoria Compartida Distribuida

  • Coherencia: Resolver problemas de snooping o de directorio.
  • Consistencia: Se resuelve mediante la definición de modelos de alto nivel.
  • Sincronización: Se resuelve mediante mecanismos como cerrojos y semáforos.

Modelos de Consistencia

  • Modelo de Consistencia Estricta: La lectura de cualquier variable devuelve el valor más reciente escrito. Todos los procesadores observan que las operaciones de escritura y lectura se hacen atómicamente y secuencialmente, en el mismo orden para todas las operaciones. Se tiene que simular el tiempo global, lo que lo hace costoso.
  • Modelo de Consistencia Secuencial: Las operaciones se ordenan de manera secuencial. Cualquier orden es posible, pero los procesadores lo observan de la misma forma en cada ejecución. Este orden debe cumplir una condición (operaciones locales en el orden del programa). Es menos costoso y no requiere simular el tiempo global, aunque no garantiza la escritura más reciente.
  • Modelo de Consistencia Causal: No se exige un orden total, solo se debe observar el mismo orden para las escrituras entre las que haya una relación causal. La implementación es similar al modelo secuencial.
  • Modelo de Consistencia PRAM (Pipelined Random Access Memory): Es un modelo más flexible. Las escrituras se consideran concurrentes. Los procesadores observan el mismo orden para las escrituras realizadas por un mismo procesador, pero no para las de diferentes procesadores. Trabaja como un búfer FIFO.
  • Modelo de Slow Memory: Más flexible que el anterior. Solo se debe observar el mismo orden para las escrituras lanzadas por un mismo procesador. El resto de órdenes no influye.

Dejar un Comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *