Trabajando con Btrfs – Compresión

Este artículo explorará la compresión transparente del sistema de archivos en Btrfs y cómo puede ayudar a ahorrar espacio de almacenamiento. Esto es parte de una serie que analiza más de cerca Btrfs, el sistema de archivos predeterminado para Fedora estación de trabajo, y Fedora Silverblue desde Fedora Linux 33.

En caso de que se lo haya perdido, aquí está el artículo anterior de esta serie: https://fedoramagazine.org/working-with-btrfs-snapshots

Introducción

La mayoría de nosotros probablemente ya nos hemos quedado sin espacio de almacenamiento. Tal vez desee descargar un archivo grande de Internet, o necesite copiar rápidamente algunas imágenes desde su teléfono, y la operación falla repentinamente. Si bien el espacio de almacenamiento es cada vez más barato, un número cada vez mayor de dispositivos se fabrican con una cantidad fija de almacenamiento o son difíciles de ampliar para los usuarios finales.

Pero, ¿qué puedes hacer cuando el espacio de almacenamiento es escaso? Tal vez recurras al almacenamiento en la nube, o encuentres algún medio de almacenamiento externo para llevar contigo.

En este artículo, investigaré otra solución a este problema: la compresión transparente del sistema de archivos, una función integrada en Btrfs. ¡Idealmente, esto resolverá sus problemas de almacenamiento y no requerirá casi ninguna modificación en su sistema! Veamos cómo.

Compresión transparente explicada

Primero, investiguemos qué significa la compresión transparente. Puede comprimir archivos con algoritmos de compresión como gzip, xz o bzip2. Esta suele ser una operación explícita: toma una utilidad de compresión y la deja operar en su archivo. Si bien esto proporciona ahorro de espacio, según el contenido del archivo, tiene un gran inconveniente: cuando desea acceder al archivo para leerlo o modificarlo, primero debe descomprimirlo.

Este no es solo un proceso tedioso, sino que también anula temporalmente el ahorro de espacio que había logrado anteriormente. Además, terminas (des)comprimiendo partes del archivo que no tenías la intención de tocar en primer lugar. ¡Claramente hay algo mejor que eso!

La compresión transparente, por otro lado, tiene lugar a nivel del sistema de archivos. Aquí, los archivos comprimidos aún se ven como archivos normales sin comprimir para el usuario. Sin embargo, se almacenan con compresión aplicada en el disco. Esto funciona porque el sistema de archivos descomprime selectivamente solo las partes de un archivo al que accede y se asegura de comprimirlas nuevamente a medida que escribe los cambios en el disco.

La compresión aquí es transparente en el sentido de que no es perceptible para el usuario, excepto posiblemente por un pequeño aumento en la carga de la CPU durante el acceso a los archivos. Por lo tanto, puede aplicar esto a los sistemas existentes sin realizar modificaciones de hardware ni recurrir al almacenamiento en la nube.

Comparación de algoritmos de compresión

Btrfs ofrece múltiples algoritmos de compresión para elegir. Por razones técnicas no puede utilizar programas de compresión arbitrarios. Actualmente es compatible con:

  • zstd
  • lzo
  • zlib

La buena noticia es que, debido a cómo funciona la compresión transparente, no tienes que instalar estos programas para que Btrfs los use. En los siguientes párrafos, verá cómo ejecutar un punto de referencia simple para comparar los algoritmos de compresión individuales. Sin embargo, para realizar el benchmark, debe instalar los ejecutables necesarios. No es necesario mantenerlos instalados después, por lo que utilizará un contenedor podman para asegurarse de no dejar ningún rastro en su sistema.

Debido a que escribir los mismos comandos una y otra vez es una tarea tediosa, he preparado un programa listo para ejecutar bash script que está alojado en Gitlab ( https://gitlab.com/hartang/btrfs-compression-test ). Esto ejecutará una sola compresión y descompresión con cada uno de los algoritmos mencionados anteriormente en diferentes niveles de compresión.

Primero, descargue el script:

                      $ curl -LO https://gitlab.com/hartang/btrfs-compression-test/-/raw/main/btrfs_compression_test.sh
                    

A continuación, haga girar un Fedora Contenedor de Linux que monta su directorio de trabajo actual para que pueda intercambiar archivos con el host y ejecutar el script allí:

                      $ podman run --rm -it --security-opt label=disable -v "$PWD:$PWD" 
    -w "$PWD" registry.fedoraproject.org/fedora:37
                    

Finalmente ejecute el script con:

                      $ chmod +x ./btrfs_compression_test.sh
$ ./btrfs_compression_test.sh
                    

La salida en mi máquina se ve así:

                      [INFO] Using file 'glibc-2.36.tar' as compression target
[INFO] Target file 'glibc-2.36.tar' not found, downloading now...
################################################################### 100.0%
[ OK ] Download successful!
[INFO] Copying 'glibc-2.36.tar' to '/tmp/tmp.vNBWYg1Vol/' for benchmark...
[INFO] Installing required utilities
[INFO] Testing compression for 'zlib'

 Level | Time (compress) | Compression Ratio | Time (decompress)
-------+-----------------+-------------------+-------------------
     1 |         0.322 s |          18.324 % |           0.659 s
     2 |         0.342 s |          17.738 % |           0.635 s
     3 |         0.473 s |          17.181 % |           0.647 s
     4 |         0.505 s |          16.101 % |           0.607 s
     5 |         0.640 s |          15.270 % |           0.590 s
     6 |         0.958 s |          14.858 % |           0.577 s
     7 |         1.198 s |          14.716 % |           0.561 s
     8 |         2.577 s |          14.619 % |           0.571 s
     9 |         3.114 s |          14.605 % |           0.570 s

[INFO] Testing compression for 'zstd'

 Level | Time (compress) | Compression Ratio | Time (decompress)
-------+-----------------+-------------------+-------------------
     1 |         0.492 s |          14.831 % |           0.313 s
     2 |         0.607 s |          14.008 % |           0.341 s
     3 |         0.709 s |          13.195 % |           0.318 s
     4 |         0.683 s |          13.108 % |           0.306 s
     5 |         1.300 s |          11.825 % |           0.292 s
     6 |         1.824 s |          11.298 % |           0.286 s
     7 |         2.215 s |          11.052 % |           0.284 s
     8 |         2.834 s |          10.619 % |           0.294 s
     9 |         3.079 s |          10.408 % |           0.272 s
    10 |         4.355 s |          10.254 % |           0.282 s
    11 |         6.161 s |          10.167 % |           0.283 s
    12 |         6.670 s |          10.165 % |           0.304 s
    13 |        12.471 s |          10.183 % |           0.279 s
    14 |        15.619 s |          10.075 % |           0.267 s
    15 |        21.387 s |           9.989 % |           0.270 s

[INFO] Testing compression for 'lzo'

 Level | Time (compress) | Compression Ratio | Time (decompress)
-------+-----------------+-------------------+-------------------
     1 |         0.447 s |          25.677 % |           0.438 s
     2 |         0.448 s |          25.582 % |           0.438 s
     3 |         0.444 s |          25.582 % |           0.441 s
     4 |         0.444 s |          25.582 % |           0.444 s
     5 |         0.445 s |          25.582 % |           0.453 s
     6 |         0.438 s |          25.582 % |           0.444 s
     7 |         8.990 s |          18.666 % |           0.410 s
     8 |        34.233 s |          18.463 % |           0.405 s
     9 |        41.328 s |          18.450 % |           0.426 s

[INFO] Cleaning up...
[ OK ] Benchmark complete!
                    

Es importante tener en cuenta algunas cosas antes de tomar decisiones basadas en los números del guión:

  • No todos los archivos se comprimen igual de bien. Los formatos multimedia modernos, como imágenes o películas, ya comprimen su contenido y no lo hacen mucho más.
  • El script realiza cada compresión y descompresión exactamente una vez. Ejecutarlo repetidamente en el mismo archivo de entrada generará salidas ligeramente diferentes. Por lo tanto, los tiempos deben entenderse como estimaciones, más que como una medida exacta.

Dados los números en mi salida, decidí usar el algoritmo de compresión zstd con el nivel de compresión 3 en mis sistemas. Dependiendo de sus necesidades, puede elegir niveles de compresión más altos (por example, si sus dispositivos de almacenamiento son comparativamente lentos). Para obtener una estimación de las velocidades de lectura/escritura alcanzables, puede dividir el tamaño de los archivos de origen (alrededor de 260 MB) por los tiempos de (des)compresión.

La prueba de compresión funciona en el código fuente GNU libc 2.36 de forma predeterminada. Si desea ver los resultados de un archivo personalizado, puede proporcionarle al script una ruta de archivo como primer argumento. Tenga en cuenta que el archivo debe ser accesible desde el interior del contenedor.

Siéntase libre de leer el código del script y modificarlo a su gusto si desea probar algunas otras cosas o realizar un punto de referencia más detallado.

Configuración de la compresión en Btrfs

La compresión transparente del sistema de archivos en Btrfs se puede configurar de varias maneras:

  • Como opción de montaje al montar el sistema de archivos (se aplica a todos los subvolúmenes del mismo sistema de archivos Btrfs)
  • Con propiedades de archivo Btrfs
  • Durante la desfragmentación del sistema de archivos btrfs (no permanente, no se muestra aquí)
  • Con la interfaz de atributos del archivo chattr (no se muestra aquí)

Solo echaré un vistazo a los dos primeros.

Habilitación de la compresión en el momento del montaje

Hay una opción de montaje Btrfs que permite la compresión de archivos:

                      $ sudo mount -o compress=<ALGORITHM>:<LEVEL> ...
                    

Para examplepara montar un sistema de archivos y comprimirlo con el algoritmo zstd en el nivel 3, escribiría:

                      $ sudo mount -o compress=zstd:3 ...
                    

La configuración del nivel de compresión es opcional. Es importante tener en cuenta que la opción de montaje comprimido se aplica a todo el sistema de archivos Btrfs y todos sus subvolúmenes. Además, es la única forma admitida actualmente de especificar el nivel de compresión a utilizar.

Para aplicar compresión al sistema de archivos raíz, debe especificarse en /etc/fstab. El Fedora Instalador de Linux, para examplehabilita la compresión zstd en el nivel 1 de forma predeterminada, que se ve así en /etc/fstab:

                      $ cat /etc/fstab
[ ... ]
UUID=47b03671-39f1-43a7-b0a7-db733bfb47ff  /  btrfs   subvol=root,compress=zstd:1,[ ... ] 0 0
                    

Habilitación de la compresión por archivo

Otra forma de especificar compresiones es a través de las propiedades del sistema de archivos Btrfs. Para leer la configuración de compresión de cualquier archivo, carpeta o subvolumen, use el siguiente comando:

                      $ btrfs property get <PATH> compression
                    

Asimismo, puedes configurar la compresión así:

                      $ sudo btrfs property set <PATH> compression <VALUE>
                    

Para examplepara habilitar la compresión zlib para todos los archivos en /etc:

                      $ sudo btrfs property set /etc compression zlib
                    

Puede obtener una lista de valores admitidos con man btrfs-property. Tenga en cuenta que esta interfaz no permite especificar el nivel de compresión. Además, si se establece una propiedad de compresión, anula otra compresión configurada en el momento del montaje.

Comprimir archivos existentes

En este punto, si aplica compresión a su sistema de archivos existente y verifica el uso del espacio con df o comandos similares, notará que nada ha cambiado. Esto se debe a que Btrfs, por sí mismo, no “recomprime” todos sus archivos existentes. La compresión solo tendrá lugar cuando se escriban nuevos datos en el disco. Hay algunas formas de realizar una recompresión explícita:

  1. Espere y no haga nada: a medida que los archivos se modifican y se vuelven a escribir en el disco, Btrfs comprime el contenido del archivo recién escrito según lo configurado. En algún momento, si esperamos lo suficiente, una parte cada vez mayor de nuestros archivos se reescriben y, por lo tanto, se comprimen.
  2. Mueva los archivos a un sistema de archivos diferente y viceversa: dependiendo de los archivos a los que desee aplicar la compresión, esto puede convertirse en una operación bastante tediosa.
  3. Realizar una desfragmentación Btrfs

La última opción es probablemente la más conveniente, pero viene con una advertencia en los sistemas de archivos Btrfs que ya contienen instantáneas: romperá la extensión compartida entre las instantáneas. En otras palabras, todo el contenido compartido entre dos instantáneas, o una instantánea y su subvolumen principal, estará presente varias veces después de una operación de desfragmentación.

Por lo tanto, si ya tiene muchas instantáneas en su sistema de archivos, no debe ejecutar una desfragmentación en todo el sistema de archivos. Esto tampoco es necesario, ya que con Btrfs puedes desfragmentar directorios específicos o incluso archivos individuales, si así lo deseas.

Puede usar el siguiente comando para realizar una desfragmentación:

                      $ sudo btrfs filesystem defragment -r /path/to/defragment
                    

Para examplepuede desfragmentar su directorio de inicio de esta manera:

                      $ sudo btrfs filesystem defragment -r "$HOME"
                    

En caso de duda, es una buena idea comenzar con la desfragmentación de archivos grandes individuales y continuar con directorios cada vez más grandes mientras se monitorea el espacio libre en el sistema de archivos.

Medición de la compresión del sistema de archivos

En algún momento, puede preguntarse cuánto espacio ha ahorrado gracias a la compresión del sistema de archivos. ¿Pero cómo lo dices? Primero, para saber si un sistema de archivos Btrfs está montado con compresión aplicada, puede usar el siguiente comando:

                      $ findmnt -vno OPTIONS /path/to/mountpoint | grep compress
                    

Si obtiene un resultado, ¡el sistema de archivos en el punto de montaje dado está usando compresión! A continuación, el comando compsize puede decirle cuánto espacio necesitan sus archivos:

                      $ sudo compsize -x /path/to/examine
                    

En mi directorio de inicio, el resultado se ve así:

                      $ sudo compsize -x "$HOME"
Processed 942853 files, 550658 regular extents (799985 refs), 462779 inline.
Type       Perc     Disk Usage   Uncompressed Referenced
TOTAL       81%       74G          91G         111G
none       100%       67G          67G          77G
zstd        28%      6.6G          23G          33G
                    

Las líneas individuales le indican el “Tipo” de compresión aplicada a los archivos. El “TOTAL” es la suma de todas las líneas debajo de él. Las columnas, por otro lado, te dicen cuánto espacio necesitan nuestros archivos:

  • “Uso del disco” es la cantidad real de almacenamiento asignado en el disco duro,
  • “Sin comprimir” es la cantidad de almacenamiento que necesitarían los archivos sin aplicar la compresión,
  • “Referenciado” es el tamaño total de todos los archivos sin comprimir sumados.

“Referenciado” puede diferir de los números en “Sin comprimir” si, por example, uno ha deduplicado archivos previamente, o si hay instantáneas que comparten extensiones. En el example arriba, puede ver que 91 GB de archivos sin comprimir ocupan solo 74 GB de almacenamiento en mi disco. Según el tipo de archivos almacenados en un directorio y el nivel de compresión aplicado, estos números pueden variar significativamente.

Notas adicionales sobre la compresión de archivos

Btrfs utiliza un algoritmo heurístico para detectar archivos comprimidos. Esto se hace porque los archivos comprimidos generalmente no se comprimen bien, por lo que no tiene sentido desperdiciar ciclos de CPU intentando comprimir más. Con este fin, Btrfs mide la relación de compresión al comprimir datos antes de escribirlos en el disco. Si las primeras partes de un archivo se comprimen mal, el archivo se marca como incompresible y no se realiza más compresión.

Si, por alguna razón, desea que Btrfs comprima todos los datos que escribe, puede montar un sistema de archivos Btrfs con la opción de fuerza de compresión, así:

                      $ sudo mount -o compress-force=zstd:3 ...
                    

Cuando se configura así, Btrfs comprimirá todos los datos que escriba en el disco con el algoritmo zstd en el nivel de compresión 3.

Una cosa importante a tener en cuenta es que un sistema de archivos Btrfs con una gran cantidad de datos y la compresión habilitada puede tardar unos segundos más en montarse que sin la compresión aplicada. Esto tiene razones técnicas y es un comportamiento normal que no influye en el funcionamiento del sistema de archivos.

Conclusión

Este artículo detalla la compresión transparente del sistema de archivos en Btrfs. Es una forma integrada, comparativamente económica, de obtener algo de espacio de almacenamiento adicional del hardware existente sin necesidad de modificaciones.

Los próximos artículos de esta serie tratarán sobre:

  • Qgroups: limitar el tamaño de su sistema de archivos
  • RAID: reemplace su configuración de mdadm

Si hay otros temas relacionados con Btrfs sobre los que desea obtener más información, eche un vistazo a Btrfs Wiki [1] y documentos [2] . ¡No olvide consultar los primeros tres artículos de esta serie, si aún no lo ha hecho! Si cree que falta algo en esta serie de artículos, hágamelo saber en los comentarios a continuación. ¡Nos vemos en el próximo artículo!

Fuentes

[1]: https://btrfs.wiki.kernel.org/index.php/Main_Page
[2]: https://btrfs.readthedocs.io/en/latest/Introducción.html

Related Posts