Está en la página 1de 5

SECCIÓN 3.

5 MIGRACIÓN DE CÓDIGO 103

Por supuesto, necesitamos más. Los servidores virtuales Linux no solamente separan el siste-
ma de archivos, sino que por lo general comparten información sobre procesos, direcciones de red,
uso de memoria, y así por el estilo. En consecuencia, una máquina física en realidad se particiona
en diversas unidades, cada unidad corresponde a un completo y totalmente funcional ambiente
Linux aislado de las demás partes. Podemos encontrar un resumen de los servidores virtuales Linux
en Potzl y colaboradores, (2005).

3.5 MIGRACIÓN DE CÓDIGO


Hasta aquí, nos hemos preocupado primordialmente de los sistemas distribuidos en los cuales la
comunicación está limitada para el paso de datos. Sin embargo, existen situaciones en las cuales el
paso de programas, a veces incluso mientras se ejecutan, simplifica el diseño de un sistema distri-
buido. En esta sección daremos un vistazo cercano a lo que realmente es la migración de código.
Iniciaremos mediante la consideración de diferentes métodos para implementar la migración de
código, seguida por una explicación con respecto a la manera de tratar con los recursos locales que
utiliza un programa en migración. Un problema particularmente difícil es la migración de código
en sistemas heterogéneos, la cual también explicaremos.

3.5.1 Métodos para la migración de código


Antes de revisar las diferentes formas de migración de código, consideremos primero el porqué mi-
grar código pudiera ser útil.

Razones para la migración de código


De manera tradicional, la migración de código en sistemas distribuidos se realizó en la forma de mi-
gración de procesos en los cuales todo un proceso se trasladaba de una máquina a otra (Milojicic
y cols., 2000). El traslado de un proceso en ejecución hacia una máquina diferente es una tarea
costosa e intrincada, y debiera existir una mejor razón para hacerlo. Esta razón siempre ha sido el
rendimiento. La idea básica es que se puede mejorar el rendimiento general del sistema si los pro-
cesos se trasladan desde una máquina muy saturada hacia máquinas ligeramente saturadas. Con
frecuencia, la carga se expresa en términos de la longitud de la cola o de la inicialización de la CPU,
pero también se utilizan otros indicadores de rendimiento.
Los algoritmos de distribución mediante los cuales tomamos las decisiones con respecto a la
ubicación y distribución de tareas referentes a un conjunto de procesadores juegan un papel impor-
tante en los sistemas de cómputo intenso. Sin embargo, en muchos sistemas distribuidos modernos,
la optimización de la capacidad de cómputo es menos importante que, por ejemplo, tratar de mini-
mizar la comunicación. Más aún, debido a la heterogeneidad de las plataformas subyacentes y de
las redes de computadores, la mejora en el rendimiento a través de la migración de código se basa
generalmente en razones cualitativas en lugar de en modelos matemáticos.
Como ejemplo, considere un sistema cliente-servidor en donde el servidor administra una base
de datos de gran tamaño. Si el cliente de una aplicación necesita realizar muchas operaciones de
104 CAPÍTULO 3 PROCESOS

bases de datos que involucran grandes cantidades de datos, pudiera ser mejor enviar parte de la apli-
cación del cliente hacia el servidor y enviar por la red solamente los resultados. De lo contrario, la
red podría colapsarse con la transferencia de datos desde el servidor hacia el cliente. En este caso,
la migración de código se basa en la presunción de que a menudo tiene sentido procesar los datos
cerca de donde residen.
Podemos utilizar el mismo razonamiento para migrar partes del servidor al cliente. Por ejem-
plo, en muchas aplicaciones interactivas de base de datos, los clientes necesitan llenar formas que
posteriormente se traducen a series de operaciones en la base de datos. El procesamiento de la for-
ma del lado del cliente, y el sólo envío de la forma completa al servidor, puede en ocasiones evitar
que un número relativamente alto de mensajes cortos necesite cruzar la red. El resultado es que el
cliente percibe un mejor rendimiento, mientras que el servidor invierte menos tiempo en el proce-
samiento de la forma y la comunicación.
El soporte para migración de código también puede ayudar a mejorar el rendimiento mediante
la explotación del paralelismo, pero sin las usuales e intrincadas relaciones de la programación en
paralelo. Un ejemplo típico es la búsqueda de información en la web. Es relativamente sencillo im-
plementar una consulta de búsqueda en la forma de un pequeño programa móvil, llamado agente
móvil, que se mueve de sitio en sitio. Al hacer distintas copias de dicho programa, y enviar cada
copia a diferentes sitios, podemos lograr un aumento lineal de la velocidad para utilizar solamente
una instancia individual del programa.
Además de mejorar el rendimiento, existen otras razones para soportar la migración de código.
La más importante es la relacionada con la flexibilidad. El método tradicional para construir apli-
caciones distribuidas es crear particiones de la aplicación en diferentes partes, y decidir por adelan-
tado el lugar donde se deben ejecutar. Por ejemplo, este método ha desembocado en diferentes
aplicaciones cliente-servidor multiniveles, las cuales explicamos en el capítulo 2.
Sin embargo, si el código se puede trasladar entre diferentes máquinas, es posible configurar
sistemas distribuidos de manera dinámica. Por ejemplo, suponga que un servidor implementa una
interfaz estándar para un sistema de archivos. Para permitir el acceso de clientes remotos al siste-
ma de archivos, el servidor hace uso del protocolo propietario. Por lo general, la implementación
del lado del cliente de la interfaz del sistema, basada en dicho protocolo, necesitará estar ligada con
la aplicación del cliente. Este método requiere que el software se encuentre disponible para el cliente
en el momento que se desarrolla la aplicación del cliente.
Una alternativa es permitir que el servidor proporcione la implementación del cliente no antes
de que sea estrictamente necesario, esto es, cuando el cliente se conecta con el servidor. En ese
punto, el cliente descarga de manera dinámica la implementación, sigue los pasos necesarios de im-
plementación, y luego invoca al servidor. Este principio aparece en la figura 3-17. Este modelo de
código que se traslada dinámicamente desde un sitio remoto requiere que el protocolo para la des-
carga y la inicialización del código sea estandarizado. Además, es necesario que el código descarga-
do se pueda ejecutar en la máquina del cliente. En los siguientes capítulos explicaremos diferentes
soluciones.
La ventaja más importante de este modelo de descarga dinámica del software del cliente es que
los clientes no necesitan tener instalado todo el software previamente para poder comunicarse con los
servidores. En cambio, se puede introducir el software si es necesario, y de manera similar descar-
SECCIÓN 3.5 MIGRACIÓN DE CÓDIGO 105

2. El cliente y el servidor
se comunican
Cliente Servidor

Código específico 1. El cliente recupera


del lado del cliente el código

Depósito de código

Figura 3-17. El principio de la configuración dinámica de un cliente para co-


municarse con un servidor. El cliente primero recupera el software necesario,
y luego invoca al servidor.

tarlo cuando ya no se requiera. Otra ventaja es que mientras las interfaces sean estandarizadas,
podemos modificar el protocolo del cliente y su implementación con tanta frecuencia como desee-
mos. Los cambios no afectarán las aplicaciones existentes en la máquina del cliente y que se apoyan
en el servidor. Por supuesto, también hay desventajas. La más seria, que explicaremos en el capítu-
lo 9, tiene que ver con la seguridad. Confiar en que el código descargado se implemente sólo en la
interfaz anunciada mientras accede a su desprotegido disco duro, y no que envíe las partes más sig-
nificativas a quién sabe dónde no siempre es una buena idea.

Modelos para migración de código


Aunque la migración de código sugiere que el código solamente se traslada a través de las máqui-
nas, en realidad el término cubre un área mucho más completa. Tradicionalmente, en los sistemas
distribuidos la comunicación va enfocada al intercambio de datos entre procesos. La migración de
código desde el punto de vista de la difusión se basa en el movimiento de programas entre máqui-
nas, con la intención de que dichos programas se ejecuten en el destino. En algunos casos, como en
el proceso de migración, el estado de ejecución de un programa, señales pendientes, y otras partes
del entorno también se deben trasladar.
Para tener un mejor entendimiento de los diferentes modelos existentes para la migración de
código, utilizamos un marco de trabajo (framework) descrito en Fuggetta y colaboradores (1998).
En este marco de trabajo, un proceso consta de tres segmentos. El segmento de código es la parte
que contiene el conjunto de instrucciones constitutivas del programa en ejecución. El segmento de
recurso contiene referencias a recursos externos necesarios para el proceso, tales como archivos,
impresoras, dispositivos, otros procesos, entre otros factores. Finalmente, se usa un segmento de
ejecución para almacenar el estado actual de la ejecución de un proceso, el cual consta de datos pri-
vados, la pila, y por supuesto, el contador de programa.
106 CAPÍTULO 3 PROCESOS

El mínimo necesario para una migración de código es proporcionar solamente movilidad


débil. En este modelo, es posible transferir solamente el segmento de código, junto con quizás
algunos datos de inicialización. Una característica clásica de la movilidad débil es que un pro-
grama transferido siempre comienza desde uno de los diversos puntos de inicio predefinidos.
Por ejemplo, esto sucede con los applets de Java, los cuales siempre comienzan la ejecución desde
el principio. El beneficio de este método es su simplicidad. La movilidad débil requiere sola-
mente que una máquina de destino pueda ejecutar el código, y en esencia prepara al código para
que sea portable. Regresaremos a estos temas cuando expliquemos la migración en sistemas he-
terogéneos.
Al contrario de la movilidad débil, en sistemas que soportan la movilidad fuerte el segmento
de ejecución también se puede transferir. Esta característica clásica de la movilidad fuerte es que un
proceso se puede detener, y posteriormente trasladarse hacia otra máquina, y luego continuar su eje-
cución a partir del punto en donde se quedó. Claramente, la movilidad fuerte es más general que la
movilidad débil, pero también más difícil de implementar.
Sin importar si la movilidad es fuerte o débil, podemos hacer una distinción más profunda en-
tre migración iniciada por el remitente y migración iniciada por el destinatario. En la migración ini-
ciada por el remitente, por lo general, la migración empieza en la máquina donde reside el código
o donde se ejecuta. A menudo, la migración iniciada por el remitente se hace cuando los programas
se cargan al servidor de cómputo. Otro ejemplo, es el envío de un programa de búsqueda por internet
hacia un servidor web de base de datos para ejecutar las consultas en dicho servidor. En la migra-
ción iniciada por el destinatario, la máquina de destino toma la iniciativa para realizar la migración
de código. Los applets de Java son un ejemplo de este método.
La migración iniciada por el destinatario es más simple que la migración iniciada por el re-
mitente. En muchos casos, la migración de código ocurre entre un cliente y un servidor, donde el
cliente toma la iniciativa para realizar la migración. La carga segura del código hacia un servidor,
como lo hace la migración iniciada por el remitente, con frecuencia requiere que el cliente se en-
cuentre previamente registrado y autentificado en dicho servidor. En otras palabras, se requiere que
el servidor conozca a todos sus clientes, la razón para esto es que el cliente presumiblemente que-
rrá acceder a recursos de servidor tales como un disco. Proteger dichos recursos es esencial. Por el
contrario, la descarga de código como en el caso iniciado por el destinatario, a menudo se realiza
de manera anónima. Más aún, generalmente el servidor no está interesado en los recursos del cliente.
En lugar de eso, la migración de código hacia el cliente solamente se hace para mejorar el rendi-
miento del lado del cliente. En ese punto, sólo es necesario proteger un número limitado de recursos,
tales como la memoria y las conexiones de red. Regresaremos al código seguro más extensamente
en el capítulo 9.
En el caso de la movilidad débil, también hay diferencia si el código migrado se ejecuta me-
diante el proceso de destino o es iniciado como un proceso separado. Por ejemplo, los applets de
Java se descargan de manera sencilla mediante un navegador web y se ejecutan dentro del espacio
de direcciones del navegador. El beneficio de este método es que no hay necesidad de comenzar un
proceso por separado, ello evita la comunicación en la máquina de destino. La principal desventaja
es que el proceso de destino requiere estar protegido contra ejecuciones de código maliciosas o
inadvertidas. Una solución sencilla es dejar que el sistema operativo se haga cargo de eso mediante
la creación de un proceso separado para ejecutar el código migrado. Observe que esta solución no
SECCIÓN 3.5 MIGRACIÓN DE CÓDIGO 107

resuelve los problemas de acceso a recursos que mencionamos anteriormente. Aún tenemos que tra-
tar con ellos.
En lugar de trasladar un proceso en ejecución, también conocido como migración de procesos,
la movilidad fuerte puede ser soportada además por clonación remota. En contraste con la migración
de procesos, clonar significa producir una copia exacta del proceso original, pero ahora ejecutado
en una máquina diferente. El proceso de clonación se ejecuta en paralelo con el proceso original.
En sistemas UNIX, la clonación remota tiene lugar al bifurcar un proceso hijo y dejar que el hijo
continúe en una máquina diferente. El beneficio de la clonación es que el modelo se asemeja mucho
al modelo que ya utilizan muchas aplicaciones. La única diferencia es que el proceso de clonación
se ejecuta en una máquina diferente. En este sentido, la migración por clonación es una manera sen-
cilla de mejorar la transparencia de distribución.
En la figura 3-18 aparecen las distintas alternativas para implementar la migración de
código.

Ejecución en
Movilidad iniciada proceso de destino
por el remitente Ejecución en un
proceso separado
Movilidad débil
Ejecución en
Movilidad iniciada proceso de destino
por el destinatario Ejecución en un
proceso separado
Mecanismo de movilidad
Migración del proceso
Movilidad iniciada
por el remitente
Clonación del proceso
Movilidad fuerte
Migración del proceso
Movilidad iniciada
por el destinatario
Clonación del proceso

Figura 3-18. Alternativas para efectuar la migración de código.

3.5.2 Migración y recursos locales


Hasta aquí, solamente hemos tomado en cuenta la migración de código y los segmentos de ejecu-
ción. El segmento de recursos requiere atención especial. Con frecuencia, lo que vuelve tan difícil
la migración de código es que el segmento de recursos no siempre se puede transferir de manera
sencilla, junto con los otros segmentos, sin sufrir modificación alguna. Por ejemplo, supongamos
que un proceso mantiene una referencia a un puerto TCP específico a través del cual se comunica-
ba con otros procesos (remotos). Tal referencia se mantiene dentro de su segmento de recurso.
Cuando el proceso se traslada a otra ubicación, tendrá que entregarse el puerto y solicitarse uno
nuevo en el destino. En otros casos, transferir una referencia no tiene que ser un problema. Por

También podría gustarte