Como e onde os metadados do sistema de arquivos são armazenados em cache no Linux

6

Minha pergunta anterior aparentemente tinha uma premissa errada. Eu pensei que os metadados do sistema de arquivos foram armazenados em cache no cache inode e dentry, mas aparentemente não.

Quando faço:

# time find . > /dev/null

real    10m4.435s
user    0m3.904s
sys     0m15.505s

# time find . > /dev/null

real    0m5.681s
user    0m1.400s
sys     0m4.224s

Você pode ver que a segunda corrida é muito mais rápida. Mas, ele volta a 10 minutos quando eu libero apenas o cache de páginas :

echo 1 > /proc/sys/vm/drop_caches

Slabtop ainda mostra um cache grande depois de eliminar esses caches:

   OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME                   
1758897 1758713  99%    0.19K  83757       21    335028K dentry
1216908 1211861  99%    0.76K  57948       21    927168K ext3_inode_cache

Eu não entendo como isso funciona, porque depois de eliminar todos os caches ( echo 3 > /proc/sys/vm/drop_caches ), slabtop ainda relata um grande tamanho de cache:

  OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME                   
1288434 955168  74%    0.19K  61354       21    245416K dentry                 
1216908 1211861  99%    0.76K  57948       21    927168K ext3_inode_cache

Então, os dados obtidos por find são armazenados no cache de páginas? Eu gostaria de armazenar esses dados no cache permanentemente, para não ter disco IO por causa de backups diários, mas se for armazenado no page_cache, não posso usar vfs_cache_pressure para controlá-lo.

Editar:

Quando eu faço um find e echo 2 to drop_caches (o que droparia o cache do dentry e do inode), o find ainda é rápido, e o /proc/meminfo ainda mostra o uso do slab:

# time find . > /dev/null    
real    8m11.918s
user    0m3.888s
sys     0m15.313s

# echo 2 > /proc/sys/vm/drop_caches

# time find . > /dev/null
real    0m8.883s
user    0m1.540s
sys     0m4.724s

E meminfo:

# cat /proc/meminfo |grep -i "^cache\|Slab"
Cached:           425224 kB
Slab:             891648 kB

echo 2 > /proc/sys/vm/drop_caches

# cat /proc/meminfo |grep -i "^cache\|Slab"
Cached:           333740 kB
Slab:             793428 kB

É o Ubuntu 12.04 no ext3.

    
por Halfgaar 08.04.2015 / 16:38

2 respostas

5

Isso ocorre porque seu teste é falho. A execução de find . simplesmente chama getdents () na árvore de diretórios. Um diretório, neste caso, é apenas um arquivo que contém entradas de diretório e, portanto, é armazenado no cache de páginas. Note que você não faz nada para realmente acessar os arquivos que você está tentando armazenar em cache desta maneira.

Seu teste é basicamente o armazenamento em cache de todos os diretórios na árvore do sistema de arquivos e nada mais.

Teste seu teste, o que dá find uma tarefa mais difícil. Por exemplo, forçando-o a chamar lstat para cada arquivo e você verá um comportamento diferente.

No meu teste, há um milhão de arquivos nesse diretório.

[root@home test]# echo 3 >/proc/sys/vm/drop_caches 
[root@home test]# time find ./tmp -printf "%p %c\n" >/dev/null

real    0m16.443s
user    0m2.123s
sys 0m9.320s
[root@home test]# time find ./tmp -printf "%p %c\n" >/dev/null

real    0m2.704s
user    0m1.224s
sys 0m1.479s
[root@home test]# echo 1 >/proc/sys/vm/drop_caches 
[root@home test]# time find ./tmp -printf "%p %c\n" >/dev/null

real    0m3.791s
user    0m1.359s
sys 0m1.756s

Note que no último teste leva um pouco mais de tempo, imagino que isso esteja diretamente relacionado a toda a leitura do diretório 'file' em si, e não porque o cache de dentry e inode não existe.

    
por 08.04.2015 / 19:42
0

No meu sistema (CentOS 7 x86_64), find . /usr/ parece carregar somente o cache do i / dentry, e não o pagecache.

Vamos começar a formar um estado "limpo":

echo 3 > /proc/sys/vm/drop_caches

cat /proc/meminfo | grep -i "^cache\|Slab"
Cached:           280432 kB
Slab:              66632 kB

Agora, time find . /usr/ > /dev/null 2>/dev/null

real    0m5.126s
user    0m0.580s
sys     0m2.939s

cat /proc/meminfo | grep -i "^cache\|Slab"
Cached:           283308 kB
Slab:             288656 kB

Apenas a placa aumentou em tamanho. Agora, vamos soltar o i / dcache:

echo 2 > /proc/sys/vm/drop_caches

cat /proc/meminfo | grep -i "^cache\|Slab"
Cached:           282704 kB
Slab:              66428 kB

O tamanho da laje diminui drasticamente. time find . /usr/ > /dev/null 2>/dev/null give

real    0m5.122s
user    0m0.624s
sys     0m2.905s

O mesmo que acima. Descartando o pagecache apenas com

echo 1 > /proc/sys/vm/drop_caches

time find . /usr/ > /dev/null 2>/dev/null
real    0m0.848s
user    0m0.256s
sys     0m0.575s

Como você pode ver, a queda do pagecache só não afeta find speed, que permanece muito mais rápida que antes.

    
por 08.04.2015 / 17:17