Este documento presenta el diseño de una solución para buscar, cargar y descargar contenido de un servidor central en una arquitectura P2P. Se desarrollaron tres aplicaciones: un cliente P2P, un servidor P2P y un simulador P2P. Se incluyen diagramas de clases y explicaciones de las clases y paquetes más importantes de cada aplicación. Finalmente, se explica de forma conceptual el funcionamiento de cada aplicación.
2. PROYECTO 1
BORIS RAINIERO PÉREZ GUTIÉRREZ
(Código 2007.17.640)
CRISTIAN CAMILO CASTELLANOS RODRÍGUEZ
(Código 2009.17.691)
SOLUCIONARIO
FRANCISCO RUEDA
PROFESOR
SISTEMAS DISTRIBUIDOS
MAESTRÍA EN INGENIERÍA DE SISTEMAS Y COMPUTACIÓN
UNIVERSIDAD DE LOS ANDES
FACULTAD DE INGENIERÍA
BOGOTÁ D.C.
2009
3. TABLA DE CONTENIDO
DISEÑO DE LA SOLUCIÓN 4
FUNCIONAMIENTO CONCEPTUAL 11
EVALUACIÓN DEL DESEMPEÑO DE IMPLEMENTACIONES 15
CONCLUSIONES 16
4. Magister en Ingeniería de Sistemas y Computación 4
Sistemas Distribuidos
DISEÑO DE LA SOLUCIÓN
Para la realización del proyecto sobre búsqueda, carga y descarga de contenido a un servidor central en
arquitectura P2P se realizaron tres aplicaciones. Cada una está especializada en una función en particular, de
este modo tenemos: aplicación cliente, aplicación servidor y aplicación simulador. A continuación se profundiza
un poco en su funcionamiento:
Cliente P2P (P2PClient1). Esta aplicación se encarga de llevar a cabo las operaciones de buscar,
descargar y subir contenido todo desde y hacia el servidor central. Adicional, establece una carpeta
local para almacenar el contenido descargado. Solicita también la dirección IP del servidor.
Servidor P2P (P2PServer2). Esta aplicación se encarga de atender las solicitudes enviadas por los
clientes conectados. Las peticiones son de carga, descarga, búsqueda y localización. Esta última es una
comunicación que se hace desde el cliente para verificar la existencia del servidor. El material cargado
al servidor es almacenado en una carpeta en el servidor. Dicha carpeta es requerida antes de
arrancarlo. El servidor puede subir como secuencial o manejando un pool de hilos. Para el caso del
pool de hilos, el servidor emplea un arreglo de 10 hilos. El servidor mantiene en memoria la lista de
archivos de los cuales dispone para compartir. Esta lista se arma al arrancar el servidor, con los
archivos que encuentre en la carpeta compartida y se actualiza cada vez que un usuario sube un nuevo
archivo.
Simulador P2P (P2PClientSimulator3). Esta aplicación se encarga de las pruebas contra el servidor al
recargarlo en distintas operaciones. Las operaciones se hacen simultáneamente con el fin de evaluarlo
ante distintas cargas y analizar qué tipo de administración de peticiones es mejor.
DIAGRAMA DE CLASES
En esta sección se presentarán los diagramas de clases empleados para el desarrollo de la solución. Estos
diagramas están disponibles dentro de la carpeta DiagramaClases incluida en las fuentes de cada proyecto.
La presentación de los diagramas es como sigue a continuación. La Figura 1 corresponde al diagrama de clases
de la aplicación Servidor P2P, la Figura 2 corresponde a la aplicación Cliente P2P y finalmente, la Figura 3
corresponde a la aplicación Simulador P2P.
Los diagramas incluyen al final de esta sección, una explicación sobre los paquetes y clases más importantes
para el funcionamiento. La documentación de todas las clases no se hace por razones prácticas y porque
algunas son solo de apoyo y cumples una función del negocio.
El funcionamiento de las aplicaciones, por separado, se explica en la sección siguiente, de forma conceptual.
Esto permite una visión de alto nivel del comportamiento de las mismas.
1
Nombre del proyecto en Java incluido en la carpeta source.
2
Nombre del proyecto en Java incluido en la carpeta source.
3
Nombre del proyecto en Java incluido en la carpeta source.
8. Magister en Ingeniería de Sistemas y Computación 8
Sistemas Distribuidos
A continuación se presenta la explicación de las clases o paquetes más sobresalientes de las aplicaciones.
PROYECTO CLASE EXPLICACIÓN
P2PServer ServerGUI Contiene la definición de la interfaz gráfica y sus
componentes. El servidor utiliza solo una
pantalla en la cual se inicia o detiene el servidor,
además de tener un cuadro de mensajes.
ServerFacade Esta clase es la puerta de entrada a la lógica de
negocio del servidor. Es dónde se ejecutan las
instrucciones de arrancar y detener servidor,
además de atender las solicitudes que lleguen y
direccionarlas de acuerdo al tipo de atención
seleccionada (Secuencial o Pool).
ThreadPool Clase encarga de la administración del pool de
hilos que empleará el servidor. Dispone de ellos,
y los envía a dormir o despertar según la
necesidad.
Worker Es la unidad básica de procesamiento en el pool
de hilos. Corresponde entonces, al hilo per se.
Realiza el procesamiento de la solicitud que
corresponda.
SocketListenerPoolThread Hilo encargado de atender la petición, obtener
un hilo del pool y procesar la petición.
SocketListenerThread Hilo encargado de procesar la solicitud cuando el
servidor está configurado en modo secuencial.
ContentManipulation Esta clase es quien procesa en última instancia la
petición del cliente. Determina si es una petición
de conexión, de búsqueda, de carga o descarga.
Intercambia mensajes con el cliente y objetos,
según corresponda.
P2PClient ClientGUIStart Contiene la definición de la interfaz gráfica de
inicio y sus componentes. En esta pantalla se
solicita la carpeta de descarga y la ip del servidor
ClientGUI Interfaz gráfica secundaria, donde se realizan las
operaciones de búsqueda, carga, descarga y
ejecución de los archivos
ConnectAction Clase que implementa ActionListener para el
evento conectar de la primera pantalla. Realiza
las verificaciones de los datos de entrada y se
encarga de comunicarse con la ClientFacade
OpenFolder Dedicada al manejo del componente FileChooser
que se encuentra en las interfaces gráficas y
administra la navegación local de directorios
SendAction Escuchador que procesa en envío de archivos
comunicándose con la fachada ClientFacade
9. Magister en Ingeniería de Sistemas y Computación 9
Sistemas Distribuidos
ClientFacade Esta clase hace de puente entre las clases
escuchadoras de eventos en la interfaz y la
lógica del negocio. Es una clase Singleton dónde
se hace los llamados a los métodos de
búsqueda, envío y recepción de archivos que
implementa la clase Communication.
Communication Realiza las operaciones de bajo nivel en cuanto a
manejo de sockets y envío de tramas.
P2PClientSimulator ClientSimulatorGUIStart Contiene la definición de la interfaz gráfica de
inicio y sus componentes. En esta pantalla se
solicita la carpeta de descarga, archivos para
simular carga y la ip del servidor
ClientSimulatorGUI Interfaz gráfica secundaria, donde se realizan las
operaciones de búsqueda, simulación de carga,
descarga y carga‐descarga.
ConnectAction Clase que implementa ActionListener para el
evento conectar de la primera pantalla. Realiza
las verificaciones de los datos de entrada y se
encarga de comunicarse con la
ClientSimulatorFacade.
SimularAction Encarga de atender la petición desde la GUI de
simular algún escenario. Invoca los métodos
correspondientes de las clases Carga, Descarga,
ThreadCarga y ThreadDescarga
ClientSimulatorFacade Esta clase es la que permite a las clases que
escuchan los eventos de la interfaz, el acceso a
la lógica del negocio. Es una clase Singleton
dónde se hace los llamados a los métodos de
búsqueda, envío y recepción de archivos.
Communication Ejecuta la búsqueda de archivos en el servidor y
la replicación de los ficheros con los cuales se
realizará la simulación.
Carga Clase que contiene el proceso de simulación de
carga concurrente mediante un arreglo de n
hilos, donde n es el número de solicitudes a
simular. Cada hilo que genera es de tipo
ThreadRequestUpload
Descarga Clase que contiene el proceso de simulación de
descarga concurrente mediante un arreglo de n
hilos, donde n es el número de solicitudes a
simular. Cada hilo que genera es de tipo
ThreadRequestDownload
ThreadRequestUpload Clase que extiende de Thread, y encargada de
administrar una solicitud de carga de archivo al
10. Magister en Ingeniería de Sistemas y Computación 10
Sistemas Distribuidos
servidor
ThreadRequestDownload Clase que extiende de Thread, y encargada de
administrar una solicitud de descarga de un
archivo del servidor
11. Magister en Ingeniería de Sistemas y Computación 11
Sistemas Distribuidos
FUNCIONAMIENTO CONCEPTUAL
Esta sección presenta una explicación del funcionamiento general de la aplicación.
La primera imagen que se presenta (Figura 4) corresponde al funcionamiento de todo el sistema cuando el
usuario selecciona la opción de conectar, luego de haber ingresado la dirección del servidor. El servidor siempre
escucha en el puerto 50000. El cliente envía una petición de existencia (exists) y el servidor responde un OK.
Figura 4. Funcionamiento de la función de Conectar del cliente.
La figura 5 presenta la comunicación por parte del cliente cuando se busca por contenido. El cliente envía la
consulta que puede contener varios comodines. La búsqueda de archivos es sensible a las mayúsculas. El
servidor recibe la petición, compara el requerimiento con la lista de archivos en memoria y retorna, en un
ArrayList, la lista de los archivos que coinciden con el criterio.
Figura 5. Búsqueda de contenido.
La figura 6 presenta la comunicación por parte del cliente cuando se descarga contenido del servidor. El cliente
informa que quiere descargar el archivo música.mp3. La aplicación cliente envía la solicitud al servidor, éste se
encarga de verificar que el archivo esté al momento de la descarga y envía el archivo. El archivo se verifica con
una lista en memoria de todos los archivos disponibles para compartir. La lista se actualiza al arrancar el
servidor y cada vez que un usuario sube un nuevo material.
Figura 6. Descarga de contenido.
La figura 7 presenta la comunicación con el servidor cuando se quiere cargar un contenido. El cliente manifiesta
la intención de cargar un archivo seleccionado. La aplicación cliente revisa el tamaño y la extensión y envía la
12. Magister en Ingeniería de Sistemas y Computación 12
Sistemas Distribuidos
información por la red. El servidor la recibe valida la extensión y el tamaño y, si está correcta, retorna un OK a la
aplicación cliente. Al recibir el OK, la aplicación cliente envía el archivo, el servidor lo recibe y lo genera en la
carpeta compartida.
Figura 7. Carga de contenido.
13. Magister en Ingeniería de Sistemas y Computación 13
Sistemas Distribuidos
EVALUACIÓN DEL DESEMPEÑO DE IMPLEMENTACIONES
Después de realizar pruebas y mediciones en los diferentes escenarios propuestos, y adicionalmente
contrastando el comportamiento de las mismas pruebas en una red de área local podemos llegar a las
siguientes inferencias.
Nota: El detalle de cada prueba que sirve de origen a todos los gráficos de esta sección, están consignados en
dos archivos de Excel, incluidos en la entrega de este documento (SoloCarga.xlsx y SoloDescarga.xlsx).
Tiempos promedio para atender solicitudes de carga: De la Fig. 8 se puede concluir que los tiempos promedios de carga
sobre la implementación de servidor secuencial son menores para archivos grandes. No así para peticiones con archivos de
menos de 100 KB, donde el servidor de pool tuvo una mejor eficiencia.
Promedio Tiempo Solicitud Promedio Tiempo Solicitud
Carga MB Carga KB
120,00 0,80 0,73
102,37
0,70
100,00
84,67 0,60
Tiempo (segs)
Tiempo (segs)
80,00
0,50
0,41
60,00 Prom Sec 0,40 0,33 Prom Sec
Prom Pool 0,30 Prom Pool
40,00 29,75 32,29
0,20 0,16
20,00 0,06 0,04
4,49 6,38 0,10
0,00 0,00
10 50 100 10 50 100
Solicitudes Solicitudes
Figura 8. Gráficas de tiempos promedio para atender solicitudes de carga.
Tiempos promedio para atender solicitudes de descarga: La Fig. 9 refuerza la superioridad de desempeño del servidor
secuencial; pero en mayor proporción. Este comportamiento es más atenuado en escenarios de pocas peticiones (10).
Promedio Tiempo Solicitud Promedio Tiempo Solicitud
Descarga MB Descarga KB
5,00 4,76
120,00 112,40
4,50
100,00 4,00
Tiempo (segs)
3,50
Tiempo (segs)
80,00
3,00
60,00 Prom Sec 2,50 Prom Sec
2,00 Prom Pool
Prom Pool
40,00 1,50 1,08
19,71
18,78 22,03 0,76
12,70 1,00 0,58
20,00
4,16 0,50 0,20 0,16
0,00 0,00
10 50 100 10 50 100
Solicitudes Solicitudes
Figura 9. Gráficas de tiempos promedio para atender solicitudes de descarga.
14. Magister en Ingeniería de Sistemas y Computación 14
Sistemas Distribuidos
Tiempos promedio para atender solicitudes de carga‐descarga simultánea: La Fig. 10 presenta una llamativa diferencia en
el proceso de carga‐descarga, donde el servidor secuencial se comporta mejor en la carga de archivos grandes, en contraste
la implementación de pool responde mejor a la carga de archivos pequeños.
Para el proceso de descarga las dinámicas de las dos implementaciones son similares, con una sutil diferencia a favor de la
implementación secuencial.
Promedio Tiempo Solicitud Promedio Tiempo Solicitud
Carga‐Descarga Simultáneo KB Carga‐Descarga Simultáneo MB
2,00 80,00
1,74
1,80 68,20
70,00
1,60
1,32 60,00
Tiempo (segs)
1,40 1,25
Tiempo (segs)
1,20 1,03 50,00
1,00 Sec 40,00 Sec
0,80 Pool 27,16 Pool
30,00 22,17 24,22
0,60
0,40 20,00
0,20 10,00
0,00 0,00
Carga Descarga Carga Descarga
Operación
Operación
Figura 10. Gráficas de tiempos promedio para atender solicitudes de carga‐descarga simultánea.
Cantidad de perdidas en solicitudes de carga: Este indicador (Fig. 11) nos ofrece una fortaleza de la implementación de pool
al minimizar la cantidad de pérdidas ocurridas en ambientes de 50 solicitudes de carga y descarga simultánea y para
archivos de 10 MB. Para el caso de archivos pequeños, en ninguna modalidad se presentaron pérdidas para 50 peticiones
simuladas (carga y descarga) o menos.
Cantidad de Pérdidas Cantidad de Pérdidas
Carga MB Carga KB
60 1
49 1
50 1
40
40 1
Pérdidas
Pérdidas
1
30 Sec 1 Sec
Pool 0
20 Pool
0
10 0
0 0 0 0 0 0 0 0 0 0 0
0 0
10 50 100 10 50 100
Solicitudes
Solicitudes
Figura 11. Gráficas de cantidad de pérdidas en solicitudes de carga.
Cantidad de perdidas en solicitudes de descarga: Durante las pruebas de carga y descarga para el caso de los archivos
pequeños (menores de 100 KB) nos vimos abocados a grandes fluctuaciones en las pérdidas ocurridas que dificultaron un
poco estas mediciones. Sin embargo promediamos los resultados de varias pruebas para llegar a estas cifras. La Fig. 12.
evidencia una mejor tolerancia a perdidas del servidor pool para archivos grandes, y del servidor secuencial para archivos
pequeños.
15. Magister en Ingeniería de Sistemas y Computación 15
Sistemas Distribuidos
Cantidad de Pérdidas Cantidad de Pérdidas
Descarga MB Descarga KB
60 30
25
48
50 25
39
40 20
Pérdidas
Pérdidas
30 Sec 15 Sec
20 Pool 10 Pool
10 5
0 0 0 0 1
0 0 0 0
0 0
10 50 100 10 50 100
Solicitudes Solicitudes
Figura 12. Gráficas de cantidad de pérdidas en solicitudes de descarga.
Cantidad máxima de solicitudes sin pérdida: Desde esta nueva óptica, verificable en la Fig. 13, debemos decir,
especialmente con archivos grandes, el servidor secuencial evita más eficientemente, en ambientes de solicitudes
concurrentes, la pérdida de paquetes
Cantidad Máxima de Solicitudes Cantidad Máxima de Solicitudes
sin Pérdidas(MB) sin Pérdidas (KB)
140 130
60 58
120 112
58 98
100 92
Pérdidas
56
Pérdidas
54 52 52 52 80 62
52 51 51 Sec 60 52 Sec
50 Pool 40 Pool
48 20
46 0
Carga MB Descarga MB Carga‐Descarga MB Carga KB Descarga KB Carga‐Descarga KB
Operación Operación
Figura 13. Gráficas de cantidad máxima de solicitudes sin pérdida.
16. Magister en Ingeniería de Sistemas y Computación 16
Sistemas Distribuidos
CONCLUSIONES
Finalizado el trabajo, hemos evidenciado muchas situaciones inesperadas así como también, casos no
constantes de resultados.
Respecto a las situaciones inesperadas, la sorpresa fue el trabajo que realiza un servidor secuencial para
atender solicitudes en paralelo. Siempre consideramos que procesos concurrentes atendidos por un pool sería
mucho más eficiente que cualquier otro método. Eso quedó descartado al finalizar este trabajo. Pero también
contemplamos el hecho de que estos resultados podrían estar comprometidos de acuerdo a las características
de las máquinas empleadas y a los volúmenes de solicitudes concurrentes. Un ejemplo de esto sería: ¿qué pasa
con las peticiones concurrentes de más de 1000? ¿Cuál es el número ideal de hilos en un pool para ser
eficientes? ¿Y si usáramos un balanceador de cargas el resultado sería el mismo? Si bien estas pruebas nos
llevan a concluir que no podemos dar todo por sentado, es importante considerar muchos más ambientes a la
hora de realizar pruebas, con el fin de dar siempre la mejor opción de solución a quien lo requiera. Algo que
comprobamos fue el rendimiento en distintas máquinas. Las pruebas ejecutadas como locales (servidor y
cliente) en un computador de escritorio fueron distintas a las pruebas locales en un portátil. Claro, todo esto
cabe dentro de las especificaciones a considerar mencionadas anteriormente.
En relación al otro tema, evidenciamos muchos casos donde el servidor no se comportaba como se esperaba.
Para representar la idea damos un ejemplo: Iniciábamos el servidor en modo pool, luego el simulador, y
generábamos 100 solicitudes de descarga. La primera vez nos generó un resultado óptimo en tiempo y en
pérdidas, ya que solo se generó una pérdida. El siguiente intento, nos dio un tiempo promedio mayor y algunas
pérdidas más, hicimos un tercer intento y el tiempo se estabilizó pero las pérdidas aumentaron. Con esto
llegamos a otra conclusión, y es que la carga generada en disco tanto en el servidor como en el cliente, afecta el
rendimiento de las pruebas consecutivas, lo mismo que la congestión de la red, como si quedara ruido luego de
un proceso pesado de concurrencia. Importante es encontrar maneras como de limpiar el servidor luego de un
proceso cargado. Pero no es lo mismo al tener un servidor todo el día atendiendo peticiones pesadas, para esto,
se requieren encontrar y probar distintas implementaciones que permitan siempre un ágil desempeño de la
máquina. Un claro ejemplo de la importancia de esto, es tomar a un banco, una petición perdida puede
significar una transacción menos, y esto implica un importante detrimento financiero. O un ejemplo a mayor
escala, la implementación de peticiones de compra de una tarjeta de crédito. Perder peticiones de crédito de
compra con tarjeta un 24 de diciembre sería crítico para ellos.