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, ...)?
Respostas:
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 -rf
ou 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,
fonte
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
dd
novonc
e 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.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.
fonte
Há um par de opções. O mais simples, e deve funcionar com todos os sistemas de arquivos Linux, é
dd
copiar toda a partição (/dev/sdb3
ou/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 dodd
comando 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
xfsdump
utilitário, que despeja um sistema de arquivos inteiro em um único arquivo e geralmente o faz mais rápido do quetar
pode. É 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.fonte
Eu sugiro que você primeiro tente atualizar para o EXT4, se ainda não o estiver executando.
O Google fez muita pesquisa sobre por que EXT4 é uma boa ideia .
Depois disso, você deve implementar uma arquitetura de sistema de arquivos distribuídos. Por exemplo:
fonte
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.
fonte
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.
fonte
Você pode usar um
dump
utilitá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
restore
utilitário correspondente para restaurar backups criados pordump
.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.
fonte
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.....jpg
diretó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 danewfiles
á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:Depois de fazer isso, é claro, você está comprometido em produzir um novo backup da árvore principal.
fonte
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.
fonte
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).
fonte
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
bytea
coluna (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.fonte