Isso pode parecer estúpido, mas a verdade ( sua verdade) é um resultado de referência. Pode haver sistemas de arquivos que são mais rápidos do que outros em todos os casos, mas a estrutura ideal provavelmente depende das características de velocidade de seus discos e da quantidade de RAM e da eficácia do cache.
O que acontece se você usar diretórios menores com uma hierarquia mais profunda? Menos dados devem ser lidos para encontrar uma entrada de diretório, mas talvez (se a entrada desse diretório em seu pai não estiver mais armazenada em cache). Vamos supor que uma entrada de diretório seja de 50 bytes. São 15K para o diretório inteiro com 300 arquivos. Ao fazer leituras consecutivas, seu disco provavelmente fornece mais de 150 MiB / s. Assim, a diferença entre a leitura de 300 arquivos ou 600 arquivos é de 0,1 milissegundos. O tempo de posicionamento é de 4ms, na melhor das hipóteses (se não for um SSD). Ou seja para cada consulta de diretório salva, você pode ler as entradas de pelo menos 12.000 arquivos. Isso me faz supor que seus diretórios são bem pequenos. Mas talvez todas as suas entradas de diretório estejam no cache (eu não sei como monitorar isso, seria interessante), então esse cálculo é irrelevante. Talvez seja útil manter um script em segundo plano, que acessa todos os diretórios uma vez a cada poucos segundos, para que nenhum deles seja descartado do cache.
Eu assumo que o problema não é o tempo de pesquisa para o arquivo inode. Provavelmente, muitos processos tentam fazer E / S simultaneamente. Se isso levar os arquivos a serem lidos em várias etapas, o desempenho está morto, é claro. O mesmo é verdade para a fragmentação de arquivos. Dê uma olhada em filefrag
e seus arquivos de cache. E dê uma olhada em blockdev --setra
. Você deve ajustar isso ao tamanho médio do seu arquivo (ou ao tamanho de mais de 90% dos seus arquivos) e verificar se isso tem alguma influência. Eu também achei a dica (vários anos, embora) para definir este valor como zero para todos os dispositivos, exceto para o mais alto:
/dev/sdx -> ra=0
/dev/mdx -> ra=0
/dev/lvm/ -> ra=xxxx
Eu não sei o quanto você está disposto a fazer, mas posso imaginar que um módulo FUSE ajudaria no seu caso (dependendo do tamanho do arquivo e da eficácia da leitura antecipada): Este módulo teria que garantir que os arquivos são lidos em uma etapa e que (dentro dos limites do userspace) esses acessos não são interrompidos. A próxima etapa seria classificar os acessos a arquivos por posição no disco, ou seja, fazer no nível do arquivo o que o kernel (e o próprio disco) faz com operações de E / S únicas. Em vez de ter um grande sistema de arquivos com diretórios, você poderia criar LVs menores. Assim, você poderia classificar os acessos a arquivos pelo nome e obter os acessos ordenados por área de disco.
Se você estiver disposto a mudar seu hardware, isso pode ser interessante: Colocando apenas os metadados em um SSD . E você deve tentar obter acessos de gravação dos seus discos de cache. Isso pode ser principalmente arquivos de log. Eles geralmente não são realmente importantes, portanto, pode ser útil colocá-los em um sistema de arquivos com tempo de confirmação longo e data=writeback
.
Se (alguns de) seus dados de cache são estáticos (e você não precisa de ACL), então você pode testar o desempenho se você movê-lo de ext4 para squashfs (FS somente leitura compactados). Mesmo a compressão transparente (FUSE) dentro do ext4 pode ajudar se o problema estiver lendo um arquivo em várias etapas. A leitura antecipada do sistema de arquivos (e do disco interno) obteria mais do arquivo (se ele fosse compressível).