Extender el directorio de archivo a varios discos con MergerFS
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.
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:
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.