Linux: quantas E / S de disco são necessárias para ler um arquivo? Como minimizá-lo? [duplicado]

10

De acordo com este artigo no Haystack do Facebook:

" Devido à maneira como os dispositivos NAS gerenciam os metadados do diretório, colocar milhares de arquivos em um diretório era extremamente ineficiente, pois o mapa de blocos do diretório era muito grande para ser armazenado em cache pelo dispositivo. Consequentemente, era comum incorrer em mais de 10 operações de disco para recuperar um Depois de reduzir o tamanho dos diretórios para centenas de imagens por diretório, o sistema resultante geralmente ainda incorre em 3 operações de disco para buscar uma imagem: uma para ler os metadados do diretório na memória, uma segunda para carregar o inode na memória e uma terceira para ler o conteúdo do arquivo " .

Eu tinha assumido que os metadados e o inode do diretório do sistema de arquivos sempre seriam armazenados em cache na RAM pelo sistema operacional e uma leitura de arquivo normalmente exigiria apenas 1 E / S de disco.

Esse problema de "E / S de discos múltiplos para ler um único arquivo" descrito neste documento é exclusivo para dispositivos NAS ou o Linux também tem o mesmo problema?

Estou planejando executar um servidor Linux para veicular imagens. De qualquer maneira, posso minimizar o número de E / S de disco - idealmente, certificando-se de que o sistema operacional armazene em cache todos os dados de diretório e inode na RAM e que cada leitura de arquivo exija apenas 1 E / S de disco?

user9517
fonte
1
Não é uma resposta para a pergunta, mas você sempre pode usar o Varnish (o Facebook usa), que mantém os arquivos na memória. Desta forma, se uma imagem se torna quente (um monte de pedido para o mesmo arquivo), IO de disco não será usado em todos para servi-lo
Darhazer - O Varnish não ajudaria aqui, já que o cache de arquivos do Linux (no qual o Varnish conta) já armazena arquivos quentes na memória. Colocar o verniz na frente do Nginx para veiculação estática de arquivos não adiciona nada. Minha pergunta é sobre quando os arquivos são grandes demais / demais para serem armazenados em cache na memória. Eu ainda gostaria de garantir que pelo menos os dados e inodes do diretório sejam armazenados em cache para reduzir o IO do disco para apenas 1 por leitura.
Muitos sistemas de arquivos armazenam o inode dentro do diretório, reduzindo o número de solicitações em um e aumentando significativamente a chance de ocorrência de um cache. Mas essa não é uma questão de programação.
Ben Voigt
Você pode alterar o tamanho do bloco do sistema de arquivos ao criá-lo, por exemplo, com mke2fs -b 3276832k. No entanto, isso é útil apenas se você não tiver arquivos pequenos nesse sistema de arquivos.

Respostas:

5

Linux tem o mesmo "problema". Aqui está um artigo que um aluno meu publicou há dois anos, onde o efeito é mostrado no Linux. Os vários IOs podem vir de várias fontes:

  • Pesquisa de diretório em cada nível de diretório do caminho do arquivo. Pode ser necessário ler o inode do diretório e um ou mais blocos de entrada do diretório
  • Inode do arquivo

No padrão normal de E / S, o armazenamento em cache é realmente eficaz e inodes, diretórios e blocos de dados são alocados de maneira a reduzir as buscas. No entanto, o método de pesquisa normal, que é realmente compartilhado por todos os sistemas de arquivos, é ruim para tráfego altamente aleatório.

Aqui estão algumas idéias:

1) Os caches relacionados ao sistema de arquivos ajudam. Um cache grande absorve a maioria das leituras. No entanto, se você deseja colocar vários discos em uma máquina, a proporção de disco para RAM limita quanto é armazenado em cache.

2) Não use milhões de arquivos pequenos. Agregue-os em arquivos maiores e armazene o nome do arquivo e o deslocamento dentro do arquivo.

3) Coloque ou armazene em cache os metadados em um SSD.

4) E, é claro, use um sistema de arquivos que não possua um formato de diretório em disco totalmente anárquico. Um readdir não deve demorar mais que o tempo linear e o acesso direto a arquivos, idealmente, apenas o tempo logarítmico.

Manter os diretórios pequenos (menos de 1000 ou mais) não deve ajudar muito, porque você precisaria de mais diretórios com cache.

dmeister
fonte
E, é claro, use um sistema de arquivos que não possua um formato de diretório em disco totalmente arcaico. Um readdir não deve demorar mais que o tempo linear e o acesso direto a arquivos, idealmente, apenas o tempo logarítmico.
Jorgensen
Acrescentei que a resposta como quarto ponto
dmeister
@dmeister Coisas boas. +1
Magalhães
@dmeister Seu link está morto.
Don Scott
1

Isso depende do sistema de arquivos que você planeja usar. Antes de ler o sistema de dados do arquivo:

  • Leia o arquivo de diretório.
  • Leia o inode do seu arquivo
  • Leia os setores do seu arquivo

Se a pasta contiver um grande número de arquivos, isso é uma grande garantia no cache.


fonte
Se você estiver listando os acessos de E / S, pode ser mais interessante separar os executados por open()daqueles executados por read(). A página win.tue.nl/~aeb/linux/vfs/trail.html mostra uma boa descrição dos diferentes conceitos de Kernel envolvidos. (Talvez seja ultrapassada eu não seria capaz de dizer?.)
ADL
0

Você provavelmente não conseguirá manter todos os dados de diretório e inode na RAM, pois provavelmente possui mais dados de diretório e inode que a RAM. Você também pode não querer, pois essa RAM pode ser melhor usada para outros fins; no seu exemplo de imagem, você não prefere que os dados de uma imagem acessada com frequência sejam armazenados em cache na RAM do que a entrada de diretório para uma imagem acessada com pouca frequência?

Dito isto, acho que o botão vfs_cache_pressure é usado para controlar isso. "Quando vfs_cache_pressure = 0, o kernel nunca recuperará dentries e inodes devido à pressão da memória e isso pode facilmente levar a condições de falta de memória."

Samuel Edwin Ward
fonte