Quais são as implicações de desempenho para milhões de arquivos em um sistema de arquivos moderno?

30

Digamos que estamos usando o ext4 (com o dir_index ativado) para hospedar cerca de 3 milhões de arquivos (com uma média de tamanho de 750 KB) e precisamos decidir qual esquema de pastas usaremos.

Na primeira solução , aplicamos uma função de hash ao arquivo e usamos a pasta de dois níveis (sendo 1 caractere para o primeiro nível e 2 caracteres para o segundo nível): portanto, sendo o filex.forhash igual a abcde1234 , vamos armazená-la no / path / a / bc /abcde1234-filex.for.

Na segunda solução , aplicamos uma função de hash ao arquivo e usamos a pasta de dois níveis (sendo 2 caracteres para o primeiro nível e 2 caracteres para o segundo nível): portanto, sendo o filex.forhash igual a abcde1234 , vamos armazená-la no / path / ab / de /abcde1234-filex.for.

Para a primeira solução, teremos o seguinte esquema /path/[16 folders]/[256 folders]com uma média de 732 arquivos por pasta (a última pasta, onde o arquivo residirá).

Enquanto na segunda solução, teremos /path/[256 folders]/[256 folders]uma média de 45 arquivos por pasta .

Considerando que vamos escrever / desvincular / ler arquivos ( mas principalmente ler ) desse esquema (basicamente o sistema de cache nginx), isso agrega, no sentido do desempenho, se escolhermos uma ou outra solução?

Além disso, quais são as ferramentas que poderíamos usar para verificar / testar essa configuração?

leandro moreira
fonte
7
Obviamente, o benchmarking ajudará. Mas ext4 pode ser o sistema de arquivos errado para isso. Eu estaria olhando para o XFS.
ewwhite
4
Eu não olharia apenas para o XFS, usaria imediatamente sem mais delongas. A árvore B + bate sempre na tabela de hash.
Michael Hampton
Obrigado pelas dicas, o benchmarking é um pouco difícil, tentei, hdparm -Tt /dev/hdXmas pode não ser a ferramenta mais apropriada.
leandro moreira
2
Não, hdparmnão é a ferramenta certa, é uma verificação do desempenho bruto do dispositivo de bloco e não um teste do sistema de arquivos.
precisa saber é o seguinte

Respostas:

28

A razão pela qual você criaria esse tipo de estrutura de diretório é que os sistemas de arquivos devem localizar um arquivo em um diretório e, quanto maior o diretório, mais lenta será a operação.

Quanto mais lento depende do design do sistema de arquivos.

O sistema de arquivos ext4 usa uma árvore B para armazenar entradas de diretório. Espera-se que uma pesquisa nesta tabela demore O (log n) , que na maioria das vezes é menor que a tabela linear ingênua usada pelos sistemas de arquivos ext3 e anteriores (e quando não é, o diretório é muito pequeno para ser usado). realmente importa).

O sistema de arquivos XFS usa uma árvore B + . A vantagem disso sobre uma tabela de hash ou uma árvore B é que qualquer nó pode ter vários filhos b , onde no XFS b varia e pode chegar a 254 (ou 19 no nó raiz; e esses números podem estar desatualizados ) Isso fornece uma complexidade de tempo de O (log b n) , uma grande melhoria.

Qualquer um desses sistemas de arquivos pode lidar com dezenas de milhares de arquivos em um único diretório, com o XFS sendo significativamente mais rápido que o ext4 em um diretório com o mesmo número de inodes. Mas você provavelmente não deseja um único diretório com inodes da 3M, pois mesmo com uma árvore B +, a pesquisa pode levar algum tempo. Isso foi o que levou à criação de diretórios dessa maneira em primeiro lugar.

Quanto às estruturas propostas, a primeira opção que você deu é exatamente o que é mostrado nos exemplos do nginx. Ele terá um bom desempenho em qualquer sistema de arquivos, embora o XFS ainda tenha um pouco de vantagem. A segunda opção pode ter um desempenho um pouco melhor ou um pouco pior, mas provavelmente será bem próxima, mesmo em benchmarks.

Michael Hampton
fonte
E para XFS ou ext4, o hardware no qual você coloca o sistema de arquivos terá um enorme impacto no desempenho. Uma unidade SATA lenta de 5400 rpm pode executar cerca de 50 operações aleatórias de E / S, uma boa unidade SAS de 15.000 rpm pode fazer algumas centenas e um SSD provavelmente terá uma largura de banda limitada e poderá obter alguns milhões de operações aleatórias de E / s se não mais.
Andrew Henle
11
Estritamente falando, $ O (\ log_b n) $ para $ b $ fixo é a mesma complexidade que $ O (\ log n) $. Mas para o OP, as constantes reais importariam.
Hagen von Eitzen
A menos que haja algo errado com meu sistema de arquivos, o ext4 não pode manipular 10.000 arquivos em um único diretório. Fazer um simples ls -lleva um minuto inteiro se o diretório caiu do cache do inode. E quando é armazenado em cache, ainda leva mais de um segundo. Isso ocorre com um SSD e um Xeon com toneladas de RAM em um servidor Web de tráfego bastante baixo.
Abhi Beckert
@AbhiBeckert Foi atualizado a partir do ext3? Nesse caso, tente criar um novo diretório e mova os arquivos para ele.
Michael Hampton
@Hampton No. É um servidor (razoavelmente) recentemente configurado em hardware moderno. Estou trabalhando no problema com nosso administrador de sistemas / data center há alguns meses. Pagamos milhares de dólares por mês para alugar o servidor e não obtemos um desempenho aceitável. Parece que a única opção é mudar para uma nova estrutura de diretórios - talvez usando hashes em vez de datas para nomes de arquivos para distribuí-la de maneira mais uniforme.
Abhi Beckert
5

Na minha experiência, um dos fatores de escala é o tamanho dos inodes, dada uma estratégia de particionamento de nome de hash.

As duas opções propostas criam até três entradas de inode para cada arquivo criado. Além disso, 732 arquivos criarão um inode ainda menor que o normal de 16 KB. Para mim, isso significa que qualquer uma das opções executará o mesmo.

Aplaudo por seu curto hash; sistemas anteriores em que trabalhei pegaram o sha1sum do arquivo fornecido e os diretórios emendados com base nessa string, um problema muito mais difícil.

sysadmin1138
fonte
11
O que torna o uso de somas SHA1 (e outras somas de hash mais longas) "um problema muito mais difícil"? É pesado para usuários humanos, sim, mas é o mesmo para o sistema operacional, sistema de arquivos e outros programas.
Kbolino
4

Certamente qualquer uma das opções ajudará a reduzir o número de arquivos em um diretório para algo que pareça razoável, para xfs ou ext4 ou qualquer outro sistema de arquivos. Não é óbvio o que é melhor, teria que testar para contar.

O benchmark com seu aplicativo simulando algo como a carga de trabalho real é ideal. Caso contrário, crie algo que simule especificamente muitos arquivos pequenos. Falando nisso, aqui está um código aberto chamado smallfile . Sua documentação faz referência a outras ferramentas.

hdparmfazer E / S sustentada não é tão útil. Não mostrará muitas entradas / entradas pequenas de diretório ou gigantes associadas a muitos arquivos.

John Mahowald
fonte
1

Um dos problemas é a maneira de verificar a pasta.

Imagine o método Java que executa a verificação na pasta.

Ele precisará alocar grande quantidade de memória e desalocá-la em um curto período de tempo, o que é muito pesado para a JVM.

A melhor maneira é organizar a estrutura de pastas da maneira que cada arquivo está na pasta dedicada, por exemplo, ano / mês / dia.

A maneira como a verificação completa é feita é que, para cada pasta, há uma execução da função, portanto a JVM sai da função, desaloca a RAM e a executa novamente em outra pasta.

Este é apenas um exemplo, mas de qualquer maneira ter uma pasta tão grande não faz sentido.

Andrew Smith
fonte
2
Você está assumindo Java e varrendo a pasta. Também não é mencionado. Na questão, e há outras maneiras de processar a pasta em Java além da verificação.
user207421
1

Eu estou tendo o mesmo problema. Tentando armazenar milhões de arquivos em um servidor Ubuntu no ext4. Acabei de executar meus próprios benchmarks. Descobriu que o diretório simples tem um desempenho muito melhor e é muito mais simples de usar:

referência

Escreveu um artigo .

Hartator
fonte
Esse definitivamente não é o resultado esperado. Antes de ir com isso ou recomendá-lo, você deve examinar mais detalhadamente por que obteve esse resultado inesperado.
Michael Hampton