Está en la página 1de 42

Sistemas Distribuidos

Tema 4 – Patrones para mejorar la eficiencia y escalabilidad de


arquitecturas distribuidas

Diego Sevilla Ruiz

DITEC
Facultad de Informática

Murcia, noviembre de 2007

Diego Sevilla Ruiz DITEC Facultad de Informática


Sistemas Distribuidos
Índice

◮ INTRODUCCIÓN
◮ Aspectos especı́ficos de diseño para aplicaciones distribuidas
◮ Eficiencia y escalabilidad en sistemas distribuidos
◮ PATRONES PARA EFICIENCIA Y ESCALABILIDAD
◮ Diseño de interfaces remotas (fat operations, coarse object
models, wrapper)
◮ Escalabilidad en el número de objetos y clientes
◮ Manejo de threads de ejecución
◮ Patrón Evictor
Bibliografı́a: F. Bellas (§3.5), Henning & Vinoski (§12.6), Schmidt
(POSA2)

Diego Sevilla Ruiz DITEC Facultad de Informática


Sistemas Distribuidos
Aspectos de diseño para app. distribuidas

◮ El diseño de aplicaciones distribuidas está guiado por los


requisitos de los sistemas de computación:
◮ Eficiencia
◮ Mantenimiento
◮ Escalabilidad
◮ Pero adaptados a las aplicaciones distribuidas:
◮ Diseño de interfaces adecuados a las llamadas remotas
◮ Manejo eficiente de threads y servicio concurrente
◮ Tratamiento de múltiples clientes
◮ Protocolos de comunicación flexibles (multicast, etc.)
◮ Servicios y componentes reutilizables
◮ Administración sencilla de servicios
◮ Procesos de deployment automatizables

Diego Sevilla Ruiz DITEC Facultad de Informática


Sistemas Distribuidos
Diseño de interfaces remotas

◮ Lo adaptaremos para IDL:


◮ Buen estilo de IDL
◮ Diseño de IDL eficiente
◮ Patrones de IDL

Diego Sevilla Ruiz DITEC Facultad de Informática


Sistemas Distribuidos
Buen estilo de IDL

◮ Evitar el espacio de nombres global


◮ Un módulo por fichero IDL
◮ Nada fuera de un módulo
◮ Módulos anidados si es necesario/útil
◮ uso de #ifdef:
// Fichero Control.idl
#include <YYY.idl>
#ifndef _CONTROL_IDL_
#define _CONTROL_IDL_
module Control
{ ... };
#endif

Diego Sevilla Ruiz DITEC Facultad de Informática


Sistemas Distribuidos
Diseño de IDL eficiente

◮ Granularidad
◮ Algunos ORBs optimizan las llamadas locales
◮ Los objetos de granularidad baja pueden ser útiles
◮ Sin embargo, en general
◮ Los objetos pueden estar en remoto
◮ Para obtener los datos de un objeto, hacen falta varias
llamadas remotas
◮ Patrón “Fat Operations”

Diego Sevilla Ruiz DITEC Facultad de Informática


Sistemas Distribuidos
Diseño de IDL eficiente

◮ Un diseño tan sencillo como:

interface SensorAire {
readonly attribute float temperatura;
readonly attribute float presión;
readonly attribute float humedad;
readonly attribute float velocidad_viento;
};
◮ Mismo proceso: 0.01 µs
◮ Distintos procesos, mismo sistema: 24 µs (mem. compartida)
◮ Distintos procesos, mismo sistema: 60 µs (TCP)
◮ Distintos procesos, diferente sistema: 220 µs (TCP+Ethernet)
◮ 1000 invocaciones: 220.000 µs
◮ 250 llamadas con todos los parámetros: 460 µs (x478!!)

Diego Sevilla Ruiz DITEC Facultad de Informática


Sistemas Distribuidos
Diseño de IDL eficiente

◮ Se puede convertir:
interface SensorAire {
struct DatosSensor {
float temperatura;
float presión;
float humedad;
float velocidad_viento;
};

DatosSensor getDatos();
};

Diego Sevilla Ruiz DITEC Facultad de Informática


Sistemas Distribuidos
Diseño de IDL eficiente

interface SensorAire {
typedef sequence<float> FloatSeq;
struct DatosSensor {
FloatSeq temperatura;
FloatSeq presión;
FloatSeq humedad;
FloatSeq velocidad_viento;
};

DatosSensor getDatos();
};
◮ Arrays vs. secuencias
◮ Las secuencias son de tamaño variable
◮ Sólo se envı́an los elementos que hay
Diego Sevilla Ruiz DITEC Facultad de Informática
Sistemas Distribuidos
Diseño de IDL eficiente

◮ Los sistemas de mensajerı́a ponen la lógica en los datos


◮ Se utilizan órdenes case para identificar los distintos mensajes
◮ Difı́cil corrección:
◮ Pueden no existir casos para los mensajes nuevos
◮ Un mensaje mal decodificado no produce un error de
compilación (puede permanecer oculto mucho tiempo)

Diego Sevilla Ruiz DITEC Facultad de Informática


Sistemas Distribuidos
Diseño de IDL eficiente

◮ Hay que evitar esto en IDL:


interface MessagePort
{
void send(in any message);
void recv(in any message);
}
◮ Falta de tipado estricto
◮ Eficiencia: conversión del tipo any

Diego Sevilla Ruiz DITEC Facultad de Informática


Sistemas Distribuidos
Diseño de IDL eficiente

◮ Se convierte cada mensaje en una operación IDL


◮ El nombre de la operación es el tipo de mensaje
◮ Los parámetros son los datos del mensaje
◮ Ventajas en espacio y tiempo
◮ El compilador y el linkador puede eliminar los mensajes sin usar
◮ Optimizaciones en tiempo de compilación
◮ Código para nuevos mensajes o con tipos no adecuados
◮ Encontrado en tiempo de compilación
◮ No descubierto en tiempo de ejecución
◮ La herencia se puede usar para agrupar operaciones
relacionadas (mixins)

Diego Sevilla Ruiz DITEC Facultad de Informática


Sistemas Distribuidos
Diseño de IDL eficiente – Excepciones

◮ Se deben de usar sólo en circunstancias excepcionales


◮ Utilización de la capacidad de incluir datos para establecer el
contexto de la excepción
◮ Sin embargo, no es bueno tener un único tipo de excepción y
diferenciar por los datos miembro
◮ Se evita lógica innecesaria para evitar las excepciones no
deseadas
◮ Es importante pensar sobre cómo las aplicaciones responden a
la excepción
◮ Los casos de uso guı́an los patrones de uso
◮ ¿El nombre de la excepción y los datos miembros tienen
sentido en el cliente?

Diego Sevilla Ruiz DITEC Facultad de Informática


Sistemas Distribuidos
Patrones de IDL – Factorı́as

◮ Encapsulan la inicialización de un sistema


◮ Alternativas
◮ Servicio de nombres
◮ Sistemas propietarios de enlazado (bind)
◮ Mejores para referencias iniciales
◮ Se deben usar para ensamblar el sistema (dónde y cómo crear
los objetos)

Diego Sevilla Ruiz DITEC Facultad de Informática


Sistemas Distribuidos
Patrones de IDL – Factorı́as

◮ Una factorı́a de factorı́as también es interesante para


encapsular la construcción del sistema:
interface WeatherStation
{
AirSensorFactory air_sensors();
WaterSensorFactory water_sensors();
};

Diego Sevilla Ruiz DITEC Facultad de Informática


Sistemas Distribuidos
Patrones de IDL – Callbacks
◮ Caso de uso:
◮ Notificación ası́ncrona de un incidente crı́tico
◮ Invocaciones petición/respuesta vs. peticiones one way
◮ Funcionan igual
◮ Depende del modelo de bloqueo deseado
◮ Problema: Ambos cliente y servidor tienen que ser servidores
◮ Problema en dispositivos pequeños sólo con interfaz de cliente
CORBA
interface Sensor; struct ValoresSensor {...};
interface SensorListener
{
oneway void nueva_lectura(in ValoresSensor v);
};

interface Sensor
{
void addListener(in SensorListener listener);
void removeListener(in SensorListener listener);
};

Diego Sevilla Ruiz DITEC Facultad de Informática


Sistemas Distribuidos
Patrones de IDL – Callbacks

◮ El sistema deja de ser cliente/servidor puro para pasar a ser


peer-to-peer
◮ Problemas:
◮ Escalabilidad: ¿Cómo enviar los eventos a miles de listeners?
◮ Seguridad: ¿cómo aseguramos que el que elimina un listener es
la entidad que debe hacerlo?
◮ Identificación: ¿Cómo saber si dos referencias se refieren al
mismo objeto CORBA?

Diego Sevilla Ruiz DITEC Facultad de Informática


Sistemas Distribuidos
Callbacks (Escalabilidad)

◮ ¿Cómo permitir notificar a miles de listeners?


◮ Incluso con funciones oneway, el tiempo de invocación puede
ser prohibitivo
◮ El proceso, o bien lanza un thread para enviar las peticiones, o
bien se bloquea hasta que notifica a todos
◮ Lo ideal: delegar la invocación a una entidad externa
◮ Una única invocación
◮ Separación de roles
◮ Por ejemplo: Servicio de Eventos (y de Notificaciones) de
CORBA:
◮ El canal es la entidad encargada de depositar los mensajes a
los destinatarios
◮ Implementada con cualquier optimización (multicast, etc.)

Diego Sevilla Ruiz DITEC Facultad de Informática


Sistemas Distribuidos
Callbacks (Seguridad)

◮ ¿Cómo saber que la entidad que elimina un listener es


realmente la adecuada?
◮ Varias soluciones:
◮ Mantener siempre privada la referencia al listener
◮ Utilizar el Servicio de Seguridad de CORBA
◮ Que el sensor devuelva un ListenerTerminator, único para
cada listener

Diego Sevilla Ruiz DITEC Facultad de Informática


Sistemas Distribuidos
Callbacks (Identificación)

◮ ¿Cómo saber qué listener eliminar?


◮ Se envı́a la referencia del listener, pero...
◮ en CORBA no hay manera de asegurar que dos referencias
apuntan al mismo objeto
◮ Object::is equivalent: true–ambos objetos son el mismo;
false–No se puede asegurar nada
◮ Razones: eficiencia, sólo se compara el IOR, campos
propietarios, etc.
◮ Solución: Añadir la identificación como una clase mixin

Diego Sevilla Ruiz DITEC Facultad de Informática


Sistemas Distribuidos
Callbacks (Identificación)

interface Identifiable
{
readonly attribute string id;
};

interface SensorListener: Identifiable


{
// ...
};
◮ Problema: La identificación es una operación remota
◮ Depende de la implementación, por lo que no se puede
reutilizar (o bien se implementa directamente en el servant o
bien heredan del servant que implementa identificable)
Diego Sevilla Ruiz DITEC Facultad de Informática
Sistemas Distribuidos
Escalabilidad, eficiencia y mantenimiento

◮ Patrón wrapper ó layers


◮ Gestión de múltiples clientes
◮ Gestión de múltiples threads

Diego Sevilla Ruiz DITEC Facultad de Informática


Sistemas Distribuidos
Layers

◮ Capa de traducción y delegación


◮ Muy pequeña con respecto al resto de la aplicación
◮ Patrón Adapter (Wrapper Facade, POSA2, p. 47)

Diego Sevilla Ruiz DITEC Facultad de Informática


Sistemas Distribuidos
Layers – ventajas

◮ Menos código dependiente de CORBA


◮ Menos errores en mappings complejos (C++)
◮ Sólo un grupo de programadores tiene que conocer CORBA
◮ La aplicación se puede probar de forma independiente
◮ Aisla al programa de la tecnologı́a utilizada

Diego Sevilla Ruiz DITEC Facultad de Informática


Sistemas Distribuidos
Layers – inconvenientes

◮ Añade más sobrecarga (otro nivel más)


◮ Necesidad de hacer conversión de tipos
◮ Requiere más código
◮ Necesidad de generar nuevos tipos y APIs equivalentes a los
que aparecen en IDL

Diego Sevilla Ruiz DITEC Facultad de Informática


Sistemas Distribuidos
Escalabilidad en el número de objetos y clientes

◮ Default Servant
◮ Patrón Evitor

Diego Sevilla Ruiz DITEC Facultad de Informática


Sistemas Distribuidos
Patrón Evictor

◮ Permite tener en memoria un pool de servants listos para


ejecutar métodos, hasta un tope fijo
◮ Balance entre un DefaultServant y un esquema de un
servant por objeto CORBA
◮ Ventajas
◮ Velocidad de servicio elevada (los sirvientes están ya creados)
◮ Poco uso de memoria
◮ Flexibilidad en la elección del método de descarte de sirvientes
(p. ej. LRU)
◮ Inconvenientes
◮ Manejo de sirvientes programado por el usuario
◮ Mayor complejidad
◮ Henning & Vinoski, 12.3
Diego Sevilla Ruiz DITEC Facultad de Informática
Sistemas Distribuidos
Patrón Evictor

◮ Polı́ticas del POA:


◮ RequestProcessingPolicy
◮ USE SERVANT MANAGER
◮ ServantRetentionPolicy
◮ NON RETAIN (ServantLocator)
◮ El POA llama al locator para cada llamada a un objeto

Diego Sevilla Ruiz DITEC Facultad de Informática


Sistemas Distribuidos
Patrón Evictor

◮ Con ServantLocators:
◮ Ineficiente: Creación de sirvientes en cada petición,
fragmentación del heap
◮ Evictor:
◮ En memoria los sirvientes más usados (LRU)
◮ Aprovecha la localidad temporal
◮ Necesidades:
◮ Creación de referencias
◮ Creación del ServantLocator (Objeto CORBA local)
◮ Obtención del Object ID (Interfaz Current, POACurrent)
◮ El ServantLocator debe reconocer la operación destroy del
objeto CORBA (interesante diseñar interfaces que la
contengan para limpiar la memoria del servidor lo máximo
posible)

Diego Sevilla Ruiz DITEC Facultad de Informática


Sistemas Distribuidos
Patrón Evictor

1
Cliente POA

Sirvientes
2
5 4 3 2 1
3

Servant Locator 4
5 4 3 2 1
Cola Cabeza
Cola del Evictor

Diego Sevilla Ruiz DITEC Facultad de Informática


Sistemas Distribuidos
Manejo de threads de ejecución

◮ Introducción
◮ Modelos de un único thread
◮ Patrón reactor/proactor
◮ Modelos de threads:
◮ Thread per request
◮ Thread per client (per connection)
◮ Thread pool
◮ Configuración del ORB

Diego Sevilla Ruiz DITEC Facultad de Informática


Sistemas Distribuidos
Manejo de threads de ejecución

◮ Cada POA puede especificar la polı́tica de threads


◮ SINGLE THREAD
◮ ORB CTRL MODEL – el ORB decide
◮ Un ORB con n POAs SINGLE THREAD puede tener n threads
de ejecución, pero cada POA recibirá las peticiones serializadas
◮ CORBA no estandariza los modelos de concurrencia
◮ Normalmente como extensiones propietarias
◮ Estandarizado en RT-CORBA, pero no trasladado a CORBA
(?)

Diego Sevilla Ruiz DITEC Facultad de Informática


Sistemas Distribuidos
Manejo de threads – Único thread

Diego Sevilla Ruiz DITEC Facultad de Informática


Sistemas Distribuidos
Único thread – Patrón Reactor

Diego Sevilla Ruiz DITEC Facultad de Informática


Sistemas Distribuidos
Único thread – Patrón Reactor
◮ El Dispatcher usa el demultiplexor sı́ncrono
◮ El Dispatcher implementa la función handle event para
notificar a cada handler
◮ También posee operaciones para añadir y eliminar handlers
◮ La clase Event Handler es genérica, los distintos handlers
heredan de ella
◮ Caso genérico: handlers de ficheros y llamada select()
◮ También incluye un timeout que hace que el bucle pueda
integrar a otros bucles de eventos (GUI, X11, Qt, etc.)
◮ Los ORBs de un único thread utilizan este patrón para sus
conexiones
◮ Ver también: Patrón Proactor, Acceptor/Connector,
Asynchronous Completion Token, etc. (POSA1/2)
Diego Sevilla Ruiz DITEC Facultad de Informática
Sistemas Distribuidos
Manejo de threads – Thread per request

Diego Sevilla Ruiz DITEC Facultad de Informática


Sistemas Distribuidos
Manejo de threads – Thread per request

◮ El código de cada thread debe ser thread-safe


◮ Se crea un thread para cada petición
◮ No es muy escalable, y
◮ Funciona bien con pocas peticiones que se pueden ejecutar en
paralelo
◮ El tiempo de respuesta es largo
◮ Puede dejar exhaustos los recursos del servidor (no de threads,
por ejemplo)
◮ Memoria, manejo de threads, cambios de contexto, creación y
destrucción de threads, etc.

Diego Sevilla Ruiz DITEC Facultad de Informática


Sistemas Distribuidos
Manejo de threads – Thread per Client

◮ Bueno para muchas peticiones y pocos clientes (orientado a


sesión)
◮ Reusa conexiones entre ordenadores

Diego Sevilla Ruiz DITEC Facultad de Informática


Sistemas Distribuidos
Manejo de threads – Thread pool

Diego Sevilla Ruiz DITEC Facultad de Informática


Sistemas Distribuidos
Manejo de threads – Thread pool

Diego Sevilla Ruiz DITEC Facultad de Informática


Sistemas Distribuidos
Manejo de threads – Thread pool

◮ Al principio se crean un conjunto de threads


◮ Se elige un thread de los del pool (o cada thread coge una
petición cuando no tiene nada que hacer)
◮ Permite tener acotados los recursos
◮ Número de threads fijo o acotado
◮ No incurre en creación de nuevos threads

Diego Sevilla Ruiz DITEC Facultad de Informática


Sistemas Distribuidos
Thread-Specific Storage

◮ El manejo de memoria compartida entre threads a veces causa


muchos retrasos:
◮ candados
◮ métodos sincronizados para el acceso a estructuras de datos
◮ Abstracción: Objeto especı́fico para un thread
◮ Disponibles en las librerı́as de Threads (pthreads, JTC...)
◮ En JTC, es la clase JTCTSS.
◮ El almacenamiento se realiza por thread.
◮ Ideal para almacenar sesiones.

Diego Sevilla Ruiz DITEC Facultad de Informática


Sistemas Distribuidos