Pular para o conteúdo principal

Expansão do diretório de arquivo para vários discos com o MergerFS

Use o MergerFS apenas se não puder planejar o array de discos com antecedência

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.

Observação

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:

Observe

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.