Expansão do diretório de arquivo para vários discos com o MergerFS
Recomendamos planejar o espaço para o arquivo com antecedência e, para grandes volumes de dados, usar tecnologias especializadas, como o ZFS, que permitem balancear os dados uniformemente entre os discos, possuem um sistema de tolerância a falhas e podem expandir arrays de dados sem problemas para dezenas de discos e centenas de terabytes de dados.
Problema
Você iniciou o Yucca em uma configuração básica com o arquivo no mesmo disco do sistema, com o tempo o número de câmeras e o volume de arquivo aumentaram e o disco atual já não é suficiente. É possível adicionar mais um ou vários discos ao sistema e distribuir uniformemente o armazenamento do arquivo entre eles – isso exigiria parar o Yucca, criar um array de discos e migrar todos os dados. Nesse caso, o serviço pode ficar indisponível por várias horas, o que é inaceitável.
Solução
Caso você queira expandir gradualmente o diretório de armazenamento do arquivo adicionando discos adicionais, mas sem usar tecnologias RAID, como ZFS ou mdadm, e sem reconstruir toda a infraestrutura, você pode usar sistemas de arquivos unificados – Union filesystem.
Existem várias soluções nesse segmento, mas vamos nos concentrar no mergerfs e, a partir daqui, tudo será no contexto dele. Uma comparação do mergerfs com outras soluções está disponível aqui.
mergerfs é um sistema de arquivos unificado, projetado para simplificar o armazenamento e o gerenciamento de arquivos em vários dispositivos de armazenamento comuns, é semelhante ao mhddfs, UnionFS e Aufs. Mais detalhes podem ser encontrados no repositório oficial do projeto - https://github.com/trapexit/mergerfs.
Em termos gerais, o mergerfs cria um diretório virtual, sob o qual podem existir vários diretórios reais em discos diferentes com sistemas de arquivos diferentes, como ext4 ou XFS. O mergerfs não divide os arquivos em partes, eles são armazenados por completo, com todos os metadados, em um dos subdiretórios:
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
Vantagens
- Fácil de expandir o espaço adicionando novos discos;
- Fácil de configurar, o mergerfs é um sistema de arquivos em espaço de usuário, então você pode instalá-lo como um programa em qualquer Linux;
- Não há requisitos especiais para os diretórios unidos, podem ser discos com volumes diferentes, sistemas de arquivos diferentes ou até mesmo pastas de rede;
- Não exige a reconstrução de toda a infraestrutura.
Desvantagens
- Não há balanceamento de carga – a carga em alguns discos pode ser maior do que em outros, como resultado, o arquivo de algumas câmeras pode ser entregue mais lentamente que o de outras;
- Não há redundância, a falha de um disco causará perda total de dados.
Instalação
As instruções de instalação estão disponíveis no repositório.
Se o gerenciador de pacotes da sua distribuição inclui o mergerfs, verifique se a versão é atual. Se a versão estiver desatualizada, recomenda-se usar a versão mais recente, disponível na página. Detalhes para as distribuições mais comuns estão descritos abaixo.
As ações descritas abaixo foram realizadas no Ubuntu 22.04, o mergerfs foi instalado por meio de um pacote deb do repositório.
Para o openSUSE há um repositório no OBS com as versões mais recentes.
Configuração
No exemplo, uma máquina virtual com um disco de 20 gigabytes e dois discos adicionais 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
# lsblk
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
O servidor está executando o Yucca, com 6 câmeras adicionadas com arquivo:
cat /opt/yucca/yucca.toml | grep "alloc_dir ="
alloc_dir = "/opt/yucca/data/alloc"
Os dados estão sendo gravados no arquivo com sucesso:
# tree /opt/yucca/data/alloc/ | head
/opt/yucca/data/alloc/
├── 2
│ ├── archive
│ │ └── 2024
│ │ └── 03
│ │ └── 27
│ │ ├── 15.dvr
│ │ └── 15.ranges
│ ├── logs
│ │ └── ffmpeg.log
│ └── segment
...
Agora, dentro dos pontos de montagem dos nossos discos adicionais, vamos criar um diretório que será montado e atribuir as permissões para que o Yucca possa escrever nele:
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
Criamos o diretório no qual faremos a montagem:
mkdir -p /mnt/yucca_mergerfs
Montamos o volume 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
O significado de todos os parâmetros pode ser consultado na documentação oficial. Vamos verificar se o volume foi montado:
O volume final tem um tamanho igual à soma de todos os volumes unificados.
# 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
Vamos verificar se os diretórios /mnt/yucca_mergerfs e /opt/yucca/data/alloc têm o mesmo conjunto de arquivos:
ls /mnt/yucca_mergerfs/
2 3 4 5 6 8
ls /opt/yucca/data/alloc/
2 3 4 5 6 8
Agora, usando qualquer editor de texto, alteramos o 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 o servidor Yucca e verificamos se está tudo certo:
systemctl restart yucca
systemctl status yucca
O Yucca grava os segmentos em blocos de uma hora, então nos novos discos /mnt/HC_Volume_100511911/yucca e /mnt/HC_Volume_100511912/yucca os dados só devem aparecer a partir do início da próxima 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 o diretório unificado seja montado na reinicialização do sistema, adicionamos uma entrada em /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
Verificamos que não há erros:
mount -a
Reiniciamos o sistema para verificar.
Conclusão
Não testamos o mergerfs sob cargas elevadas ou em outras situações excepcionais, mas podemos dizer que, em geral, tudo funciona de forma estável e nenhum problema foi observado. Se algum problema surgir, entre em contato com o rastreador de issues do projeto, onde você também pode apoiar financeiramente os desenvolvedores.