linux: acessando milhares de arquivos em hash de diretórios

3

Gostaria de saber qual é a maneira mais eficiente de acessar simultaneamente milhares de arquivos de tamanho semelhante em um cluster moderno de computadores Linux.

Estou carregando uma operação de indexação em cada um desses arquivos, então os 4 arquivos de índice, cerca de 5-10x menores que o arquivo de dados, são produzidos ao lado do arquivo a ser indexado.

Agora, estou usando uma hierarquia de diretórios de ./00/00/00 para ./99/99/99 e coloco um arquivo no final de cada diretório.
 como ./00/00/00/file000000.ext to ./99/99/99/file999999.ext .

Parece funcionar melhor do que ter milhares de arquivos no mesmo diretório, mas eu gostaria de saber se existe uma maneira melhor de organizar os arquivos para melhorar o acesso.

    
por 719016 03.07.2012 / 10:20

3 respostas

1

Um problema comum de desempenho com diretórios grandes no ext [34] é que ele contém as entradas de diretório e as armazena em ordem de hash. Isso permite resolver um nome específico rapidamente, mas efetivamente randomiza a ordem na qual os nomes são listados. Se você estiver tentando operar em todos os arquivos no diretório e apenas iterar sobre cada entrada na ordem em que eles estão listados, você causará um erro. monte de IO aleatório, que é muito lento. A solução para isso é classificar a listagem de diretórios pelo número de inode e, em seguida, fazer um loop nos arquivos na ordem do menor para o maior número de inode. Isso mantém seu IO na maior parte sequencial.

    
por 03.07.2012 / 17:07
1

Um esquema comumente usado está renomeando os arquivos com seu valor de hash, mantendo a extensão e usando os primeiros caracteres para armazená-los em pastas diferentes.

ou seja:
md5 (test.jpg) fornece "13edbb5ae35af8cbbe3842d6a230d279"
Seu arquivo será nomeado "13edbb5ae35af8cbbe3842d6a230d279.jpg" e você o armazenará em ./13/ed/bb/5ae35af8cbbe3842d6a230d279.jpg, dessa forma e com uma grande quantidade de arquivos você deverá ter uma boa distribuição de arquivos por pasta.

Você acaba com uma árvore semelhante à sua, mas mais clara (com metadados), pois você só precisa armazenar o nome do arquivo original e seu hash (o caminho sendo construído a partir do hash).

Como um efeito colateral (que deve ser levado em conta no desenvolvimento), você ganha automaticamente a deduplicação baseada em arquivos.
Além disso, se você gerar o hash antes de armazenar o arquivo, receberá também uma verificação de erros gratuita. Você poderia imaginar codificar um pequeno cronjob para verificar a integridade de seus backups dessa forma, por exemplo.

    
por 03.07.2012 / 10:42
0

Uma resposta aceita no ServerFault por Ignacio Vazquez-Abrams diz

Provided you have a distro that supports the dir_index capability then you can easily have 200,000 files in a single directory. I'd keep it at about 25,000 though, just to be safe. Without dir_index, try to keep it at 5,000.

O que eu considero como sugerindo

 ./000/file000000 to ./000/file000999
 ./001/file001000 to ./001/file001999
 ...
 ./999/file999000 to ./999/file999999

O tamanho de uma estrutura de diretórios nunca diminui, portanto, se um diretório já contiver tantos arquivos que ele cresceu para um tamanho ineficiente, excluir ou mover arquivos desse diretório não melhorará o desempenho desse diretório. Então sempre comece com novos diretórios (se necessário, renomeie diretórios grandes, crie novos diretórios, mova arquivos, apague diretórios antigos)

Respostas a outra pergunta do Stackoverflow diz

Nowadays the default is ext3 with dir_index, which makes searching large directories very fast.

Um comentarista diz

There is a limit of around 32K subdirectories in one directory in ext3, but the OP is talking about image files. There is no (practical?) limit on files in an ext3 file system with Dir Index enabled.

Acho que executei alguns testes para ver se a organização de arquivos em subdiretórios valeu a pena para algo diferente de ls performance. Regras gerais de otimização: 1 não, 2 realmente não, 3 medidas.

    
por 03.07.2012 / 10:36