Comunicación de procesos en sistemas distribuidos

Anuncio
Objetivo del tema
Comunicación de procesos en sistemas
distribuidos
• Presentar los diferentes esquemas para comunicar procesos en
sistemas distribuidos:
– Servicios básicos de comunicación (colas de mensajes
POSIX, mailslots de Win32, sockets)
– Llamadas a procedimientos remotos
– Entornos orientados a objetos (CORBA, DCOM, RMI).
• Presentar el concepto de cliente-servidor
• Comunicación de grupos.
• Comunicación de procesos en aplicaciones paralelas (MPI)
Sistemas Distribuidos
Contenido
•
•
•
•
•
•
•
2
Félix García Carballeira (1999)
Comunicación en sistemas distribuidos
• La comunicación de procesos es fundamental en cualquier
sistema distribuido
• Existen diferentes posibilidades todas ellas basadas en el paso de
mensajes
– Mecanismos de bajo nivel, el programador debe preocuparse
de establecer los protocolos de comunicación, representación
de datos, etc.
• Colas de mensajes
• Sockets
– Mecanismo de alto nivel, ofrecen abstracciones donde el
programador no debe preocuparse de establecer protocolos
• Llamadas a procedimientos remotos
• Invocación de métodos remotos (entornos orientados a objetos)
Sistemas Distribuidos
4
Félix García Carballeira (1999)
Mecanismos de comunicación entre procesos
Mecanismos básicos de comunicación entre procesos
Modelo cliente/servidor y comunicación en grupos
Colas de mensajes POSIX y Mailslots de Win32
Sockets en Unix y Java
Llamadas a procedimientos remotos (RPC)
Entornos orientados a objetos. CORBA, RMI
Comunicación en aplicaciones paralelas. MPI
Sistemas Distribuidos
1
Félix García Carballeira (1999)
• Ficheros
• Tuberías
– Sin nombre: pipes
– Con nombre: FIFOs
• Memoria Compartida
– Espacio del sistema operativo
– Espacio compartido entre los procesos (threads)
• Paso de mensajes
Sistemas Distribuidos
3
Félix García Carballeira (1999)
Paso de mensajes: conceptos básicos
• Primitivas básicas
– send(destino, mensaje)
– receive(origen, mensaje)
• Tamaño del mensaje
– Longitud fija o variable
• Flujo de datos
– Bidireccional, unidireccional
• Nombrado
– Comunicación directa
• send(P, m): envía un mensaje m al proceso P
• receive(Q, m): recibe un mensaje del proceso Q
• receive (ANY, m): recibe un mensaje de cualquiera
Sistemas Distribuidos
5
Félix García Carballeira (1999)
Conceptos básicos
Patrones típicos de comunicación
• Nombrado
– Comunicación indirecta: los datos se envían a estructuras
intermedias
• Puertos: se asocian a un proceso (un único receptor)
– Ejemplo: sockets
• Comunicación cliente-servidor
– Transmisión de datos y código
• Comunicación de grupos
– Útil en servicios replicados
• Colas de mensajes: múltiples emisores y receptores
– Ejemplo: Colas de mensajes POSIX
• Tipos de comunicación
– Síncrona o asíncrona
• Capacidad de almacenamiento (buffering)
• Fiabilidad
– Fiables o no fiables
• Representación de datos, aplanamiento
Sistemas Distribuidos
6
Félix García Carballeira (1999)
Sistemas Distribuidos
Comunicación cliente-sevidor
petcición
Máquina B
cliente
NÚCLEO
servidor
respuesta
Félix García Carballeira (1999)
Comunicación de grupos
• Muy utilizada en entornos distribuidos (más del 90% de los
sistemas distribuidos utilizan la arquitectura cliente-servidor)
Máquina A
7
NÚCLEO
• Utiliza mensajes multicast
• Útil para:
– Ofrecer tolerancia a fallos basado en servicios replicados
– Localizar objetos en sistemas distribuidos
– Mejor rendimiento mediante datos replicados
– Actualizaciones múltiples
– Operaciones colectivas en cálculo paralelo
RED
• Protocolo típico: petición-respuesta
Sistemas Distribuidos
8
Félix García Carballeira (1999)
Sistemas Distribuidos
Tuberías en POSIX (pipes, FIFOS)
Tuberías en POSIX
• Si p ≥ n ⇒ devuelve n
• Si p < n ⇒ devuelve p
• int pipe(int fildes[2]);
– Creación de FIFOS
• int mkfifo(char *name, mode_t mode);
• int open(char *name, int flag);
– Lectura de una tubería
• read(int fd, char *buf, int size);
– Escritura de una tubería
• write(int fd, char *buf, int size);
10
Félix García Carballeira (1999)
• Semántica de las lecturas (read(fd[0], buf, n))
– Si la tubería está vacía ⇒ se bloquea al lector
– Si la tubería tiene p bytes:
• Mecanismo de comunicación y sincronización
• Servicios POSIX
– Creación de pipes
Sistemas Distribuidos
9
Félix García Carballeira (1999)
– Si la tubería está vacía y no hay escritores devuelve 0
• Semántica de las escrituras (write(fd[1], buf, n))
– Si la tubería está llena ⇒ se bloquea el escritor
– Si no hay lectores se recibe la señal SIGPIPE
• Lecturas y escrituras son atómicas (cuidado con tamaños
grandes)
Sistemas Distribuidos
11
Félix García Carballeira (1999)
Colas de mensajes POSIX
• Mecanismo de comunicación y sincronización
• Nombrado indirecto
• Asignan a las colas nombres de ficheros
– Sólo pueden utilizar colas de mensajes procesos que
comparten un mismo sistema de ficheros
• Tamaño del mensaje variable
• Flujo de datos: bidireccional
• Sincronización:
– Envío asíncrono
– Recepción síncrona o asíncrona
• Los mensajes se pueden etiquetar con prioridades
Sistemas Distribuidos
12
Félix García Carballeira (1999)
Colas de mensajes POSIX: servicios
• mqd_t mq_open(char *name, int flag, mode_t mode,
struct mq_attr *attr)
– Crea una cola de mensajes con nombre y atributos
• Número máximo de mensajes
• Tamaño del mensaje
• Recepción bloqueante o no bloqueante
• int mq_close(mqd_t mqdes)
– Cierra una cola
• int mq_unlink(char *name)
– Borra una cola de mensajes
Sistemas Distribuidos
Colas de mensajes POSIX: servicios
• int mq_send(mqd_t mqdes, char *msg, size_t len, int prio)
– Envía un mensaje a una cola con prioridad prio
– Si la cola está llena el servicio bloquea al proceso
• int mq_receive(mqd_t mqdes, char *msg, size_t len, int
prio)
– Recibe un mensaje de una cola
– La recepción puede ser bloqueante o no dependiendo de
los atributos asociados a las colas.
Sistemas Distribuidos
14
Félix García Carballeira (1999)
M áquina A
cliente
M áquina B
sum ar(5,2)
servidor
5+2
N Ú CLE O
R estulado = 7
N Ú CLE O
R ED
Sistemas Distribuidos
15
Félix García Carballeira (1999)
Proceso servidor
256
struct peticion {
int a;
int b;
char q_name[MAXSIZE];
Félix García Carballeira (1999)
Ejemplo
Definición de tipos
#define MAXSIZE
13
/* operando 1 */
/* operando 2 */
/* nombre de la cola cliente
donde debe enviar la respuesta
el servidor */
#include <mqueue.h>
void main(void)
{
mqd_t q_servidor;
mqd_t q_cliente;
struct peticion pet;
int res;
struct mq_attr attr;
/* cola de mensajes del servidor */
/* cola de mensajes del cliente */
attr.mq_maxmsg = 20;
attr.mq_msgsize = sizeof(struct peticion);
q_servidor = mq_open(“SERVIDOR_SUMA”, O_CREAT|O_READ, 0700, &attr);
while(1) {
mq_receive(q_servidor, &pet, sizeof(pet), 0);
res = pet.a + pet.b;
};
/* se responde al cliente abriendo previamente su cola */
q_cliente = mq_open(pet.q_name, O_WRONLY);
mq_send(q_cliente, &res, sizeof(int), 0);
mq_close(q_cliente);
Sistemas Distribuidos
16
Félix García Carballeira (1999)
}
}
Sistemas Distribuidos
17
Félix García Carballeira (1999)
Proceso cliente
#include <mqueue.h>
void main(void) {
mqd_t q_servidor;
mqd_t q_cliente;
struct peticion pet;
int res;
struct mq_attr attr;
Mailslots de Win32
• Similares a las colas de mensajes de POSIX
• Tamaño máximo de los mensajes es de 64 KB
• Pueden utilizarse entre procesos que ejecuten en máquinas
de un mismo dominio.
• El nombre de un mailslots sigue el formato:
\\.\mailslot\nombre
• Para abrir un mailslot debe utilizarse:
– \\.\mailslot\nombre para un mailslot local
– \\.\maquina\mailslot\nombre para una
máquina remota
– \\.\dominio\mailslot\nombre para un
mailslot creado en un dominio
/* cola de mensajes del proceso servidor */
/* cola de mensajes para el proceso cliente */
attr.mq_maxmsg = 1;
attr.mq_msgsize = sizeof(int);
q_cliente = mq_open(“CLIENTE_UNO”, O_CREAT|O_RDONLY, 0700, &attr);
q_servidor = mq_open(“SERVIDOR_SUMA”, O_WRONLY);
/* se rellena la petición */
pet.a = 5;
pet.b = 2;
strcpy(pet.q_name, “CLIENTE_UNO”);
mq_send(q_servidor, &pet, sizeof(struct petiticion), 0);
mq_receive(q_cliente, &res, sizeof(int), 0);
mq_close(q_servidor); mq_close(q_cliente);
mq_unlink(“CLIENTE_UNO”);
}
Sistemas Distribuidos
18
Félix García Carballeira (1999)
Sistemas Distribuidos
Mailslots: servicios
• HANDLE CreateFile(LPCSTR name, DWORD Access,
DWORD ShareMode, LPVOID lpSecurityAttributes,
DWORD CreationDisposition,
DWORD FlagsAndAttributes, Handle TemplateFile);
– Abre un mailslot existente.
20
Félix García Carballeira (1999)
Mailslots: servicios
• HANDLE CreateMailslot(LPCTSTR name,
DWORD MaxMessSize, DWORD lReadTimeout,
LPSECURITY_ATTRIBUTES lpsa):
– Tamaño máximo del mensaje de mensajes
– Tiempo de bloqueo de una operación de lectura (INFINITE)
– Atributos de seguridad
Sistemas Distribuidos
19
Félix García Carballeira (1999)
• BOOL ReadFile(HANDLE hm, LPVOID lpBuffer
DWORD nBytes, LPDWORD lpnBytes,
LPOVERLAPPED lpOverlapped);
– Lee datos de un mailslot
• BOOL WriteFile(HANDLE hm, LPVOID lpBuffer
DWORD nBytes, LPDWORD lpnBytes,
LPOVERLAPPED lpOverlapped);
– Escribe datos a un mailslot
• BOOL CloseHandle(HANDLE hm);
– Cierra un mailslot
Sistemas Distribuidos
Proceso servidor
21
Félix García Carballeira (1999)
Proceso cliente
#include <windows.h>
void main(void)
{
HANDLE mhs, mhc;
struct peticion pet;
int res, nrw;
#include <windows.h>
void main(void) {
HANDLE mhs;
HANDLE mhc;
struct peticion pet;
int res, nrw;
mhs = CreateMailslot(“\\.\mailslot\SERVIDOR_SUMA”,
sizeof(struct peticion), INFINITE, NULL);
while(1) {
ReadFile(mhs, (char *)&pet, sizeof(struct peticion),
&nrw, NULL);
res = pet.a + pet.b;
/* mailslot del proceso servidor */
/* mailslot para el proceso cliente */
mhc = CreateMailslot(“\\.\mailslot\CLIENTE_UNO”,
sizeof(struct peticion), INFINITE, NULL);
mhs = CreateFile (“\\.\mailslot\SERVIDOR_SUMA”,
GENERIC_WRITE, 0, NULL, OPEN_EXISTING, NULL);
/* se rellena la petición */
pet.a = 5;
pet.b = 2;
strcpy(pet.q_name, “\\.\mailslot\CLIENTE_UNO”);
/* se responde al cliente abriendo previamente su mailslot */
mhc = CreateFile(pet.q_name, GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
NULL);
WriteFile(mhc, &res, sizeof(int), &nrw, NULL);
CloseHandle(mhc);
WriteFile(mhs, (char *)&pet, sizeof(struct peticion),&nrw, NULL);
ReadFile(mhc, &res, sizeof(int),&nrw, NULL);
}
CloseHandle(mhc);
CloseHandle(mhs);
}
}
Sistemas Distribuidos
22
Félix García Carballeira (1999)
Sistemas Distribuidos
23
Félix García Carballeira (1999)
Sockets: introducción
Sockets: introducción
• Aparecieron en 1981 en UNIX BSD 4.2
– Intento de incluir TCP/IP en UNIX
– Diseño independiente del protocolo de comunicación
• Un socket es punto final de comunicación (dirección IP y
puerto)
• Abstracción que:
– Ofrece interfaz de acceso a los servicios de red en el nivel de
transporte
• Sujetos a proceso de estandarización dentro de POSIX (POSIX
1003.1g)
• Actualmente
– Disponibles en casi todos los sistemas UNIX
– En prácticamente todos los sistemas operativos
• WinSock: API de sockets de Windows
– En Java como clase nativa
• Protocolo TCP
• Protocolo UDP
– Representa un extremo de una comunicación bidireccional
con una dirección asociada
Sistemas Distribuidos
24
Félix García Carballeira (1999)
Sistemas Distribuidos
Sockets UNIX
•
•
•
•
•
•
•
•
•
26
•
•
•
•
Un dominio representa una familia de protocolos
Un socket está asociado a un dominio desde su creación
Sólo se pueden comunicar sockets del mismo dominio
Algunos ejemplos:
– PF_UNIX (o PF_LOCAL): comunicación dentro de una
máquina
– PF_INET: comunicación usando protocolos TCP/IP
• Los servicios de sockets son independientes del dominio
Félix García Carballeira (1999)
Sistemas Distribuidos
Tipos de sockets
28
27
Félix García Carballeira (1999)
Direcciones de sockets
• Stream (SOCK_STREAM)
– Orientado a conexión
– Fiable, se asegura el orden de entrega de mensajes
– No mantiene separación entre mensajes
– Si PF_INET se corresponde con el protocolo TCP
• Datagrama (SOCK_DGRAM)
– Sin conexión
– No fiable, no se asegura el orden en la entrega
– Mantiene la separación entre mensajes
– Si PF_INET se corresponde con el protocolo UDP
• Raw (SOCK_RAW)
– Permite el acceso a los protocolos internos como IP
Sistemas Distribuidos
Félix García Carballeira (1999)
Dominios de comunicación
Dominios de comunicación
Tipos de sockets
Direcciones de sockets
Creación de un socket
Asignación de direcciones
Solicitud de conexión
Preparar para aceptar conexiones
Aceptar una conexión
Transferencia de datos
Sistemas Distribuidos
25
Félix García Carballeira (1999)
• Cada socket debe tener asignada una dirección única
• Las direcciones se usan para:
– Asignar una dirección local a un socket (bind)
– Especificar una dirección remota (connect o sendto)
• Dependientes del dominio
• Se utiliza la estructura struct sockaddr
• Cada dominio usa una estructura específica
– Uso de cast en las llamadas
• Direcciones en PF_UNIX (struct sockaddr_un)
– Nombre de fichero
Sistemas Distribuidos
29
Félix García Carballeira (1999)
Direcciones de sockets en PF_INET
• Usuarios manejan direcciones en forma de texto:
– decimal-punto: 138.100.8.100
– dominio-punto: laurel.datsi.fi.upm.es
• Conversión a binario desde decimal-punto:
– int inet_aton(char *str, struct in_addr *dir)
• Host (32 bits) + puerto (16 bits)
• Estructura struct sockaddr_in
– Debe iniciarse a 0
– sin_family: dominio (AF_INET)
– sin_port: puerto
– sin_addr: dirección del host
• Funciones para transformar formato:
– htonl: de host a red
– ntohl: de red a host
Sistemas Distribuidos
30
Obtención de la dirección de host
• str: contiene la cadena a convertir
• dir: resultado de la conversión en formato de red
• Conversión a binario desde dominio-punto:
– struct hostent *gethostbyname(char *str)
• str: cadena a convertir
• Devuelve la estructura que describe el host
Félix García Carballeira (1999)
Sistemas Distribuidos
Creación de un socket
31
Félix García Carballeira (1999)
Asignación de direcciones
• int socket(int dominio, int tipo, int protocolo)
– Crea un socket devolviendo un descriptor de fichero
– dominio: PF_XXX
– tipo: SOCK_XXX
– protocolo: dependiente del dominio y tipo
• 0 elige el más adeucado
• Especificados en /etc/protocols
• El socket creado no tiene dirección asignada
• int bind(int sd, struct sockaddr *dir, int long)
– sd: descriptor devuelto por socket
– dir: dirección a asignar
– long: longitud de la dirección
• Si no se asigna dirección (típico en clientes)
– Se le asigna automáticamente (puerto efímero) en la su
primera utilización (connect o sendto)
• Direcciones en dominio PF_INET
– Puertos en rango 0..65535. Reservados: 0..1023. Si 0, el
sistema elige uno
– Host: una dirección local IP
• INNADDR_ANY: elige cualquiera de la máquina
• El espacio de puertos para streams y datagramas es indendiente
Sistemas Distribuidos
32
Félix García Carballeira (1999)
Solicitud de conexión
Sistemas Distribuidos
33
Félix García Carballeira (1999)
Preparar para aceptar conexiones
• Realizada en el cliente
• int connect(int sd, struct sockaddr *dir, int long)
– sd: descriptor devuelto por socket
– dir: dirección del socket remoto
– long: longitud de la dirección
• Si el socket no tiene dirección asignada, se le asigna una
automáticamente
• Normalmente se usa con streams
• Realizada en el servidor stream después de socket y bind
• int listen(int sd, int baklog)
– sd: descriptor devuelto por socket
– backlog:
Sistemas Distribuidos
Sistemas Distribuidos
34
Félix García Carballeira (1999)
• Número máximo de peticiones pendientes de aceptar que se
encolarán (algunos manuales recomiendan 5)
• Hace que el socket quede preparado para aceptar conexiones.
35
Félix García Carballeira (1999)
Aceptar una conexión
Aceptar una conexión
• Realizada en el servidor stream después de socket, bind y listen
• Cuando se produce la conexión, el servidor obtiene:
– La dirección del socket del cliente
– Un nuevo descriptor que queda conectado al socket del
cliente
• Después de la conexión quedan activos dos sockets en el
servidor:
– El original para aceptar nuevas conexiones
– El nuevo para enviar/recibir datos por la conexión
• int accept(int sd, struct sockaddr *dir, int *long)
– sd: descriptor devuelto por socket
– dir: dirección del socket del cliente devuelta
– long: parámetor valor-resultado
Sistemas Distribuidos
Sistemas Distribuidos
36
Félix García Carballeira (1999)
Obtener la dirección de un socket
• Obtener la dirección a partir del descriptor
– int getsockname(int sd, struct sockaddr *dir, int *long)
• sd: descriptor devuelto por socket
• dir: dirección del socket devuelta
• long: parámetro valor-resultado (igual que en accept)
• Obtener la dirección del socket en el toro extremo de la
conexión:
– int gerpeername(int sd, struct sockaddr *dir, int *long)
• sd: descriptor devuelto por socket
• dir: dirección del socket remoto
• long: parámetro valor-resultado
Sistemas Distribuidos
38
• Antes de la llamada: tamaño de dir
• Después de la llamada: tamaño de la dirección del cliente que
se devuelve.
37
Félix García Carballeira (1999)
Transferencia de datos con streams
• Una vez realizada la conexión, ambos extremos puede
transferir datos.
• Envío:
– Puede usarse el servicio write sobre el descriptor de socket
– int send(int sd, char *mem, int long, int flags)
• Devuelve el nº de bytes enviados
• Recepción:
– Puede usarse el servicio read sobre el descriptor de socket
– int recv(int sd, char *mem, int long, int flags)
• Devuelve el nº de bytes recibidos
• Los flags implican aspectos avanzado como enviar o recibir
datos urgentes (out-of-band)
Félix García Carballeira (1999)
Sistemas Distribuidos
39
Félix García Carballeira (1999)
Transferencia de datos con datagramas
Cerrar un socket
• No hay conexión real
• Para usar un socket para transferir basta con:
– Crearlo: socket
– Asignarle una dirección: bind (si no, lo hará el sistema)
• Envío:
– int sendto(int sd, char *men, int long, int flags,
struct sockaddr *dir, int long)
• Se usa close para cerrar ambos tipos de sockets
• Si el socket es de tipo stream, close cierra la conexión en ambos
sentidos
• Se puede cerrar un único extremo:
– int shutdown(int st, int modo)
• Devuelve el nº de bytes enviados
• dir: dirección del socket remoto y long la longitud
• sd: descriptor devuelto por socket
• modo: SHUT_RD, SHUT_RW o SHUT_RDWR
• Rccepción:
– int recvfrom(int sd, char *men, int long, int flags,
struct sockaddr *dir, int long)
• Devuelve el nº de bytes enviados
• dir: dirección del socket remoto y long la longitud
Sistemas Distribuidos
40
Félix García Carballeira (1999)
Sistemas Distribuidos
41
Félix García Carballeira (1999)
Escenario típico con sockets streams
Configuración de opciones
Proceso servidor
• Existen varios niveles dependiendo del protocolo afectado como
parámetro
– SOL_SOCKET: opciones independientes del protocolo
– IPPROTO_TCP: nivel de protocolo TCP
– IPPTOTO_IP: nivel de protocolo IP
• Consultar opciones asociadas a un socket
socket()
Proceso cliente
bind()
listen()
socket()
Abrir conexión
accept()
connect()
– int getsockopt(int sd, int nivel, int opc, char *val, int *long)
• Modificar las opciones asociadas a un socket
Petición
write()
– int setsockopt(int sd, int nivel, int opc, char *val, int long)
• Ejemplos (nivel SOL_SOCKET):
– SO_REUSEADDR: permite reutilizar direcciones
Sistemas Distribuidos
42
read()
cliente
M áquina B
servidor
Restulado = 7
close()
43
Félix García Carballeira (1999)
Servidor (TCP)
5+2
NÚCLEO
write()
Sistemas Distribuidos
Ejemplo (TCP)
sumar(5,2)
read()
Respuesta
close()
Félix García Carballeira (1999)
M áquina A
Crear
thread
accept()
void main(int argc, char *argv[])
{
struct sockaddr_in server_addr,
int sd, sc;
int size, val;
int size;
int num[2], res;
client_addr;
sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
val = 1;
setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (char *) &val, sizeof(int));
NÚCLEO
RED
bzero((char *)&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = 4200;
bind(sd, &server_addr, sizeof(server_addr));
Sistemas Distribuidos
44
Félix García Carballeira (1999)
Sistemas Distribuidos
Servidor (TCP)
Félix García Carballeira (1999)
Cliente (TCP)
listen(sd, 5);
size = sizeof(client_addr);
while (1)
{
printf("esperando conexion\n");
sc = accept(sd, (struct sockaddr *)&client_addr,&size);
read(sc, (char *) num, 2 *sizeof(int));
45
// recibe la petición
res = num[0] + num[1];
void main(void)
{
int sd;
struct sockaddr_in server_addr;
struct hostent *hp;
int num[2], res;
sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
bzero((char *)&server_addr, sizeof(server_addr));
hp = gethostbyname ("arlo.datsi.fi.upm.es");
write(sc, &res, sizeof(int));
// se envía el resultado
memcpy (&(server_addr.sin_addr), hp->h_addr, hp->h_length);
server_addr.sin_family = AF_INET;
server_addr.sin_port = 4200;
close(sc);
}
close (sd);
exit(0);
}
Sistemas Distribuidos
46
Félix García Carballeira (1999)
Sistemas Distribuidos
47
Félix García Carballeira (1999)
Cliente (TCP)
Servidor (datagramas)
// se establece la conexión
connect(sd, (struct sockaddr *) &server_addr,
sizeof(server_addr));
num[0]=5;
num[1]=2;
void main(void)
{
int num[2];
int s, res, clilen;
struct sockaddr_in server_addr, client_addr;
s =
write(sd, (char *) num, 2 *sizeof(int));
read(sd, &res, sizeof(int));
// envía la petición
// recibe la respuesta
printf("Resultado es %d \n", res);
close (sd);
exit(0);
socket(AF_INET, SOCK_DGRAM, 0);
bzero((char *)&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = 7200;
bind(s, (struct sockaddr *)&server_addr, sizeof(server_addr));
}
Sistemas Distribuidos
48
Félix García Carballeira (1999)
Sistemas Distribuidos
Servidor (datagramas)
49
Félix García Carballeira (1999)
Cliente (datagramas)
void main(int argc, char *argv[]){
struct sockaddr_in server_addr, client_addr;
struct hostent *hp;
int s, num[2], res;
clilen = sizeof(client_addr);
while (1)
{
recvfrom(s, (char *) num, 2* sizeof(int), 0,
(struct sockaddr *)&client_addr, &clilen);
if (argc != 2){
printf("Uso: client <direccion_servidor> \n");
exit(0);
}
res = num[0] + num[1];
sendto(s, (char *)&res, sizeof(int), 0,
(struct sockaddr *)&client_addr,
s = socket(AF_INET, SOCK_DGRAM, 0);
hp = gethostbyname (argv[1]);
clilen);
bzero((char *)&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
memcpy (&(server_addr.sin_addr), hp->h_addr, hp->h_length);
server_addr.sin_port = 7200;
}
}
Sistemas Distribuidos
50
Félix García Carballeira (1999)
Sistemas Distribuidos
Cliente (datagramas)
51
Félix García Carballeira (1999)
Rendimiento I
bzero((char *)&client_addr, sizeof(client_addr));
client_addr.sin_family = AF_INET;
client_addr.sin_addr.s_addr = INADDR_ANY;
client_addr.sin_port = htons(0);
• Tiempo en realizar una suma utilizando datagramas y streams.
Incluye todas las operaciones (creación de sockets, conexión,
etc.)
• Biprocesador Pentiun II 266 MHZ con Linux.
bind (s, (struct sockaddr *)&client_addr, sizeof(client_addr));
num[0] = 2;
UDP
TCP
Local
2,2 ms
2,74 ms
Remoto
6,8 ms
7,35 ms
num[1] = 5;
sendto(s, (char *)num, 2 * sizeof(int), 0,
(struct sockaddr *) &server_addr, sizeof(server_addr));
recvfrom(s, (char *)&res, sizeof(int), 0, NULL, NULL);
printf("2 + 5 = %d\n", res);
close(s);
}
Sistemas Distribuidos
52
Félix García Carballeira (1999)
Sistemas Distribuidos
53
Félix García Carballeira (1999)
Rendimiento II
Sockets de Java
• Tiempo en realizar únicamente el envío y la recepción de datos
(sendto, recvfrom, read, write). Sin conexiones
UDP
TCP
Local
0,21 ms
0,34 ms
Remoto
0,29 ms
0,44 ms
Sistemas Distribuidos
54
Félix García Carballeira (1999)
• El paquete java.net de Java permite crear sockets TCP/IP.
• Clases para sockets datagrama
– DatagramSocket
– DatagramPacket
• Clases para sokcets stream
– ServerSocket
– Socket
Sistemas Distribuidos
55
Félix García Carballeira (1999)
Sockets datagrama
Sockets stream
• DatagramPacket: implementa un objeto que permite enviar o
recibir paquetes:
– Constructor: DatagramPackect
– Métodos: getAddres, getPort, setData,...
• DatagramSocket: implementa un socket que se puede utilizar
para enviar o recibir datagramas.
– Constructor: DatagramSocket
– Métodos: send, receive, close, setSoTimetout,
getSoTimetout, ...
• La clase socket implementa un socket stream
• La clase ServerSocket implementa un socket a utilizar en los
servidores para esperar la conexiones de los clientes
• Alunas clases abstractas para trabajar con streams:
– OutputStream
• close, flush, write
– InputStream
• close, read
– DataOutputStream
• writeByte, writeInt, writeDouble,...
– DataInputStream
• readBye, readInt, readDouble,...
Sistemas Distribuidos
56
Félix García Carballeira (1999)
Cliente-servidor con sockets streams de Java
Sistemas Distribuidos
57
Félix García Carballeira (1999)
Cliente-servidor con sockets streams de Java
Servidor
Proceso servidor
Cliente
S erverS ocket(puerto);
ServerSocket()
Proceso cliente
socket(host, puerto)
accept();
Socket()
O uto putS tream
Abrir conexión
Accept()
Obtener
streams
InputS tream
Accept()
Crear
Thread
Obtener
streams
Petición
write()
InputS tream
O uto putS tream
clo se()
Sistemas Distribuidos
clo se()
58
Félix García Carballeira (1999)
read()
Respuesta
Sistemas Distribuidos
read()
write()
close()
close()
59
Félix García Carballeira (1999)
Ejemplo
M áquina A
cliente
Servidor (streams)
import
import
import
import
M áquina B
sumar(5,2)
servidor
5+2
NÚCLEO
Restulado = 7
NÚCLEO
RED
Sistemas Distribuidos
60
Félix García Carballeira (1999)
java.lang.* ;
java.io.* ;
java.net.* ;
java.util.* ;
public class servidor
{
public static void main ( String [] args)
{
ServerSocket serverAddr = null;
Socket sc = null;
int num[] ; // petición
int res;
try {
serverAddr = new ServerSocket(2500);
}
catch (Exception e){
System.err.println("Error creando socket");
}
Sistemas Distribuidos
61
Servidor (streams)
Félix García Carballeira (1999)
Cliente (streams)
while (true){
try {
sc = serverAddr.accept(); // esperando conexión
InputStream istream = sc.getInputStream();
ObjectInput in = new ObjectInputStream(istream);
num = (int[]) in.readObject();
res = num[0] + num[1];
DataOutputStream ostream =
new DataOutputStream(sc.getOutputStream());
ostream.writeInt(res);
ostream.flush();
sc.close();
}
catch(Exception e) {
System.err.println("excepcion " + e.toString() );
e.printStackTrace() ;
}
}
}
import
import
import
import
java.lang.* ;
java.io.* ;
java.net.* ;
java.util.* ;
public class client
{
public static void main ( String [] args)
{
int res;
int num[] = new int[2];
if (args.length != 1) {
System.out.println("Uso: cliente <host>");
System.exit(0);
}
try {
// se crea la conexión
String host = args[0];
Socket sc = new Socket(host, 2500); // conexión
}
Sistemas Distribuidos
62
Félix García Carballeira (1999)
Sistemas Distribuidos
Cliente (streams)
num[1] = 2;
//prepara la petición
sc.close();
System.out.println("La suma es " + res);
}
catch (Exception e){
System.err.println("excepcion " + e.toString() );
e.printStackTrace() ;
}
}
}
64
import
import
import
import
java.lang.* ;
java.io.* ;
java.net.* ;
java.util.* ;
public class servidor
{
public static void main ( String [] args)
{
DatagramSocket s = null;
DatagramPacket in, out;
InetAddress client_addr = null;
int client_port;
byte brecv[] = new byte[100];
byte bsend[] = new byte[100];
int num[], res;
try {
s = new DatagramSocket(2500);
in = new DatagramPacket(brecv, 100); // paquete para recibir la
// solicitud
s.writeObject(num); s.flush();
res = istream.readInt();
Sistemas Distribuidos
Félix García Carballeira (1999)
Servidor (datagramas)
OutputStream ostream = sc.getOutputStream();
ObjectOutput s = new ObjectOutputStream(ostream);
DataInputStream istream = new DataInputStream(sc.getInputStream());
num[0] = 5;
63
Félix García Carballeira (1999)
Sistemas Distribuidos
65
Félix García Carballeira (1999)
Servidor (datagramas)
Servidor (datagramas)
while (true) {
s.receive(in); // esperamos a recibir los paquetes
bsend = baos.toByteArray();
out = new DatagramPacket(bsend, bsend.length,
client_addr, client_port);
brecv = in.getData(); // obtener datos
client_addr = in.getAddress();
client_port = in.getPort();
// desempaquetar los datos.
ByteArrayInputStream bais = new ByteArrayInputStream(brecv) ;
ObjectInputStream dis = new ObjectInputStream(bais);
num = (int[])dis.readObject();
res = num[0] + num[1];
s.send(out);
}
}
catch(Exception e) {
System.err.println("excepcion " + e.toString() );
e.printStackTrace() ;
}
}
}
ByteArrayOutputStream baos = new ByteArrayOutputStream() ;
DataOutputStream dos = new DataOutputStream(baos);
dos.writeInt(res);
Sistemas Distribuidos
66
Félix García Carballeira (1999)
Sistemas Distribuidos
Cliente (datagramas)
import
import
import
import
67
Félix García Carballeira (1999)
Cliente (datagramas)
java.lang.* ;
java.io.* ;
java.net.* ;
java.util.* ;
try
{
// se crea el socket del cliente
s = new DatagramSocket(); // en el puerto que quiera
public class client{
public static void main ( String [] args)
{
byte bsend[] = new byte[100];
byte brecv[] = new byte[100];
InetAddress server_addr = null;
DatagramSocket s = null;
DatagramPacket in = null;
DatagramPacket out = null;
int res;
int num[] = new int[2];
// direción del servidor
server_addr = InetAddress.getByName(args[0]);
num[0] = 2;
num[1] = 5;
// empaquetar los datos.
ByteArrayOutputStream baos = new ByteArrayOutputStream() ;
ObjectOutputStream
dos = new ObjectOutputStream(baos);
dos.writeObject(num) ;
if (args.length != 1) {
System.out.println("Uso: cliente <host>");
System.exit(0);
}
Sistemas Distribuidos
68
bsend = baos.toByteArray() ; // se obtiene el buffer (datagrama)
// un único envio
out = new DatagramPacket(bsend, bsend.length, server_addr, 2500);
s.send(out);
Félix García Carballeira (1999)
Sistemas Distribuidos
Cliente (datagramas)
69
Félix García Carballeira (1999)
Rendimiento I
// se recibe el datagrama de respuesta
in = new DatagramPacket(brecv, 100);
s.receive(in);
• Tiempo en realizar una suma utilizando datagramas y streams.
Incluye todas las operaciones (creación de sockets, conexión,
etc.)
• Biprocesador Pentiun II 266 MHZ con Linux.
// se obtiene el buffer
brecv = in.getData();
// se desempaqueta
ByteArrayInputStream bais = new ByteArrayInputStream(brecv) ;
DataInputStream dis = new DataInputStream(bais);
res = dis.readInt();
System.out.println("Datos recibidos " + res);
}
catch (Exception e)
{
System.err.println("<<<<<excepcion " + e.toString() );
e.printStackTrace() ;
}
UDP
TCP
Local
211 ms
235,6 ms
Remoto
217 ms
286 ms
}
}
Sistemas Distribuidos
70
Félix García Carballeira (1999)
Sistemas Distribuidos
71
Félix García Carballeira (1999)
Rendimiento II
Rendimiento: sockets Unix contra Java
• Tiempo en realizar únicamente el envío y la recepción de datos
(sin conexiones)
UDP
TCP
Local
6,25 ms
152 ms
Remoto
4,95 ms
139 ms
Sistemas Distribuidos
72
Félix García Carballeira (1999)
• Streams con conexión (en ms)
local
235,6
Java
Sokcets Unix 2,74
• Datagramas con conexión (en ms)
local
211
Java
Sokcets Unix 2,2
Sistemas Distribuidos
local
152
Java
Sokcets Unix 0,34
Sistemas Distribuidos
74
remoto
139
0,44
remoto
4,95
0,29
Félix García Carballeira (1999)
Funcionamiento de las RPC
• El proceso que realiza la llamada empaqueta los argumentos en
un mensaje, se los envía a otro proceso y espera el resultado
• El proceso que ejecuta el procedimiento extrae los argumentos
del mensaje, realiza la llamada de forma local, obtiene el
resultado y se lo envía de vuelta al proceso que realizó la
llamada
• Objetivo: acercar la semántica de las llamadas a procedimiento
convencional a un entorno distribuido (transparencia).
Sistemas Distribuidos
76
Félix García Carballeira (1999)
RPC
• RPC (remote procedure call): llamadas a procedimiento remoto
(Birrel y Nelson 1985)
• Híbrido entre llamadas a procedimientos y paso de mensajes
• Las RPC constituyen el núcleo de muchos sistemas distribuidos
• Llegaron a su culminación con DCE (Distributed Computing
Environment)
• Han evolucionado hacia orientación a objetos
– Invocación de métodos remotos (CORBA, RMI)
• Datagramas sin conexión (en ms)
local
6,25
Java
Sokcets Unix 0,21
remoto
217
6,8
73
Rendimiento: sockets Unix contra Java
• Streams sin conexión (en ms)
remoto
286
7,35
Félix García Carballeira (1999)
Sistemas Distribuidos
75
Félix García Carballeira (1999)
Llamadas y mensajes en una RPC
SISTEMA CLIENTE
SISTEMA SERVIDO R
PROCEDIM IENTOS
CÓDIGO DE LA APLICACIÓN
INICIO
LLAMADA
RESG UAR DO
CLIEN TE
Sistemas Distribuidos
EJECUTA
PROCEDIM IENTO
REMOTO
PREPARA
2
9
ENVÍA
ENTRADA
RECIBE
SALIDA
CONVIERTE
ENTRADA
RESG UAR DO
SERVID OR
1 ENTRADA
CONVIERTE
SALIDA
BIBLIOT.
EJECUCIÓN
RPC
5
FIN
LLAMADA
6
PREPARA
SALIDA
7
TRANSMITE
SALIDA
BIBLIOT.
EJECUCIÓN
RPC
8
77
RECIBE
Y PASA
4
3
Félix García Carballeira (1999)
Resguardos (stubs)
RPC: protocolo básico
• Se generan automáticamente por el software de RPC
• En el cliente:
– Localizan al servidor
– Empaquetan los parámetros y construyen los mensajes
– Envían el mensaje al servidor
– Espera la recepción del mensaje y devuelven los resultados
• En el servidor
– Realizan tareas similares
• Los resguardos son independientes de la implementación que se
haga del cliente y del servidor. Sólo dependen de la interfaz.
“enlaza con
el servidor”
servidor
cliente
Se registra con un
servicio de nombres
prepara
parámetros,
envía petición
recibe petición
Ejecuta el
procedimiento
envía petición
Desempaqueta
la respuesta
Sistemas Distribuidos
78
Félix García Carballeira (1999)
Problemas de diseño de las RPC
•
•
•
•
Lenguaje de definición de interfaces. Generador de resguardos.
Transferencia de parámetros
Enlace dinámico (binding)
Semántica de las RPC en presencia de fallos
Sistemas Distribuidos
80
Félix García Carballeira (1999)
Sistemas Distribuidos
Sistemas Distribuidos
82
Félix García Carballeira (1999)
Félix García Carballeira (1999)
Lenguaje de definición de interfaces
• Una interfaz especifica un nombre de servicio que utilizan los
clientes y servidores
• Nombres de procedimientos y parámetros (entrada y salida).
• Los compiladores pueden diseñarse para que los clientes y
servidores se escriban en lenguajes diferentes.
• Tipos de RPC
– Integrado con un lenguaje de programación (Cedar, Argus)
– Lenguaje de definición de interfaces específico para describir
las interfaces entre los clientes y los servidores (RPC de Sun
y RPC de DCE)
Sistemas Distribuidos
Transferencia de parámetros
• Una de las funciones de los resguardos es empaquetar los
parámetros en un mensaje: aplanamiento (marshalling)
• Problemas en la representación de los datos
– Servidor y cliente pueden ejecutar en máquinas con
arqutecturas distintas
– XDR (external data representation) es un estándar que
define la representación de tipos de datos
• Problemas con los punteros
– Una dirección sólo tiene sentido en un espacio de direcciones
79
81
Félix García Carballeira (1999)
Enlace dinámico (Binding)
• Enlace dinámico: permite localizar objetos con nombre en un
sistema distribuido, en concreto, servidores que ejecutan las
RPC.
• Tipos de enlace:
– Enlace no persistente: la conexión entre el cliente y el
servidor se establece en cada RPC.
– Enlace persistente: la conexión se mantiene después de la
primera RPC.
• Útil en aplicaciones con muchas RPC repetidas
• Problemas si lo servidores cambian de lugar
Sistemas Distribuidos
83
Félix García Carballeira (1999)
Enlazador dinámico
Semántica de las RPC en presencia de fallos
• Enlazador dinámico (binder): Es el servicio que mantiene una
tabla de traducciones entre nombres de servicio y direcciones.
Incluye funciones para:
– Registrar un nombre de servicio
– Eliminar un nombre de servicio
– Buscar la dirección correspondiente a un nombre de servicio
• Como localizar al enlazador dinámico:
– Ejecuta en una dirección fija de un computador fijo.
– El sistema operativo se encarga de indicar su dirección
– Difundiendo un mensaje (broadcast) cuando los procesos
comienzan su ejecución.
• Problemas que pueden plantear las RPC
– El cliente no es capaz de localizar al servidor
– Se pierde el mensaje de petición del cliente al servidor
– Se pierde el mensaje de respuesta del servidor al cliente
– El servidor falla después de recibir una petición
– El cliente falla después de enviar una petición
Sistemas Distribuidos
Sistemas Distribuidos
84
Félix García Carballeira (1999)
Cliente no puede localizar al servidor
•
•
•
•
El servidor puede estar caído
El cliente puede estar usando una versión antigua del servidor
La versión ayuda a detectar accesos a copias obsoletas
Cómo indicar el error al cliente
– Devolviendo un código de error (-1)
85
Félix García Carballeira (1999)
Pérdida de mensajes del cliente
• Es la más fácil de tratar
• Se activa una alarma (timeout) después de enviar el mensaje
• Si no se recibe una respuesta se retransmite
• No es transparente
– Ejemplo: sumar(a,b)
– Elevando una excepción
• Necesita un lenguaje que tenga excepciones
Sistemas Distribuidos
86
Félix García Carballeira (1999)
Sistemas Distribuidos
Pérdidas en los mensajes de respuesta
87
Félix García Carballeira (1999)
Fallos en los servidores
• Más difícil de tratar
• Se pueden emplear alarmas y retransmisiones, pero:
– ¿Se perdió la petición?
– ¿Se perdió la respuesta?
– ¿El servidor va lento?
• Algunas operaciones pueden repetirse sin problemas
(operaciones idempotentes)
– Una transferencia bancaria no es idempotente
• Solución con operaciones no idempotentes es descartar
peticiones ya ejecutadas
– Un nº de secuencia en el cliente
– Un campo en el mensaje que indique si es una petición
original o una retransmisión
• El servidor no ha llegado a ejecutar la operación
– Se podría retransmitir
• El servidor ha llegado a ejecutar la operación
• El cliente no puede distinguir los dos
Sistemas Distribuidos
Sistemas Distribuidos
88
Félix García Carballeira (1999)
• ¿Qué hacer?
– No garantizar nada
– Semántica al menos una vez
• Reintentar y garantizar que la RPC se realiza al menos una vez
• No vale para operaciones no idempotentes
– Semántica a lo más una vez
• No reintentar, puede que no se realice ni una sola vez
– Semántica de exactamente una
• Sería lo deseable
89
Félix García Carballeira (1999)
Fallos en los clientes
Aspectos de implementación
• La computación está activa pero ningún cliente espera los
resultados (computación huérfana)
– Gasto de ciclos de CPU
– Si cliente rearranca y ejecuta de nuevo la RPC se pueden
crear confusiones
• Protocolos RPC
– Orientados a conexión
• Fiabilidad se resuelve a bajo nivel, peor rendimiento
– No orientados a conexión
– Uso de un protocolo estándar o un específico
• Algunos utilizan TCP o UDP como protocolos básicos
Sistemas Distribuidos
90
Félix García Carballeira (1999)
Sistemas Distribuidos
Programación con un paquete de RPC
91
Félix García Carballeira (1999)
Programación con RPC
DESARROLLO
DE LA
INTER FA Z
• El programador debe proporcionar:
– La definición de la interfaz (idl)
FIC H ER O
D E D EFINIC IÓN
D E IN TE RFA Z
COM PILADOR IDL
• Nombres de las funciones
• Parámetros que el cliente pasa al servidor
• Resultados que devuelve el servidor al cliente
C A BEC ER A
R ESG UA R DO
EN C LIE NTE
– El código del cliente
– El código del servidor
• El compilador de idl proporciona:
– El resguardo del cliente
– El resguardo del servidor
C OM PILAD O R C
FIC H ER OS
FUE NTE D EL
C LIE NTE
C A BE C E R A
C A BE C E R A
C OM PILAD O R C
OB JETO
R ESG UA R DO
EN C LIE NTE
FIC H ER OS
OB JETO DE L
C LIE NTE
R ESG UA R DO
EN SER VID OR
FIC H ER OS
FUE NTE D EL
SER VID OR
B IBLIOT.
R PC
B IBLIOT.
R PC
FIC H ER OS
OB JETO DE L
SER VID OR
M ON TAD OR
92
Félix García Carballeira (1999)
Sistemas Distribuidos
OB JETO
R ESG UA R DO
EN SER VID OR
M ON TAD OR
EJEC U TA B LE
D EL
SER VID OR
DESARROLLO EJEC U TA B LE
D EL
DEL
C LIE NTE
CLIEN TE
Sistemas Distribuidos
C OM PILAD O R C
C OM PILAD O R C
93
DESARROLLO
DEL
SERVIDOR
Félix García Carballeira (1999)
Ejemplos de paquetes de RPC
RPC de Sun
• RPC de Sun (1990) utilizado en NFS
• RPC del proyecto ANSA (1989) desarrollado por Architecture
Project Management Ltd. (Cambridge, Inglaterra)
• RPC de DCE (1990), estándar desarrollado por Open Software
Foundation
• Utiliza como lenguaje de definición de interfaz XDR:
– Una interfaz contiene un nº de programa y un nº de versión.
– Cada procedimiento específica un nombre y un nº de
procedimiento
– Los procedimientos sólo aceptan un parámetro.
– Los parámetros de salida se devuelven mediante un único
resultado
– El lenguaje ofrece una notación para definir:
•
•
•
•
Sistemas Distribuidos
94
Félix García Carballeira (1999)
constantes
definición de tipos
estructuras, uniones
programas
Sistemas Distribuidos
95
Félix García Carballeira (1999)
RPC de Sun
Ejemplo
• rpcgen es el compilador de interfaces que genera:
– Resguardo del cliente
– Resguardo del servidor y procedimiento principal del
servidor.
– Procedimientos para el aplanamiento (marshalling)
– Fichero de cabecera (.h) con los tipos y declaración de
prototipos.
• Enlace dinámico
– El cliente debe especificar el host donde ejecuta el servidor
– El servidor se registra (nº de programa, nº de versión y nº de
puerto) en el port mapper local
– El cliente envía una petición al port mapper del host donde
ejecuta el servidor
Sistemas Distribuidos
96
Félix García Carballeira (1999)
M áquina A
cliente
M áquina B
sum ar(5,2)
servidor
5+2
N Ú CLE O
R estulado = 7
N Ú CLE O
R ED
Sistemas Distribuidos
Esquema de la aplicación
97
Félix García Carballeira (1999)
suma.x
clien te.c
A rch ivo s p ara
el clien te
su m a_c ln t.c
struct peticion {
int a;
int b;
};
su m a_x d r.c
rep cg en
A rch ivo s
co m u n es
su m a.x
su m a.h
su m a_s vc.c
program SUMAR {
version SUMAVER {
int SUMA(peticion) = 1;
} = 1;
} = 99;
A rch ivo s p ara
el se rv id o r
servid o r.c
Sistemas Distribuidos
98
Félix García Carballeira (1999)
Sistemas Distribuidos
suma.h
99
Félix García Carballeira (1999)
servidor.c
#ifndef _SUMA_H_RPCGEN
#define _SUMA_H_RPCGEN
#include "suma.h"
int *suma_1_svc(peticion *argp, struct svc_req *rqstp)
{
static int result;
#include <rpc/rpc.h>
struct peticion {
int a;
int b;
};
result = argp->a + argp->b;
return(&result);
#define
#define
extern
extern
SUMAVER ((u_long)99)
SUMA ((u_long)1)
int * suma_1(peticion *, CLIENT *);
int * suma_1_svc(peticion *, struct svc_req *);
}
#endif /* !_SUMA_H_RPCGEN */
Sistemas Distribuidos
100
Félix García Carballeira (1999)
Sistemas Distribuidos
101
Félix García Carballeira (1999)
cliente.c
cliente.c
#include "suma.h"
/* localiza al servidor */
clnt = clnt_create(host, SUMAR, SUMAVER, "udp");
if (clnt == NULL) {
clnt_pcreateerror(host);
exit(1);
}
suma_1_arg.a = 5;
suma_1_arg.b = 2;
main( int argc, char* argv[] )
{
CLIENT *clnt;
int *res;
peticion suma_1_arg;
char *host;
if(argc < 2) {
printf("usage: %s server_host\n", argv[0]);
exit(1);
}
host = argv[1];
res = suma_1(&suma_1_arg, clnt);
if (res == NULL) {
clnt_perror(clnt, "call failed:");
}
printf("La suma es %d\n", *res);
clnt_destroy( clnt );
}
Sistemas Distribuidos
102
Félix García Carballeira (1999)
Sistemas Distribuidos
103
Félix García Carballeira (1999)
Rendimiento I
Rendimiento II
• Rendimiento de sockets y RPC. Incluye todo el tiempo. Enlace,
conexión en sockets, etc.
• Sólo incluye el tiempo en realiza la operación. Envío/recepción
en sockets. Ejecución de suma_l en RPC
Sockets
UDP
RPC
TCP
UDP
Sockets
TCP
RPC
UDP
TCP
UDP
0,34 ms 0,28 ms
Local
2,2 ms 2,74 ms
4,61 ms
5,43 ms
Local
0,21 ms
Remoto
6,8 ms 7,35 ms
8,21 ms
8,77 ms
Remoto
0,29 ms 0,44 ms
Sistemas Distribuidos
104
Félix García Carballeira (1999)
Sistemas Distribuidos
Entornos orientados a objetos
0,36 ms
105
TCP
0,43 ms
0,55 ms
Félix García Carballeira (1999)
Modelo de objetos
• Tendencia actual hacia sistemas compuestos por un conjunto de
objetos que interactúan entre sí.
– Un programa solicita servicios invocando los métodos que
ofrece un objeto
– La invocación de métodos se ve como un paso de mensajes
• ANSA (1989-1991) fue el primer proyecto que intentó
desarrollar una tecnología para modelizar sistemas distribuidos
complejos
– Utilizaba un diseño orientado a objetos
• Estándares:
– RMI: invocación de métodos remotos de Java
– CORBA: expande DCE con servicios orientados a objetos
– DCOM: versión CORBA de Microsoft
Sistemas Distribuidos
106
Félix García Carballeira (1999)
Sistemas Distribuidos
107
Félix García Carballeira (1999)
Modelo de objetos en sistemas distribuidos
M áquina A
M áquina B
Sistemas Distribuidos
M áquina C
108
Félix García Carballeira (1999)
Arquitectura de RMI
Invocación de métodos remotos en Java
• RMI (Remote method invocation)
• El soporte para RMI en Java está basado en las interfaces y
clases definidas en los paquetes java.rmi y java.rmi.server
• RMI ofrece
– Mecanismos para crear servidores y objetos cuyos métodos
se puedan invocar remotamente
– Mecanismos que permiten a los clientes localizar los objetos
remotos
Sistemas Distribuidos
109
Félix García Carballeira (1999)
¿Cómo escribir aplicaciones con RMI?
1
• Nivel de transporte: se encarga de las comunicaciones y de
establecer las conexiones necesarias
• Nivel de gestión de referencias remotas: trata los aspectos
relacionados con el comportamiento esperado de las referencias
remotas (mecanismos de recuperación, etc.)
• Nivel de resguardo/esqueleto (proxy/skeleton) que se encarga
del aplanamiento de los parámetros
– proxy: resguardo local. Cuando un cliente realiza una
invocación remota, en realidad hace una invocación de un
método del resguardo local.
– Esqueleto (skeleton): recibe las peticiones de los clientes,
realiza la invocación del método y devuelve los resultados.
D efinición de la
interfaz rem o ta
2
Im plem entación d e la
interfaz rem o ta
(.java)
3
javac
(.class)
4
8
C liente
usa
Esqueleto
(.class)
Esqueleto
(.class)
5
(.java)
9
A rrancar R M IRegistry
javac
6
C rear los ob jeto s
(.class)
10
7
Ejectuar
C liente
R eg istrar los ob jeto s
SERVID OR
C LIENT E
Sistemas Distribuidos
110
Félix García Carballeira (1999)
Sistemas Distribuidos
Invocación remota
0iTXLQD 111
Félix García Carballeira (1999)
Ejemplo
0iTXLQD UPLUHJLVWU\
50,
&OLHQWH
Servido r
(.class)
rm ic
50,
50,
6HUYLGRU
Sistemas Distribuidos
112
Félix García Carballeira (1999)
Sistemas Distribuidos
113
Félix García Carballeira (1999)
Modelización de la interfaz remota (Sumador)
public interface Sumador extends java.rmi.Remote
{
public int sumar(int a, int b)
throws java.rmi.RemoteException;
}
Sistemas Distribuidos
114
Félix García Carballeira (1999)
Clase que implementa la interfaz (SumadorImpl)
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
public class SumadorImpl extends UnicastRemoteObject implements
Sumador {
public SumadorImpl(String name) throws RemoteException {
super();
try {
System.out.println("Rebind Object " + name);
Naming.rebind(name, this);
} catch (Exception e){
System.out.println("Exception: " + e.getMessage());
e.printStackTrace();
}
}
public int sumar (int a, int b) throws RemoteException {
return a + b;
}
}
Sistemas Distribuidos
Código del servidor (SumadorServer)
import java.rmi.*;
import java.rmi.server.*;
public class SumadorServer {
public static void main (String args[]) {
int res = 0;
System.out.println("Setting Security Manager");
if (System.getSecurityManager() == null) {
System.setSecurityManager(new RMISecurityManager());
}
System.out.println("Security Manager Installed");
try {
SumadorImpl misuma = new SumadorImpl("MiSumador");
} catch(Exception e) {
System.err.println("System exception" + e);
}
}
}
Sistemas Distribuidos
116
Félix García Carballeira (1999)
• Cualquier programa que quiera instanciar un objeto de esta clase
debe realizar el registro con el servicio de nombrado de la
siguiente forma:
Sumador misuma = (Sumador)Naming.lookup("rmi://" + args[0] + "/"
+"MiSumador");
• Antes de arrancar el cliente y el servidor, se debe arrancar el
programa rmiregistry en el servidor para el servicio de nombres
Sistemas Distribuidos
117
Félix García Carballeira (1999)
¿Cómo se ejecuta?
• Compilación
public class SumadorClient {
public static void main(String args[]){
int res = 0;
try {
System.out.println("Buscando Objeto ");
Sumador misuma = (Sumador)Naming.lookup("rmi://" + args[0] +
"/" +"MiSumador");
res = misuma.sumar(5, 2);
System.out.println("5 + 2 = " + res);
}
catch(Exception e){
System.err.println(" System exception");
}
System.exit(0);
}
}
Sistemas Distribuidos
Félix García Carballeira (1999)
Registro del servicio
Código en el cliente (SumadorCliente)
import java.rmi.registry.*;
import java.rmi.server.*;
115
118
Félix García Carballeira (1999)
javac Sumador.java
javac SumadorImpl.java
javac SumadorClient.java
javac Sumador Server.java
• Generación de los esqueletos
rmic SumadorImpl
• Ejecución del programa de registro de RMI
rmiregistry
• Ejecución del servidor
java SumadorServer
• Ejecución del cliente
java SumadorCliente <host-del-servidor>
Sistemas Distribuidos
119
Félix García Carballeira (1999)
Rendimiento
Comparando el rendimiento
• Tiempo en realizar una suma con RMI
• Biprocesador Pentiun II 266 MHZ con Linux.
Con
lookup
Sin
lookup
Local
684 ms
17,5 ms
Remoto
652 ms
15 ms
Sistemas Distribuidos
120
Sockes Unix TCP
Sockets Unix UDP
Sockets Java TCP
Sockets Java UDP
RPC-TCP
RPC-UDP
RMI-Java
Félix García Carballeira (1999)
Sistemas Distribuidos
CORBA
122
Félix García Carballeira (1999)
C liente
Cliente
Invocación
dinám ica d e
R epositorio
de interfaces
Interfaz
ORB
Adaptador
esqueletos
Esqueletos Invocación
estáticos dinám ica d e de objetos
esqueletos
R epositorio
de
im plm entación
Object Request Broker
Sistemas Distribuidos
124
Remoto
Sin conexión
0,44
0,21
139
4,95
0,55
0,34
15
Félix García Carballeira (1999)
C liente
S ervidor
O bjeto X O bjeto Y
Llam ar a f()
Invoca el
método
f del
objetoX
Código
Datos
f
f
O bject R equest Broker
M ecanism o de R PC
Sistemas Distribuidos
Invoca el
método
f del
objeto Y
123
Félix García Carballeira (1999)
Componentes de CORBA
Im plem entación
de objetos
Resguardo
del cliente
Local
Sin conexión
0,34
0,29
152
6,25
0,43
0,44
17,5
121
S ervidor
Estructura de CORBA
Invocación
dinám ica
Remoto
Con conexión
7,35
6,8
286
217
8,77
8,21
652
RPC contra ORB
• CORBA (common object request broker architecure)
• Estándar desarrollado por ONG (Object management group) a
principios de los 90
• El modelo de referencia CORBA incluye el conjunto de
componentes y servicios que debería ofrecer una plataforma
distribuida
• CORBA especifica:
– Una arquitectura de componentes cliente-servidor cooperantes.
– Un conjunto de funcionalidades
– Un lenguaje de descripción de interfaces para definir objetos
• La interfaz es independiente del lenguaje y se puede utilizar desde
diferentes lenguajes de programación (C, C++, Java, ...)
Sistemas Distribuidos
Local
Con conexión
2,74
2,2
235,6
211
5,43
4,61
684
Félix García Carballeira (1999)
• Lenguaje de definición de interfaces (IDL). Especifica objetos,
métodos, excepciones, herencia.
• Compilador del IDL. Genera los resguardos y esqueletos.
• ORB (Object Request Broker). Se ocupa de las comunicaciones,
enlaces (bindings) y gestionar la invocación de métodos. Toda
implementación CORBA debe ofrecer al menos un ORB.
• Resguardos del cliente. Define la forma en la que los clientes
invocan los servicios correspondientes del servidor. Generado
por el compilador de IDL.
• Interfaz de invocación dinámica. Permite a los clientes
descubrir e invocar nuevas interfaces en tiempo de ejecución. No
necesitan un resguardo precompilado.
• Repositorio de interfaces. Base de datos distribuida que
contiene las versiones de las interfaces definidas.
Sistemas Distribuidos
125
Félix García Carballeira (1999)
Componentes de CORBA
Ejemplo
• El interfaz ORB. API de los servicios que ofrece ORB (pe:
convertir referencias a objetos en cadenas de caracteres y
viceversa)
• Adaptador de objetos básico. Componente de ORB que soporta
la activación de objetos en los servidores.
• Esqueletos estáticos. Proporcionan las interfaces estáticas para
cada servicio exportado por un servidor. Generados por el
compilador de IDL.
• Interfaz para la invocación dinámica de esqueletos. Interfaz
para manejar la invocación de métodos dinámicos (no están en
los esqueletos).
• Repositorio de implementación. Repositorio con las clases que
soporta un servidor.
Sistemas Distribuidos
126
Félix García Carballeira (1999)
M áquina A
NÚCLEO
NÚCLEO
RED
Sistemas Distribuidos
127
Félix García Carballeira (1999)
sumar.idl
// sumar.idl
Repositorio
de interfaces
module Sumador
{
interface sumar
{
long suma(in long a, in long b);
};
};
Precompilar
Esqueleto
del servidor
Resguardo
del cliente
Implementar
el cliente
Restulado = 7
2
Escribir
la interfaz
(IDL)
3
8
servidor
5+2
Programación con invocación estática
1
M áquina B
sumar(5,2)
cliente
4
Adaptador
de objetos
Implementar
el servidor
6
9
Compilar
5
Compilar
7
Re pos itorio
de
im ple m e ntac ión
Cliente
Sistemas Distribuidos
Servidor
128
Félix García Carballeira (1999)
Sistemas Distribuidos
Servidor
130
Félix García Carballeira (1999)
Implementación del servidor
// SumarServer.java: The Sumador Server main program
class SumarServer
{ static public void main(String[] args)
{ try
{ // Initialize the ORB
org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args, null);
// Initialize the BOA
org.omg.CORBA.BOA boa = orb.BOA_init();
// Create the Sumador object
SumarImpl sumador = new SumarImpl("My Sumador");
// Export to the ORB the newly created object
boa.obj_is_ready(sumador);
// Ready to service requests
boa.impl_is_ready();
}
catch(org.omg.CORBA.SystemException e)
{ System.err.println(e);}
}
}
Sistemas Distribuidos
129
Félix García Carballeira (1999)
// SumarImpl.java: The Sumador Implementation
class SumarImpl extends Sumador._sumarImplBase
{
private int sum;
// Constructors
SumarImpl(String name)
{ super(name);
System.out.println("Creado objeto Sumador ");
}
public int suma(int a, int b)
{
int res = a+b;
return res;
}
}
Sistemas Distribuidos
131
Félix García Carballeira (1999)
Cliente
Comunicación en aplicaciones paralelas
// SumarClient.java Static Client, VisiBroker for Java
class SumarClient
{ public static void main(String args[])
{ try
{
// Initialize the ORB
org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args, null);
// Bind to the Sumador Object
Sumador.sumar sumador = Sumador.sumarHelper.bind(orb, "My Sumador");
long resultado = sumador.suma(5, 2);
System.out.println("La Suma de 5 y 2 es = " + resultado);
} catch(org.omg.CORBA.SystemException e)
{ System.err.println("System Exception");
System.err.println(e);
}
}
• Aplicaciones paralelas en multicomputadores y entornos
distribuidos:
– La aplicación se divide en procesos que ejecutan en
procesadores diferentes
– La coordinación y la comunicación se realiza mediante paso
de mensajes
• En aplicaciones paralelas es necesario utilizar mecanismos de
comunicación más fiables y más eficientes.
• Ejemplos:
– PVM (parallel virtual machine)
– MPI (message passing interface)
}
Sistemas Distribuidos
132
Félix García Carballeira (1999)
Sistemas Distribuidos
MPI
133
Félix García Carballeira (1999)
MPI-2
• MPI es una interfaz estándar para el desarrollo de aplicaciones
paralelas que utilizan paso de mensajes.
• Desarrollado en 1994 por el Forum de MPI
– http://www.mpi-forum.org
• Características:
– Portabilidad de las aplicaciones
• Interfaz para C y Fortran.
• Aparece en 1997
• Incluye aclaraciones y correcciones al estándar básico
• Características:
– Creación y gestión de procesos
– Operaciones colectivas extendidas
– Interfaz de E/S paralela (MPI-IO)
– Interfaces para lenguajes adicionales
– Eficiencia
– Funcionalidad
Sistemas Distribuidos
134
Félix García Carballeira (1999)
Sistemas Distribuidos
Características
•
•
•
•
Comunicación punto a punto (bloqueanntes, no bloqueantes).
Operaciones asíncronas
Operaciones colectivas
Grupos de procesos
– Los procesos se identifican mediante un nº entero (0,...)
– Un grupo lista los identificadores de los procesos.
– Un comunicador contiene al grupo e información sobre dicho
grupo.
Semántica multithread
Tipos de datos (MPI_INT, MPI_FLOAT, ..)
Capacidad para definir tipos de datos derivados.
Soporte para redes heterogéneas
Sistemas Distribuidos
136
Félix García Carballeira (1999)
Algunas funciones
• MPI_COMM_WORLD: comunicador por defecto que incluye
a todos los procesos
•
•
•
•
135
Félix García Carballeira (1999)
• int MPI_Init(int *argc, char ***argv);
– Inicia la biblioteca de MPI.
• int MPI_Finalize(void);
– Finaliza un programa MPI, liberando los recursos. No
interrumpe las comunicaciones pendientes.
• int MPI_Abort(MPI_Comm comm, int errcode);
– Aborta la ejecución
• int MPI_Comm_rank(MPI_Comm comm, int *rank);
– Devuelve el identificador asociado a un proceso dentro del
grupo de procesos asociado al comunicador
• int MPI_Commsize(MPI_Comm comm, int *size);
– Devuelve el nº de procesos que hay en el grupo asociado al
comunicador
Sistemas Distribuidos
137
Félix García Carballeira (1999)
Operaciones punto a punto
• int MPI_Send(void *buf, int count, MPI_Datatype datatype,
int dest, int tag, MPI_Comm comm);
– Envía un mensaje (buf) de count elementos de tipo datatype.
– El proceso receptor es dest dentro del grupo de procesos
asociado al comunicador (comm)
– El mensaje lleva asociado una etiqueta (tag).
• int MPI_Recv(void *buf, int count, MPI_Datatype datatype,
int source, int tag, MPI_Comm comm,
MPI_Status *status);
– Recibe un mensaje (en buf) de count elementos de tipo
datatype del proceso emisor (source) dentro del grupo de
procesos asociado al comunicador (comm)
– Se recibe el mensaje del proceso source con etiqueta (tag).
Sistemas Distribuidos
138
Félix García Carballeira (1999)
Ejemplo
main(int argc, char **argv)
{
int me, size; int SOME_TAG = 0;
char buf[1024];
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &me);
MPI_Comm_size(MPI_COMM_WORLD, &size);
if (me == 0)
MPI_Send(buf, 1024, MPI_CHAR,
1, SOME_TAG, MPI_COMM_WORLD);
else
MPI_Recv(buf, 1024, MPI_CHAR,
0, SOME_TAG, MPI_COMM_WORLD);
MPI_Finalize();
}
Sistemas Distribuidos
Ejemplo de operaciones colectivas
139
Félix García Carballeira (1999)
Operaciones colectivas
• int MPI_Barrier(MPI_Comm comm);
– Bloquea la ejecución del proceso hasta que todos los
miembros del grupo la ejecuten.
• int MPI_Bcast(void *buf, int count, MPI_Datatype datatype,
int root, MPI_Comm comm);
– El proceso root envía un mensaje a todos los procesos del
grupo.
• int MPI_Scatter(void *sendbuf, int sendcont,
MPI_Datatype sendtype, void *recbuf, int recvcount,
MPI_Datatype recvtype, int root, MPI_Comm comm);
– Operación scatter del proceso root al resto, incluido él.
Sistemas Distribuidos
140
Félix García Carballeira (1999)
Operaciones colectivas
Sistemas Distribuidos
• int MPI_Reduce(void *sendbuf, void *recvbuf, int count,
MPI_Datatype datatype, MPI_Op po, int root,
MPI_Comm comm);
– El proceso root combina la información de todos los
procesos del grupo usando la operación op y deja el resultado
en el buffer de recepción.
– Operaciones: MPI_MAX, MPI_SUM,...
– Posibilidad de definir nuevas operaciones.
142
Félix García Carballeira (1999)
Implementación de operaciones colectivas
Félix García Carballeira (1999)
...
.
• int MPI_Gather(void *sendbuf, int sendcont,
MPI_Datatype sendtype, void *recbuf, int recvcount,
MPI_Datatype recvtype, int root, MPI_Comm comm);
– Operación gather del proceso de todos los procesos del grupo
al root (incluido él).
Sistemas Distribuidos
141
Lista
Cadena
Árbo l b inario
Sistemas Distribuidos
Árbo l b inom ial
143
Félix García Carballeira (1999)
Ejemplo
Esqueleto del programa
• Programa que calcula el nº π
#include “mpi.h”
#include <stdio.h>
int main(int argc, char **argv)
{
while (1) {
/* el proceso maestro pide al usuario el número de intervalos */
/* El proceso maestro envía a todos el número de intervalos */
MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);
/*
procesos esclavos calcular el área de los diferentes subintervalos
*/
/* El proceso raiz recoge los resultados y realiza la suma */
MPI_Reduce(&mypi, &pi, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
}
MPI_Finalize();
}
Sistemas Distribuidos
144
Félix García Carballeira (1999)
Sistemas Distribuidos
145
Ejemplo
Ejemplo
#include “mpi.h”
#include <stdio.h>
int main(int argc, char **argv)
{
int n, myid, numprocesos, i;
double mypi, pi, h, sum, x;
else {
h = 1.0/(double)n;
sum = 0.0;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &numprocesos);
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
while(1)
{
if (myid == 0)
{
printf(“Introduzca el nº de intervalos: “);
scanf(“%d”, &n);
}
MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);
if (n==0)
break;
Sistemas Distribuidos
146
Félix García Carballeira (1999)
for(i = myid + 1; i <= n; i += numprocesos) {
x = h * ((double)i - 0.5);
sum += (4.0 / (1.0) + x*x));
}
mypi = h * sum;
MPI_Reduce(&mypi, &pi, 1, MPI_DOUBLE, MPI_SUM, 0,
MPI_COMM_WORLD);
if (myid == 0) {
printf(“PI es aproximadamente %f\n”, pi);
}
}
MPI_Finalize();
}
Sistemas Distribuidos
Algunas implementaciones
• LAM, implementación de libre distribución, disponible para redes
de estaciones de trabajo
• MPICH, (libre distribución), disponible para estaciones de trabajo
y SP2. Incluye MPI-IO (ROMIO).
• MPI de IBM (comercial). IBM utiliza esta implementación como
lenguaje nativo para la programación de SP2. Implementación
con semántica thread-safe.
• MiMPI, desarrollada en el DATSI (UPM) y está disponible para
redes de estaciones de trabajo y SP2.
Sistemas Distribuidos
Félix García Carballeira (1999)
148
Félix García Carballeira (1999)
147
Félix García Carballeira (1999)
MiMPI
• Implementación multithread de MPI
• Objetivos de MiMPI
– Adecuada para el desarrollo de programas multithread
(thread-safe)
– Empleo de threads en su implementación
• Facilita la implementación de operaciones asíoncronas
• Mejora el rendimiento de operaciones colectivas
–
–
–
–
Uso de compresión
Portabilidad entre plataformas
Ofrecer una interfaz gráfica para arrancar programas MPI
Herramientas de depuración y visualización
Sistemas Distribuidos
149
Félix García Carballeira (1999)
Arquitectura de MiMPI
Operaciones colectivas en MiMPI
M P I_B cast()
M P I_B cast()
P VM
MPI
2 th reads
send
N threads
send
receive
receive
XMP
PO SIX
M P I_B cast()
M P I_B cast()
M P I_B cast()
2 th reads
2 th reads
M P I_B cast()
TCP/IP
M P I_B cast()
2 th reads
Sistemas Distribuidos
150
Félix García Carballeira (1999)
Sistemas Distribuidos
151
Implementación actual
Félix García Carballeira (1999)
Evaluación
• MiMPI implementa sólo un subconjunto de todas las funciones
de MPI
• Primer prototipo de una interfaz gráfica para el arranque de
programas que utilizan MiMPI
• Plataformas:
– Redes de estaciones de trabajo (Linux, Unix)
– IBM SP2
3
3 4 5
3
3
4
scatter
ping-pong
3
3
3
3 4 5
3
3
broadcast
Sistemas Distribuidos
152
Félix García Carballeira (1999)
Sistemas Distribuidos
Rendimiento de MiMPI
Ping-ping
(SP2)
5
4
5
gather
153
Félix García Carballeira (1999)
ping-pong multithread
60
MiMPI
MPICH
IBM's MPI
Throughput (MB/s)
50
3URFHVV 3URFHVV 3LQJSRQJ
40
7KUHDGV
30
7KUHDGV
20
10
51
2
1K
B
2K
B
4K
B
8K
B
16
KB
32
KB
64
KB
12
8K
B
25
6K
B
51
2K
B
1M
B
25
6
64
12
8
8
32
4
16
2
1
0
Message length (bytes)
Sistemas Distribuidos
154
Félix García Carballeira (1999)
Sistemas Distribuidos
155
Félix García Carballeira (1999)
Rendimiento del ping-pong multithread (SP2)
Broadcast
(SP2)
70
1 thread
60
Broadcast
2 threads
4 threads
Throughput (MB/s)
50
80
MiMPI
MPICH
IBM's MPI
70
8 threads
60
Throughput (MB/s)
16 threads
40
30
20
50
40
30
20
10
10
8K
B
16
KB
32
KB
64
KB
12
8K
B
25
6K
B
51
2K
B
1M
B
4K
B
2K
B
51
2
1K
B
64
25
6
12
8
32
8
16
2
1
4
0
64
12
8
25
6
51
2
1K
B
2K
B
4K
B
8K
B
16
KB
32
KB
64
KB
12
8K
B
25
6K
B
51
2K
B
1M
B
8
32
4
16
2
1
0
Message length (bytes)
Message length (bytes)
Sistemas Distribuidos
156
Félix García Carballeira (1999)
Sistemas Distribuidos
157
Gather
Gather
(SP2)
Scatter
45
MiMPI
MPICH
IBM's MPI
MiMPI
MPICH
IBM's MPI
40
35
Throughput (MB/s)
Throughput (MB/s)
Scatter
Scatter
(SP2)
Gather
30
25
Félix García Carballeira (1999)
20
15
10
30
25
20
15
10
5
5
0
1
2
4
8
16
32
64
128
256
512
1KB
2KB
4KB
0
8KB 16KB 32KB 64KB
1
Message length (bytes)
Sistemas Distribuidos
158
2
4
8
16
32
64
128
256
512
1KB
2KB
4KB
8KB 16KB 32KB 64KB
Message length (bytes)
Félix García Carballeira (1999)
Sistemas Distribuidos
Evaluación en estaciones con Linux (ping-pong)
159
Félix García Carballeira (1999)
Trabajo futuro
16
12
Throughput (MB/s)
• Finalizar la implementación de todas las primitivas de MPI
• Optimizar MiMPI para reducir la latencia de las operaciones
para mensajes de tamaño pequeño
• Incorporar técnicas de compresión
• Incorporar las características de MPI-2 (MPI-IO)
• Realizar una evaluación más exhaustiva de MiMPI
• Trabajar en herramientas de depuración, visualización y gestión
del entorno de MiMPI
MiMPI
MiMPI lzrw3
MiMPI zlib/bs
MiMPI zlib/bc
MPICH
14
10
8
6
4
2
0
256
512
1K
2K
4K
8 K 16 K 32 K 64 K 128
K
256
K
512
K
1M
2M
4M
8M
Message size
Sistemas Distribuidos
160
Félix García Carballeira (1999)
Sistemas Distribuidos
161
Félix García Carballeira (1999)
Comunicación de grupos
Grupos de procesos
• Un grupo es un conjunto de procesos que actúan juntos
• Mensaje multicast: mensaje enviado por un proceso a los
miembros de un grupo de procesos.
• Los mensajes multicast son útiles para construir sistemas
distribuidos con las siguientes características:
– Tolerancia a fallos basado en servidores replicados
– Localizar objetos en servicios distribuidos
– Mejor rendimiento mediante datos replicados
– Actualización múltiple a un grupo de procesos (news)
Sistemas Distribuidos
162
Félix García Carballeira (1999)
CERR AD O
AB IER TO
DE CO M PAÑ ER O S
JERÁRQ U ICO
Sistemas Distribuidos
Grupos de procesos
163
Félix García Carballeira (1999)
Pertenencia a un grupo
• Grupos cerrados se pueden usar para procesamiento paralelo
• Grupos abiertos se pueden utilizar para servidores replicados
• En los grupos de compañeros las decisiones se toman
colectivamente
• En los jerárquicos hay un coordinador y los demás son
trabajadores (punto único de fallo)
• Se necesita un método para crear, destruir, incorporarse o dejar
un grupo de procesos
• Una posible solución es emplear un servidor de grupos
– Con una base de datos con el estado actual de los grupos
– Un punto único de fallo
Sistemas Distribuidos
Sistemas Distribuidos
164
Félix García Carballeira (1999)
Propiedades de la comunicación en grupos
• Multicast atómico:
– Un mensaje transmitido a un grupo es recibido por todos los
procesos del grupo o por ninguno.
• Multicast fiable:
– Método que intenta entregar un mensaje a todos los
miembros pero sin garantía de conseguirlo
• Multicast totalmente ordenado:
– Cuando varios mensajes se transmiten a un grupo todos los
mensajes alcanzan a los miembros del grupo en el mismo
orden.
Sistemas Distribuidos
166
Félix García Carballeira (1999)
165
Félix García Carballeira (1999)
Ejemplo de multicast sin ordenación
P1
P2
P3
P4
A
B
A
B
Tiem po
Sistemas Distribuidos
167
Félix García Carballeira (1999)
Trabajos prácticos
Trabajos prácticos
• Desarrollo de un programa ping-pong entre dos procesos
utilizando TCP y UPD con sockets UNIX y de Java. Medir la
latencia y el ancho de banda para diferentes tamaños de mensajes.
Comparar el rendimiento local con el remoto. Analizar las
posibles pérdidas de paquetes.
• Implementar un envío multicast con TCP y UDP y analizar la
latencia del envío, el ancho de banda y la fiabilidad del envío.
Obtener los resultados en función del tamaño del mensajes y el
número de procesos. Comparar el rendimiento local con el remoto.
Sistemas Distribuidos
168
Félix García Carballeira (1999)
• Implementar un esquema cliente/servidor para transferir un
fichero en bloques. Considerar diferentes implementaciones:
– Colas de mensajes POSIX
– Sockets TCP y UDP (UNIX, Java)
– RPC
– CORBA
Analizar:
1) El tiempo de desarrollo y la facilidad del mismo
2) El rendimiento de la transferencia (local, remoto)
Sistemas Distribuidos
169
Félix García Carballeira (1999)
Descargar