Estou executando o Ubuntu 24.04 usando ZFS para meus sistemas de arquivos. Isso ocorre em um laptop cujo único dispositivo de armazenamento é uma placa WD Black SN850X NVMe. O processo de instalação padrão do Ubuntu configurou dois pools ZFS:
capacity operations bandwidth
pool alloc free read write read write
-------------------------------------- ----- ----- ----- ----- ----- -----
bpool 187M 1.69G 0 0 381 204
86349523-abd9-7a45-ab84-60d7622c240f 187M 1.69G 0 0 381 204
-------------------------------------- ----- ----- ----- ----- ----- -----
rpool 286G 634G 13 31 1.11M 796K
cc31ec4d-1dd2-ed4f-9f90-fa99ec5aa3a2 286G 634G 13 31 1.11M 796K
-------------------------------------- ----- ----- ----- ----- ----- -----
/tmp
faz parte da montagem raiz, que está em rpool.
Minha /tmp
pasta continha brevemente mais de 2 milhões de arquivos devido a um bug em algum código. Quando havia tantos arquivos nele, o desempenho despencou - até mesmo a listagem de arquivos (sem classificação) fazia uma pausa por mais de um segundo. Removi a maioria dos arquivos e as coisas voltaram a um nível gerenciável agora. Porém, as operações na lista de arquivos /tmp
ainda são lentas.
Quando eu uso ls --sort=none
eg /bin
, que tem 2.842 entradas, recebo algo como:
real 0m0.088s
user 0m0.001s
sys 0m0.075s
Mas o mesmo comando on /tmp
, que atualmente possui 4.444 entradas:
real 0m0.472s
user 0m0.007s
sys 0m0.446s
Parece que abrigar brevemente 2 milhões de arquivos deixou um impacto permanente na estrutura do /tmp
? Existe uma maneira de corrigir isso? Eu só preciso fazer um novo /tmp
e passar para ele?
Em algum lugar acima de milhões de arquivos em um diretório, o desempenho será muito pior. Realmente não importa qual sistema de arquivos ou quantos IOPS no dispositivo de bloco. A semântica POSIX significa uma sobrecarga significativa para manter o arquivo no conceito de diretório. O que então se torna um exercício de compreensão dos componentes internos do sistema de arquivos.
No seu gráfico em degradê, não é surpresa que a maioria das pilhas se origine em chamadas readdir. Estou surpreso que o nível superior, que realmente leva tempo, seja principalmente a descompactação LZ4. Que é um algoritmo rápido. Centenas de milissegundos de tempo de CPU fazendo isso implicam em muitos metadados, ou muitas chamadas para getdents64, ou algo mais lento.
Pelo pouco que entendo sobre o ZFS no formato de disco , os conjuntos de dados têm seus próprios conjuntos de objetos. Então, sim, você poderia criar um novo conjunto de dados tmp a partir do pool raiz e montá-lo sobre o/tmp existente. Não é necessário copiar dados, pois são arquivos temporários.
Ou um tmpfs em/tmp. Simplifique as coisas removendo o ZFS e os dispositivos de bloco.
Tarde demais para evitar esse problema de muitos arquivos, mas o OpenZFS tem cotas de objetos. groupquota@group para definir e
zfs userspace
listar. Também pode ser definido por usuário ou projeto.Agora tenho a resposta para isso. Então, sim, é um problema conhecido. Na terminologia interna do ZFS, "se os registros ZAP forem excluídos de forma que um bloco folha inteiro do objeto ZAP seja esvaziado, o bloco não será recuperado." Mas não é apenas um problema conhecido, mas também um problema fixo . :-) A correção ainda não está em nenhuma versão de envio, mas espera-se que esteja em breve.
Esta é a solução:
https://github.com/openzfs/zfs/pull/15888