Armazenando e fazendo backup de 10 milhões de arquivos no Linux

25

Eu administro um site no qual cerca de 10 milhões de arquivos (capas de livros) são armazenados em 3 níveis de subdiretórios, variando de [0 a f]:

0/0/0/
0/0/1/
...
f/f/f/

Isso leva a cerca de 2400 arquivos por diretório, o que é muito rápido quando precisamos recuperar um arquivo. Além disso, é uma prática sugerida por muitas perguntas .

No entanto, quando preciso fazer backup desses arquivos, leva muitos dias apenas para navegar nos diretórios 4k com arquivos de 10m.

Então, eu estou querendo saber se eu poderia armazenar esses arquivos em um contêiner (ou em contêineres 4k), que cada um atuaria exatamente como um sistema de arquivos (algum tipo de contêiner ext3 / 4 montado?). Eu acho que isso seria quase tão eficiente quanto acessar diretamente um arquivo no sistema de arquivos, e isso teria a grande vantagem de ser copiado para outro servidor com muita eficiência.

Alguma sugestão sobre como fazer isso melhor? Ou alguma alternativa viável (noSQL, ...)?

Benjamin
fonte
Qual sistema de arquivos você está usando agora?
Cmcginty
NetApp é lickly ser uma opção se você pode afort os preços
Ian Ringrose
Estou usando ext4 no CentOS 5.6
Benjamin
11
Curioso por que deveria demorar "muitos dias apenas para navegar nos diretórios 4k com arquivos de 10m", o que parece muito lento. Assumindo 150 bytes por nome de caminho, os nomes de arquivos de 10m produzem 1,5 GB de dados, portanto, pode ser a memória / CPU disponível (incluindo a classificação do resultado). Além disso, verifique se a ativação / desativação do dir_index ajuda: lonesysadmin.net/2007/08/17/… além de várias dicas em serverfault.com/questions/183821/…
RichVel 6/11
Nota 5 anos depois: eu migrei tudo para o Amazon S3, que é perfeitamente adequado para armazenar uma quantidade tão grande de arquivos. Além disso, não tenho mais que dividir arquivos em três níveis de subdiretórios, pois o S3 não faz diferença (um caminho é um caminho, se ele contém barras ou não, não faz diferença). E posso dormir melhor, sabendo que meus dados são replicados com segurança em vários locais.
Benjamin

Respostas:

11

Opções para acessar e fazer backup de milhões de arquivos rapidamente

Empréstimo de pessoas com problemas semelhantes

Isso parece um problema mais fácil que os servidores de notícias da USENET enfrentam e os proxies da Web em cache: centenas de milhões de arquivos pequenos que são acessados ​​aleatoriamente. Você pode querer dar uma dica deles (exceto que eles geralmente não precisam fazer backups).

http://devel.squid-cache.org/coss/coss-notes.txt

http://citeseer.ist.psu.edu/viewdoc/download;jsessionid=4074B50D266E72C69D6D35FEDCBBA83D?doi=10.1.1.31.4000&rep=rep1&type=pdf

Obviamente, a natureza cíclica do sistema de arquivos cíclicos de notícias é irrelevante para você, mas o conceito de nível mais baixo de ter vários arquivos / dispositivos de disco com imagens compactadas e um índice rápido das informações que o usuário fornece para procurar as informações de localização são muito apropriados.

Sistemas de arquivos dedicados

Obviamente, esses são conceitos semelhantes aos do que as pessoas estavam falando ao criar um sistema de arquivos em um arquivo e montá-lo em loopback, exceto que você pode escrever seu próprio código de sistema de arquivos. Obviamente, desde que você disse que seu sistema era principalmente de leitura, você poderia realmente dedicar uma partição de disco (ou partição lvm para flexibilidade no dimensionamento) a esse único objetivo. Quando você desejar fazer backup, monte o sistema de arquivos somente leitura e faça uma cópia dos bits da partição.

LVM

Mencionei o LVM acima como útil para permitir o dimensionamento dinâmico de uma partição, para que você não precise fazer backup de muito espaço vazio. Mas, é claro, o LVM tem outros recursos que podem ser muito aplicáveis. Especificamente, a funcionalidade "instantâneo", que permite congelar um sistema de arquivos em um momento no tempo. Qualquer acidente rm -rfou qualquer coisa que não perturbe o instantâneo. Dependendo exatamente do que você está tentando fazer, isso pode ser suficiente para as necessidades de seus backups.

RAID-1

Tenho certeza de que você já conhece o RAID e provavelmente já o usa para obter confiabilidade, mas o RAID-1 também pode ser usado para backups, pelo menos se você estiver usando o RAID de software (você pode usá-lo com o RAID de hardware, mas na verdade oferece menor confiabilidade, pois pode exigir a leitura do mesmo modelo / controlador de revisão). O conceito é que você crie um grupo RAID-1 com mais um disco do que o necessário para atender às suas necessidades normais de confiabilidade (por exemplo, um terceiro disco, se você usar o software RAID-1 com dois discos, ou talvez um disco grande e um hardware - RAID5 com discos menores com um software RAID-1 na parte superior do hardware RAID-5). Quando chegar a hora de fazer um backup, instale um disco, peça ao mdadm para adicionar esse disco ao grupo de incursões, aguarde até que ele indique se está completo, peça opcionalmente uma verificação de verificação e remova o disco. Claro,

Seth Robertson
fonte
Resposta muito completa, que resume boas soluções. Acho que vou manter minha estrutura de sistema de arquivos existente e usar os instantâneos do LVM, o que parece ser perfeito para o meu caso de uso.
Benjamin
9

Você pode montar um sistema de arquivos virtual usando o gerenciador de loopback, mas, embora isso acelere seu processo de backup, pode afetar as operações normais.

Outra alternativa é fazer backup de todo o dispositivo usando o dd. Por exemplo dd if=/dev/my_device of=/path/to/backup.dd,.


fonte
+1 Fazer o backup do dispositivo em si é uma boa ideia.
Asm
3
Você deve, se usar essa abordagem, testar a restauração (bem, sempre faça isso), porque se sua entrada for um disco como / dev / sdd, o dd armazenará o tamanho e o tamanho da partição. Se você restaurá-lo em um disco menor, você receberá erros e, se restaurá-lo em um disco maior, ele aparecerá truncado. Funcionará melhor se você restaurar os dados para outro exemplo do mesmo tipo de disco. Restaurar apenas partições (/ dev / sdd1) será menos problemático.
usuário desconhecido
11
Observe que, se o dispositivo estiver no LVM, um backup também poderá ser executado sem desmontar o disco usando os instantâneos do LVM.
Bdllan
Segundo a abordagem de backup de captura instantânea do LVM. Eu alavanquei o lvm no passado para replicação ao vivo de DR. O uso do dd em combinação com os instantâneos facilita os backups rápidos em nível de bloco.
Slashdot
Eu tentei de ddnovo nce isso faz um bom trabalho! No entanto, posso ter dados inconsistentes / corrompidos, em vez de usar instantâneos do LVM em vez da partição ativa.
Benjamin
8

Como você provavelmente sabe, seu problema é a localidade. Uma busca de disco típica leva 10ms ou mais. Portanto, basta chamar "stat" (ou open ()) em 10 milhões de arquivos colocados aleatoriamente e requer 10 milhões de buscas, ou cerca de 100000 segundos ou 30 horas.

Portanto, você deve colocar seus arquivos em contêineres maiores, para que o número relevante seja a largura de banda da sua unidade (50-100 MB / s para um único disco, normalmente), em vez do tempo de busca. Além disso, você pode lançar um RAID nele, o que permite aumentar a largura de banda (mas não reduzir o tempo de busca).

Provavelmente não estou lhe dizendo nada que você ainda não saiba, mas o que quero dizer é que sua ideia de "contêiner" definitivamente resolverá o problema, e praticamente qualquer contêiner ajudará. As montagens de loopback provavelmente funcionarão tão bem quanto qualquer outra coisa.

Nemo
fonte
Sim, a localidade é crucial. Veja seus padrões de uso. A maioria dos problemas costuma seguir o Princípio de Pareto (80% dos processos atingem 20% dos dados); portanto, se você descobrir quais arquivos precisam ser armazenados em cache na RAM ou apenas colocar uma partição separada com um layout de diretórios diferente, então são necessárias menos pesquisas ou diretórios, provavelmente ajudaria bastante. Espalhar os arquivos acessados ​​com freqüência em diferentes eixos de discos para que as buscas possam ser feitas em paralelo também pode ajudar. +1 para @nemo por exibir a localidade de referência.
Marcin
5

Há um par de opções. O mais simples, e deve funcionar com todos os sistemas de arquivos Linux, é ddcopiar toda a partição ( /dev/sdb3ou /dev/mapper/Data-ImageVol) para uma única imagem e arquivar essa imagem. No caso de restaurar arquivos singulares, monte em loopback a imagem ( mount -o loop /usr/path/to/file /mountpoint) e copie os arquivos necessários. Para uma restauração completa da partição, você pode reverter a direção do ddcomando inicial , mas realmente precisa de uma partição de tamanho idêntico.

A julgar pelo seu caso de uso, acho que as restaurações individuais de arquivos são um evento pouco frequente, se é que ocorrem. É por isso que um backup baseado em imagem realmente faz sentido aqui. Se você precisar fazer restaurações individuais com mais frequência, usar snapshots LVM em etapas será muito mais conveniente; mas você ainda precisa fazer o backup baseado em imagem para os desastres críticos "perdemos tudo". As restaurações baseadas em imagem tendem a ser muito mais rápidas que as restaurações baseadas em alcatrão, simplesmente porque está apenas restaurando blocos, não está ocorrendo muitas operações de metadados a cada fopen / fclose e também pode ser uma operação de disco altamente seqüencial para mais velocidade aumenta.

Como alternativa, como o vídeo do Google @casey apontou na metade do caminho, o XFS é um ótimo sistema de arquivos (se complexo). Um dos utilitários mais agradáveis ​​do XFS é o xfsdumputilitário, que despeja um sistema de arquivos inteiro em um único arquivo e geralmente o faz mais rápido do que tarpode. É um utilitário específico do sistema de arquivos, para que você possa tirar proveito dos recursos internos do fs de maneiras que o tar não pode.

sysadmin1138
fonte
Muitas boas respostas lá! O XFS parece ser interessante, mas temo que esteja um pouco fora do meu alcance.
Benjamin
2

Talvez seja uma resposta simplista, mas meu primeiro pensamento foi usar algo como o GridFS, construído no MongoDB . Muitos dos drivers de idioma primário o suportam imediatamente, portanto, você pode trocá-lo apenas pelas seções de leitura de arquivo do seu código. Além disso, você pode apenas tornar os caminhos de diretório existentes as chaves para esses arquivos.

Um problema que você pode ter é que o Mongo tende a desacelerar muito rápido se estiver buscando o disco o tempo todo. Com 10 milhões de arquivos, espero que a maioria dos seus dados esteja em disco. Os pedaços de arquivos no GridFS são de 4 MB, pelo que me lembro, por isso, se os arquivos forem maiores do que isso, você fará várias operações caras para obter um arquivo. A chave, eu acho, seria fragmentar seus arquivos com base em sua estrutura de diretórios já organizada, para que você pudesse ter várias instâncias do Mongo executando em várias caixas para aliviar a carga. No entanto, também não sei quais são seus requisitos de desempenho, por isso posso estar pensando demais.

Qual é o benefício de tudo isso? Desempenho que se aproxima bastante das leituras de disco, se bem feito. Além disso, o Mongo vem com várias ótimas maneiras internas de fazer backup de toda a faixa de dados em uma instância de banco de dados rapidamente, e mesmo com o banco de dados ainda em execução.

daveslab
fonte
Definitivamente vou dar uma olhada no GridFS que eu não conhecia, mas acho que vou acabar mantendo tudo baseado no sistema de arquivos para diminuir a quantidade de trabalho, pois tudo já está funcionando!
Benjamin
1

Se você estiver satisfeito com um modelo de dispositivo para o armazenamento de dados, talvez considere o NexentaStor . Ele roda o ZFS no OpenSolaris, mas toda a administração é feita através de uma GUI da web.

Existem alguns recursos que ajudariam no seu problema.

  • A versão Enterprise suporta uma forma de replicação remota baseada em instantâneos que não exigem varredura em todo o sistema de arquivos.

  • Se você não se importa de sujar as mãos, o ZFS possui um comando diff do ZFS muito útil, que informa com eficiência quais arquivos foram adicionados, modificados ou excluídos desde o último instantâneo, sem a necessidade de varrer todo o sistema de arquivos. Você pode incorporar isso ao seu sistema de backup para reduzir bastante o tempo necessário para executar backups incrementais.

Tom Shaw
fonte
Obrigado, vai dar uma olhada nisso. Talvez isso acrescentasse um pouco de complexidade ao meu projeto!
Benjamin
1

Você pode usar um dumputilitário padrão Para fazer backup do sistema de arquivos EXT4 com muitos arquivos. Esse utilitário primeiro verifica quais blocos são usados ​​em um sistema de arquivos e depois faz o backup deles em ordem de disco, eliminando a maioria das buscas.

Existe um restoreutilitário correspondente para restaurar backups criados por dump.

Ele suporta backups incrementais usando arquivos de backups de nível 1 modificados a partir do último backup de nível 0 (completo), nível 2 - modificado a partir do backup de nível 1 e assim por diante.

Tometzky
fonte
0

Para backups incrementais, uma opção seria ter uma segunda árvore de sombra para novas capas. Ou seja, você teria sua árvore principal que é usada para todas as operações de leitura. Você também teria um newfiles/012345.....jpgdiretório; capas recém-adicionadas criam um link físico aqui e na árvore principal. Ao executar backups, você pode fazer backup ocasionalmente da árvore principal, mas faça backup da newfilesárvore (muito menor) com muito mais regularidade.

Observe que, para manter a newfilesárvore pequena, antes de executar um novo backup da árvore principal, você pode esvaziar a árvore dos novos arquivos:

mv newfiles newfiles_
mkdir newfiles
rm -rf newfiles_

Depois de fazer isso, é claro, você está comprometido em produzir um novo backup da árvore principal.

bdonlan
fonte
Abordagem interessante, obrigado por compartilhá-lo. Mas receio que isso envolva muitas alterações no aplicativo, e seria difícil manter o aplicativo e as necessidades de armazenamento em duas camadas separadas.
Benjamin
0

Adicionar um pouco de simultaneidade geralmente ajuda.

Eu tenho um problema semelhante ao seu; no meu caso, eu tenho que fazer backup de cerca de 30 milhões de arquivos, a maioria deles arquivos HTML, PHP ou JPEG. Para mim, o BackupPC + rsync over ssh funciona bem; o backup completo leva cerca de um dia, mas os incrementais geralmente terminam em algumas horas.

O truque é adicionar cada diretório de nível principal (0, 1, 2 ... a, b, c ...) como um novo destino para copiar no BackupPC e deixá-lo executar o backup em paralelo, para fazer backup dos diretórios simultaneamente a / , b / , c / * e assim por diante. Dependendo do seu subsistema de disco, qualquer coisa entre dois processos e cerca de 10 processos é provavelmente a maneira mais rápida de fazer backup.

Instantâneos LVM e backup em nível de bloco também são uma opção, mas com o BackuPC e o backup em nível de arquivo, você ainda pode restaurar arquivos ou diretórios individuais, se necessário.

Janne Pikkarainen
fonte
Estou surpreso que o backup simultâneo dos diretórios raiz resolva o problema para você. Espero que isso seja realmente mais lento. Todos os diretórios estão no mesmo disco? Você está usando um SSD?
Benjamin
Os arquivos de dados são armazenados na SAN.
Janne Pikkarainen
Ok, faz sentido agora, você ganha eficiência ao acessar vários arquivos simultaneamente, porque suas pastas diferentes provavelmente estão localizadas fisicamente em unidades diferentes na SAN, ou pelo menos replicadas em várias unidades, o que permite acesso simultâneo. Como sou apenas baseado em um RAID-1, acho que, acima de dois acessos simultâneos, é muito provável que minha velocidade diminua.
Benjamin
0

Benjamin,

Eu acho que seu problema pode ser resolvido com o número de arquivos por nível de diretório!

O tempo de acesso é alterado por um fator significativo se você armazenar 20 000 arquivos em um diretório?

Além disso, você pensou em armazenar os metadados do sistema de arquivos em uma unidade de acesso mais rápido separada (como um SSD).

Dragos
fonte
0

Eu recomendaria um bom e antigo banco de dados relacional.

Eu usaria um PostgreSQL com, digamos, 256 tabelas particionadas (cover_00, cover_01, ..., cover_ff) com dados de imagem como byteacoluna (binária) com armazenamento externo, com identificador de arquivo como chave primária. A recuperação de uma imagem seria rápida (graças a um índice na chave primária), a integridade dos dados seria garantida (banco de dados compatível com ACID), o backup seria em ordem de disco, portanto, não seria muito difícil.

Tometzky
fonte