Saltar al contenido principal

Extender el directorio de archivo a varios discos con MergerFS

Use MergerFS solo si no puede planificar con antelación una matriz de discos

Recomendamos planificar con antelación el espacio destinado al archivo y, para grandes volúmenes de datos, usar tecnologías dedicadas como ZFS, que permiten equilibrar los datos de manera uniforme entre discos, cuentan con un sistema de tolerancia a fallos y pueden ampliar sin problemas matrices de datos a decenas de discos y cientos de terabytes de datos.

El problema

Puso en marcha Yucca con una configuración básica con el archivo en el disco del sistema; con el tiempo, la cantidad de cámaras y de archivo creció y el disco actual ya no es suficiente. Se pueden agregar uno o varios discos más al sistema y distribuir de manera uniforme el almacenamiento del archivo entre ellos; esto requeriría detener Yucca, crear una matriz de discos y migrar todos los datos. En este caso el servicio podría no estar disponible durante varias horas, lo cual es inaceptable.

La solución

Si desea ampliar gradualmente el directorio destinado al almacenamiento del archivo agregando discos adicionales, pero sin usar tecnologías RAID como ZFS o mdadm, y sin reconstruir toda la infraestructura, puede usar sistemas de archivos unificados: Union filesystem.

Existen varias soluciones en este segmento, pero nos centraremos en mergerfs y, de aquí en adelante, todo se explicará en su contexto. Una comparación de mergerfs con otras soluciones está disponible aquí.

mergerfs es un sistema de archivos unificado diseñado para simplificar el almacenamiento y la gestión de archivos en numerosos dispositivos de almacenamiento comunes; es similar a mhddfs, UnionFS y Aufs. Puede encontrar más detalles en el repositorio oficial del proyecto: https://github.com/trapexit/mergerfs.

mergerfs, dicho de forma sencilla, crea un directorio virtual bajo el cual puede haber varios directorios reales en distintos discos con distintos sistemas de archivos, como ext4 o XFS. mergerfs no divide los archivos en partes; se almacenan completos, con todos sus metadatos, en uno de los subdirectorios:

A + B = C
/disk1 /disk2 /merged
| | |
+-- /dir1 +-- /dir1 +-- /dir1
| | | | | |
| +-- file1 | +-- file2 | +-- file1
| | +-- file3 | +-- file2
+-- /dir2 | | +-- file3
| | +-- /dir3 |
| +-- file4 | +-- /dir2
| +-- file5 | |
+-- file6 | +-- file4
|
+-- /dir3
| |
| +-- file5
|
+-- file6

Ventajas

  • Fácil de ampliar el espacio agregando nuevos discos;
  • Fácil de configurar: mergerfs es un sistema de archivos en espacio de usuario, por lo que puede instalarlo como un programa más en cualquier Linux;
  • No hay requisitos especiales para los directorios que se combinan; pueden ser discos con distinta capacidad, sistemas de archivos, o incluso carpetas de red;
  • No requiere reconstruir toda la infraestructura.

Desventajas

  • No hay balanceo de carga: la carga en unos discos puede ser mayor que en otros, y como resultado el archivo de algunas cámaras puede servirse más lento que el de otras;
  • No hay redundancia: el fallo de un disco provocará la pérdida total de los datos.

Instalación

Las instrucciones de instalación están en el repositorio.

Nota

Si el gestor de paquetes de su distribución incluye mergerfs, verifique si su versión está actualizada. Si la versión está desactualizada, se recomienda usar la última versión disponible en la página. Los detalles para las distribuciones más comunes se muestran a continuación.

Los pasos descritos a continuación se realizaron en Ubuntu 22.04; mergerfs se instaló mediante el paquete deb del repositorio.

Para openSUSE existe un repositorio en OBS con las versiones más recientes.

Configuración

En el ejemplo, una máquina virtual con un disco de 20 gigabytes y dos discos adicionales de 10 gigabytes:

# df -h | grep -v -E "(tmpfs|overlay)"
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 19G 4.5G 14G 26% /
/dev/sda15 253M 142K 252M 1% /boot/efi
/dev/sdb 9.8G 28K 9.3G 1% /mnt/HC_Volume_100511911
/dev/sdc 9.8G 28K 9.3G 1% /mnt/HC_Volume_100511912
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sda 8:0 0 19.1G 0 disk
├─sda1 8:1 0 18.8G 0 part /
├─sda14 8:14 0 1M 0 part
└─sda15 8:15 0 256M 0 part /boot/efi
sdb 8:16 0 10G 0 disk /mnt/HC_Volume_100511911
sdc 8:32 0 10G 0 disk /mnt/HC_Volume_100511912

En el servidor está en ejecución Yucca, con 6 cámaras y su archivo agregados:

cat /opt/yucca/yucca.toml | grep "alloc_dir ="
alloc_dir = "/opt/yucca/data/alloc"

Los datos se están escribiendo correctamente en el archivo:

# tree /opt/yucca/data/alloc/ | head
/opt/yucca/data/alloc/
├── 2
│ ├── archive
│ │ └── 2024
│ │ └── 03
│ │ └── 27
│ │ ├── 15.dvr
│ │ └── 15.ranges
│ ├── logs
│ │ └── ffmpeg.log
│ └── segment
...

Ahora, dentro de los puntos de montaje de nuestros discos adicionales, creemos un directorio que montaremos y asignémosle los permisos para que Yucca pueda escribir en él:

mkdir -p /mnt/HC_Volume_100511911/yucca
mkdir -p /mnt/HC_Volume_100511912/yucca
chown yucca:yucca /mnt/HC_Volume_100511911/yucca
chown yucca:yucca /mnt/HC_Volume_100511912/yucca

Creamos el directorio en el que realizaremos el montaje:

mkdir -p /mnt/yucca_mergerfs

Montamos el volumen unificado:

mergerfs -o fsname=mergerfs,cache.files=partial,dropcacheonclose=true,category.create=mfs,moveonenospc=true,minfreespace=20G /mnt/HC_Volume_100511911/yucca:/mnt/HC_Volume_100511912/yucca:/opt/yucca/data/alloc /mnt/yucca_mergerfs

Puede leer sobre el significado de todos los parámetros en la documentación oficial. Comprobamos que el volumen esté montado:

Tenga en cuenta

El volumen resultante tiene un tamaño igual a la suma de todos los volúmenes combinados.

# df -h | grep -v -E "(tmpfs|overlay)"
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 19G 5.2G 13G 30% /
/dev/sda15 253M 142K 252M 1% /boot/efi
/dev/sdb 9.8G 28K 9.3G 1% /mnt/HC_Volume_100511911
/dev/sdc 9.8G 28K 9.3G 1% /mnt/HC_Volume_100511912
mnt/HC_Volume_100511911/yucca:mnt/HC_Volume_100511912/yucca:opt/yucca/data/alloc 38G 5.2G 31G 15% /mnt/yucca_mergerfs

Comprobamos que los directorios /mnt/yucca_mergerfs y /opt/yucca/data/alloc tengan el mismo conjunto de archivos:

ls /mnt/yucca_mergerfs/
2 3 4 5 6 8

ls /opt/yucca/data/alloc/
2 3 4 5 6 8

Ahora, con cualquier editor de texto, cambiamos el parámetro alloc_dir:

# sed -i 's|/opt/yucca/data/alloc|/mnt/yucca_mergerfs|' /opt/yucca/yucca.toml
# cat /opt/yucca/yucca.toml | grep "alloc_dir ="
alloc_dir = "/mnt/yucca_mergerfs"

Reiniciamos el servidor Yucca y comprobamos que todo esté en orden:

systemctl restart yucca
systemctl status yucca

Yucca escribe segmentos en bloques de una hora, así que en los nuevos discos /mnt/HC_Volume_100511911/yucca y /mnt/HC_Volume_100511912/yucca los datos deberían aparecer solo al comenzar la nueva hora.

root@ubuntu-2gb-fsn1-1:~# tree /mnt/HC_Volume_100511911/yucca/ | head
/mnt/HC_Volume_100511911/yucca/
├── 2
│ ├── archive
│ └── logs
│ └── ffmpeg.log
├── 3
│ ├── archive
│ │ └── 2024
│ │ └── 03
│ │ └── 27
root@ubuntu-2gb-fsn1-1:~# tree /mnt/HC_Volume_100511912/yucca/ | head
/mnt/HC_Volume_100511912/yucca/
├── 2
│ ├── archive
│ │ └── 2024
│ │ └── 03
│ │ └── 27
│ │ ├── 16.dvr
│ │ └── 16.ranges
│ ├── logs
│ └── segment

Para que el directorio unificado se monte al reiniciar el sistema, agregamos una entrada en /etc/fstab:

# yucca mergerfs
/mnt/HC_Volume_100511911/yucca:/mnt/HC_Volume_100511912/yucca:/opt/yucca/data/alloc /mnt/yucca_mergerfs mergerfs cache.files=partial,dropcacheonclose=true,category.create=mfs,moveonenospc=true,minfreespace=20G 0 0

Comprobamos que no haya errores:

mount -a

Reiniciamos el sistema para verificar.

Conclusión

No hemos probado mergerfs bajo cargas elevadas ni en otras situaciones excepcionales, pero podemos decir que, en general, todo funciona de manera estable y no se observan problemas. Si de todos modos surgen problemas, diríjase al tracker del proyecto, donde también puede apoyar económicamente a los desarrolladores.