Tecnología COW aplicada a la memoria principal

Como siempre ocurre cuando hay una actualización del núcleo de Linux, uno comprueba cuales son las mejoras que este aporta respecto a su última versión para realizar un estudio de riesgos que implicaría la actualización a dicha versión y si realmente vale la pena. Por ello hace unas semanas me encontraba leyendo la información acerca del nuevo núcleo (2.6.32) y leí un apartado enfocado a la virtualización. En él, los chicos de Red Hat habían aplicado un concepto que normalmente se emplea en los sistema de ficheros, pero esta vez aplicando la idea a la memoria principal; se trata del COW o copia en escritura (Copy On Write).

Para explicar la nueva mejora vamos a exponer primero el funcionamiento de la tecnología COW aplicada en los sistemas de ficheros de entornos virtuales. COW emplea ficheros Sparse: ficheros distribuidos en bloques, donde existe un índice que indica qué bloques están ocupados. Por ello, podemos crear ficheros de un determinado tamaño, y sólo ocupará espacio realmente el tamaño de aquellos bloques que tengan información valida. Por ejemplo, antes si yo quería crear un fichero vacío de 1GB, el fichero se creaba pero ocupaba 1GB aunque no contuviese ningún tipo de información. Con los ficheros sparse puedes crear un fichero vacío de 1GB y éste ocupara sólo 4Kbyte.

Y dirán, ¿pero cómo puedo emplear esto en la virtualización? Pues muy sencillo. Imagínense que tienen un entorno con 20 máquinas virtuales en las que la única diferencia entre cada máquina virtual son un par de binarios o ficheros de configuración; por ejemplo, varios servidores Linux Debian. Con la tecnología COW usted puede tener un único fichero de tamaño X para todas las máquinas virtuales y un fichero COW para cada máquina virtual. Los ficheros que se modifiquen en la máquina virtual se escribirán única y exclusivamente en el bloque modificado del fichero COW de la máquina por lo que, si la distribución ocupa 1GB, en vez de necesitar 20GB (1GB x 20 máquinas virtuales) necesitará 1GB más lo que ocupe cada COW, que serían de media entre 10 y 50MB. Es decir, que con menos de 2GB es posible tener 20 máquinas virtuales totalmente independientes en vez de necesitar 20GB.

A su vez, se habrán dado cuenta que es la tecnología que emplean la mayoría de productos de virtualización para hacer una captura del estado actual de una máquina virtual, ya que lo que hacen es guardar el estado actual y todas las modificaciones posteriores se realizan sobre un fichero COW en lugar de sobre la imagen, por lo que para volver a un estado anterior, únicamente requerirá eliminar el fichero COW.

Además, esto presenta una mejora de rendimiento, puesto que es muy probable que una máquina solicite al sistema de ficheros un dato que previamente haya sido ya solicitado por otra máquina virtual y se encuentre ya en la memoria principal, por lo que no será necesario tener que cargarlo de disco a memoria, obteniendo un aumento considerable de la velocidad. Incluso se permite el lujo de poder cargar mediante tmpfs la imagen de la distribución totalmente en memoria principal puesto que no es lo mismo tener cargado 20GB en memoria principal que 2GB, ¿verdad?

El problema de esta tecnología es cuando se emplean máquinas distintas puesto que al final hay más bloques modificados en el fichero COW que en la imagen centralizada. A su vez, no todas las tecnologías de virtualización soportan este tipo de ficheros por lo que hacen que no se explote toda la capacidad de la tecnología COW.

Entonces, han pensado los chicos de Red Hat… ¿Por qué no aplicamos directamente el principio de la tecnología COW a la memoria principal? Si un dato que fue solicitado anteriormente por una máquina virtual se encuentra ya en memoria, cuando otra máquina virtual solicite ese mismo dato ¿que lógica tendría solicitar el dato al fichero en disco, tardando más y ocupando en la memoria datos replicados? Para ello, lo que se hace es revisar la memoria en busca de datos replicados, eliminando el dato replicado y suministrando a las máquinas virtuales los datos de la única copia que hay en memoria principal. De esta forma se consigue incrementar el rendimiento, puesto que se solicitan menos datos al sistema de ficheros, mucho más lento que la memoria, y se consigue un ahorro de memoria principal muy grande, por lo que con una misma cantidad de memoria principal se podrá virtualizar un número mayor de máquinas.

A la aplicación de los principios de la tecnología COW en memoria se conoce como deduplicación de memoria. En el caso del kernel Linux usa el hilo KSMd (Kernel Samepage Merging) para revisar la memoria en busca de áreas idénticas, eliminando las copias y conservando solo una de éstas. La prueba de concepto fue realizada sobre un servidor de virtualización con 16GB de memoria principal donde se hizo funcionar hasta 52 máquinas virtuales Windows XP concediendo 1GB de memoria principal a cada máquina virtual.

¿Les ha quedado alguna duda?

Comments

  1. Entremezclar la memoria de diferentes máquinas virtuales así… me pone un poco los pelos de punta. Supongo que los de RedHat lo habrán resuelto bien, pero de todas maneras podías poner en enlace para pegarle un vistazo. No me fio mucho, tanta virtualización, tanto “todo separado”, pero a la vez junto y entremezclado… llamame paranoico :P

    ¿Algún enlace con la info original/fuentes?

  2. que interesante articulo, los felicito.

    pda: esto de la memoria cow esta bien interesante para investigar un poco mas

  3. http://Olopez says

    Hola Ximo , Jose me ha quitado de la boca parte de lo que iba a decir, ya que esto de mezclar memorias nunca y ademas de distintas VMs nunca ha sido bueno para nadie y al final suele traer malas consecuencias, aunque tambien supongo que antes de jugarsela habran tenido bastante encuenta las implicaciones de seguridad.

    Otra cosa que veo leyendo sobre KSM es lo siguiente:

    KSM is a linux driver that allows dynamicly sharing identical memory pages
    between one or more processes.

    unlike tradtional page sharing that is made at the allocation of the
    memory, ksm do it dynamicly after the memory was created.
    Memory is periodically scanned; identical pages are identified and merged.

    Identical pages … es decir solo en entornos donde las vms sean y trabajen de manera muy muy similar esta tecnica puede realmente ayudar a reducir espacio en memoria fisica, por que si cada uno escribe en memoria cosas distintas las paginas identicas no debe darse muchas veces.

    Otro tema son tecnologias como ASLR ¿no impide que las paginas en diferentes vms sean identicas al estar los bloques de memoria posicionados en sitios distintos?

    Tambien esta el tema de la CPU, el scaneo y comparacion periodica de bloques de memoria no debe tener un coste muy bajo … pero claro con las CPUs de hoy en dia … esto ya no se mira tanto.

    Me parece que como concepto teorico esta bien , pero en practica no se si tendra tantos beneficios como parece a simple vista, aun asi habra que estudiarlo.

    Un saludo.

  4. Gracias por vuestras contestaciones.

    Jose la información puedes encontrar en la documentación del kernel apartado del KSM. Te aconsejo la lista del kernel que es donde más información podrás encontrar.

    Respecto a la viabilidad o no del proyecto, en la prueba de concepto que se realizó fue correcta, lógicamente no hubo una auditoría de seguridad al respecto por lo que las implicaciones de seguridad que pueda tener se desconocen.

    Respecto al comentario de Olopez, lógicamente esto solo es aplicable cuando las máquinas virtuales empleen sistemas operativos y aplicaciones comunes por que sino es imposible que una página de la memoria cargada por una máquina virtual A sea idéntica a otra página cargada por otra máquina virtual B.

    El ASLR yo no lo veo ningún problema, si analizamos como funciona la virtualización realmente las máquinas virtuales ven su memoria principal como si de una física se tratara, pero realmente, ¿como se guardan esos datos en lamemoria principal del host/anfitrión?.

    La mayoría de tecnologías de virtualización permiten conceder una cantidad de RAM a una máquina virtual de la cual podemos indicar que nos asegure una cierta cantidad de esa RAM, es decir, que el host le reserve a esa máquina virtual una cantidad de memoria ram física. A si mismo se puede conceder más memoria RAM en suma a todas las máquinas virtuales que las disponibles físicamente.

    Yo puedo comentaros en el caso de la gestión de la memoria de las máquinas virtuales (mv) en User Mode Linux puesto que es la tecnología que he programado y con la que más me he pegado.

    Imaginaros que yo tengo una máquina física con 512mb de RAM. El crea un fichero sparse de tamaño idéntico al tamaño de la memoria concedida a esa mv, por tanto si yo creo 5 mv de 1GB de ram, realmente me crea 5 ficheros sparse de 1GB. Lo que hará el host será emplear esos 512mb fisicos de ram a todas las máquinas virtuales y mientras no se empleen los 512mb de ram no empleara los ficheros sparse, cuando se superen esos 512mb de ram entonces usara los ficheros sparse como memoria de intercambio, tipo swap.De esta forma puedo asignar más ram a una mv de la que realmente dispongo en el host. Así como asignar una cantidad superior de memoria ram en el total de toda las memoria asignada a las mv de la que realmente dispongo, por ejemplo en el caso de que en el equipo físico anterior yo podría crear 10 máquinas virtuales con 100mb de ram por máquina.

    ¿Y que quiero decir con todo esto? pues que físicamente en el host la ejecución de procesos de las mv ya se ejecutan cada vez en distintas posiciones de memoria puesto que el host empleara el espacio de memoria ram que tenga libre o descartara las posiciones de memoria que más tiempo hace que no se visitan o menos frecuentemente usadas para cargar en esa posición liberada la página que necesita.

    Lo único que hace el host es revisar páginas idénticas, cuando las encuentra elimina una copia y le indica a la memoria ram virtualizada de dicha mv que esa página ahora esta cargada en otra posición de la memoria ram física. Si una mv es comprometida, los datos que se modifiquen y se carguen en memória ram, cuando se comprueben respecto a los que ya hay en memoria se verá que no son iguales, por lo que no implicaría ningún riesgo de seguridad para el resto de mv.

    No se si me he explicado correctamente :\

  5. http://Olopez says

    Esta claro , pero a dia de hoy, solo le veo utilidad a esta tecnica en entornos muy concretos, donde el ahorro de ram sera significativo y por norma general parece ser (sin estudiarlo a fondo) que simplemente es un proceso que estara consumiendo recursos inecesariamente en la maquina host.
    Tambien he visto algun link con problemas “legales” de esta tecnica con patetendes de vmware, que a la hora de poner esto a trabajar en produccion no molan mucho.
    De todas formas esto creo que es mas una prueba de concepto que algo que se pueda usar dia a dia, lo que no quiere decir que no sea interesante y algo que tengamos que conocer.