ZRAM: dispositivos virtuales de bloques en RAM

Publicado por Diego Córdoba en

Hoy hablaremos sobre la magia de zram como dispositivo de bloque virtual, y cómo puede utilizarse como dispositivos de propósito general.

Introducción

Este artículo tiene como intención aclarar dudas y explicar más en detalle el funcionamiento y uso de dispositivos zram en general, hablaremos sobre zram y sus posibilidades, y realizaremos algunas pruebas de concepto. En el siguiente post aprenderemos a utilizar zram para montar nuestro espacio de intercambio swap en RAM-.

¿Motivación?

Para complementar una charla que di para el FLISoL Online 2020 organizado por los amigos de la Comunidad Latina de Tecnologías Libres. Las charlas fueron de 30 minutos, y desarrollar este tema en ese tiempo es un poco complicado dado que mi intención era mostrar un poco más allá de la lista de comandos a ejecutar para el zram andando como swap. Salen dos artículos para cubrir estos temas!

Dispositivos de Bloques

Primero vamos a introducirnos (muy brevemente) en los dispositivos de bloques. Los dispositivos de bloques en Linux son básicamente dispositivos de almacenamiento que permiten la transferencia de bloques completos de información. Existen diferentes tipos de dispositivos en un sistema con kernel Linux, dispositivos de caracteres, de bloques, de red, etc.

Los dispositivos de bloques permiten que creemos un sistema de archivos dentro, como pueden ser ext4, reiserfs, xfs, etc, y dejarlos listos para montarlos en un punto de montaje (mountpoint).

En definitiva, si tenemos un sistema de archivos montado en un directorio o punto de montaje, todo lo que escribamos dentro de ese directorio se almacenará en el sistema de archivos asociado. Este sistema de archivos estará ligado a un dispositivo de bloques, por lo que el dato a su vez quedará almacenado en dicho dispositivo.

Los dispositivos de bloque podemos identificarlos rápidamente con un ls -l /dev. Los dispositivos de bloques comienzan con una b en la primer columna de la salida del ls -l.

bloques zram

Dispositivos de bloque virtuales

Ya hablamos en otra oportunidad sobre el sistema de archivos virtual y sus posibilidades. Aprendimos que no todos los archivos y directorios existen realmente almacenados en un disco, y que existen unidades de almacenamiento volátiles, como /proc o /var/run.

El controlador del sistema de archivos recibe los datos y los estructura de acuerdo a un ordenamiento particular, pero no repara en cómo se escriben esos bits en el soporte físico.

Los dispositivos de bloques virtuales tienen su back-end de almacenamiento por lo general en memoria volátil, como la RAM. Para el sistema operativo en alto nivel resulta totalmente transparente el back-end o el soporte físico o virtual sobre el que esté escrito un sistema de archivos.

Si bien la persistencia que brinda un dispositivo de bloques físico como una partición, no la posee uno virtual como un segmento de la RAM, existen aplicaciones como el uso de la swap o intercambio, que podrían beneficiarse de esta característica. Además, la velocidad de acceso al disco en RAM es muy superior a la de un disco físico, y como si fuera poco, su tamaño puede ser variable y adaptarse a las necesidades de cada uno.

Prueba de concepto de zram

Vamos a ensuciarnos las manos en el teclado!

Primero veamos si el módulo zram del núcleo se encuentra cargado:

lsmod | grep zram

Si la salida es similar a esto, es que el módulo está cargado y activo.

modprobe zram

En el caso de que el módulo no esté cargado, es decir, que el comando no muestre a zram en la salida, podremos cargarlo de esta forma (siempre con privilegios de superusuario):

modprobe zram

Con el módulo cargado podemos utilizar la utilidad zramctl para administrar de manera sencilla nuestros dispositivos de bloques comprimidos en RAM.

Supongamos que queremos crear un dispositivo ZRAM de 1024 MiB:

zramctl --find --size 1024M

Esto nos mostrará como salida el dispositivo creado. En mi caso, /dev/zram0. El modificador --find permite buscar un dispositivo libre (por defecto solo hay uno, pero pueden crearse varios). --size permite especificar el tamaño que le daremos al dispositivo virtual. Este tamaño es el espacio que tendrá el dispositivo virtual para almacenar contenido, no el espacio que ocupará en memoria.

Recordemos que los datos se almacenan comprimidos, por lo que un dispositivo zram de 1GiB permitirá almacenar hasta 1GiB de datos, pero ocupará un espacio en RAM que generalmente no superará la mitad de lo asignado.

Ahora podremos ver el nuevo dispositivo en la salida de zramctl. Puede agregarse el modificador -o o --output con una lista de argumentos para poder mostrar columnas particulares de los dispositivos (véase zramctl -h o zramctl --help)

zramctl

Por curiosidad, podríamos crear un nuevo dispositivo, esta vez de 2GiB, usando algo similar a esto:

zramctl --find --size 2G

Y la salida del comando sin argumentos cambiará a:

zramztl crear zram

Ahora tendremos el /dev/zram1 con 2GiB de almacenamiento disponible comprimido. Esto no quiere decir que estemos consumiendo desde este momento un 40% de 3GiB aproximado de nuestra RAM… el espacio se irá ocupando en la medida en que se comiencen a almacenar los datos. Nótese la columna «DATA» en el listado, que indica que en este momento no tiene contenido almacenado.

Si listamos los dispositivos de bloques, los veremos, como si fuesen discos. En la siguiente captura se ve la salida del comando ls -l /dev/zram* y de fdisk -l, donde se aprecian estos nuevos dispositivos.

zramctl mount zram

¿Funcionarán realmente como discos?

No se diga más:

mkfs -t ext4 /dev/zram0
mount -t ext4 /dev/zram0 /mnt

Sistema de archivos creado, y montado en /mnt. Creemos un archivo.

touch /mnt/hola.txt

Desmontemos, y montemos en otra ubicación, para que los más escépticos se queden tranquilos 😛

umount /mnt
mkdir /mnt/temporal
mount -t ext4 /dev/zram0 /mnt/temporal

Acá el resultado:

Claro está, el dispositivo es virtual, está en la RAM, y por más que ext4 sea un sistema de archivos persistente, y permita almacenar archivos en un dispositivo de bloques, si éste está en RAM, será volátil, y su contenido se eliminará al apagar el sistema.

Liberemos, finalmente, los dispositivos utilizados. Podemos eliminarlos usando el modificador -r en zramctl.

zramctl -r /dev/zram1
zramctl -r /dev/zram0

Con esos comandos habremos eliminado los dispositivos de bloques virtuales.

Probando al compresión de zram

Veamos un ejemplo de análisis del espacio consumido por el disco virtual.

Supongamos que creamos un disco virtual nuevo. Hagámoslo de 100MiB para notar más la diferencia de tamaños reales y comprimidos. Creemos el sistema de archivos ext4, y montemos la unidad en /mnt:

zramctl --find --size 100M
mkfs.ext4 /dev/zram0
mount -t ext4 /dev/zram0 /mnt

Ahora el directorio montado contendrá un subdirectorio, lost+found/, propio del sistema de archivos ext4.

Si verificamos el espacio ocupado ahora en el dispositivo, veremos una mínima cantidad de datos escritos, correspondientes al sistema de archivos:

En esta captura se ve toda la secuencia de comandos, y al final se puede apreciar que el tamaño del dispositivo creado es de 100MiB (DISKSIZE), con 48KiB de datos almacenados(DATA), que corresponden a 1.2 KiB de datos comprimidos (COMPR).

Creemos ahora un archivo de un tamaño específico, por ejemplo, 10MiB. Este archivo podría crearse con el comando dd sin problemas, pero esto generaría 10MiB de datos binarios, que tienen una tasa muy baja de compresión.

Por ello vamos a usar perl para crear un archivo de 10MiB de texto, altamente comprimible. Será un archivo relleno con letras ‘a’.

perl -e 'print "a" x 10485760' > /mnt/archivo.txt

Como se creé el archivo dentro del directorio punto de montaje de la unidad zram.

Podemos ahora comprobar el espacio consumido en el dispositivo con el comando zramctl, como se ve en esta captura:

En la última línea se puede ver que el dispositivo tiene un tamaño de 100MiB (DISKSIZE), de los cuales 10.1MiB (DATA) se encuentran ocupados por nuestro archivo e información del filesystem, que corresponden a 113.4 KiB de datos comprimidos(COMPR).

La columna TOTAL denota la cantidad total de memoria RAM consumida por el dispositivo, considerando su contenido comprimido, punteros de fragmentación y metadatos… podríamos resumir que, a este momento, nuestro archivo de 10MiB ocupa 228 KiB en memoria RAM, y en la medida en que almacenemos más información, se reducirá el porcentaje de overhead propio del dispositivo.

Para ampliar sobre zram …

Zram anteriormente se llamó compcache, de compressed cache, y solamente servía para crear un dispositivo de intercambio, o swap, dentro de la memoria RAM. Hoy zram permite utilizarse para eso (lo veremos en el siguiente artículo) o para cualquier otro propósito, como creación de discos virtuales para pruebas de desarrollo, sistemas, etc.

Basta decir que Google Chrome lo utiliza desde 2013, Android desde la versión 4.4, y Lubuntu desde la versión 13.10.

Soporta varios algoritmos de compresión, entre ellos, lz4, lzo, zstd, y por defecto usa lzo-rle, que ofrece un buen balance entre rendimiento y compresión.

Si bien zram requiere de tiempo de CPU para realizar la compresión, innecesaria si se tratase de un dispositivo de bloques real, este tiempo resulta ínfimo comparado con el tiempo de acceso a un dispositivo físico como un disco.

Si deseáramos, por alguna necesidad, que al cargar el módulo zram se generen dos o más dispositivos, en vez de uno, como es el caso predeterminado, puede especificarse agregando una línea en el archivo /etc/modprobe.d/zram.conf con el siguiente contenido:

options zram num_devices=2

¿Qué uso interesante se le puede dar a estos dispositivos?

Uno clásico y sumamente útil para mejorar algo el rendimiento de una computadora con memoria RAM escasa, es el de crear dispositivos virtuales zram y usarlos como espacio de intercambio.

La idea era comentarlo en este artículo, pero decidí dejarlo para la próxima entrada en el blog, ya que hay varios puntos a tener en cuenta y quiero detallarlo más 🙂

Espero les resulte interesante! Hasta la próxima!


¿Preguntas? ¿Comentarios?

Si tenés dudas, o querés dejarnos tus comentarios y consultas, sumate al grupo de Telegram de la comunidad JuncoTIC!
¡Te esperamos!

Categorías: Linux

Diego Córdoba

- Ingeniero en Informática - Mg. Teleinformática - Tesis pendiente - Docente universitario - Investigador