30% da RAM é “buffers”. O que é isso?

9
$ free -h
              total        used        free      shared  buff/cache   available
Mem:           501M        146M         19M        9.7M        335M        331M
Swap:          1.0G         85M        938M

$ free -w -h
              total        used        free      shared     buffers       cache   available
Mem:           501M        146M         19M        9.7M        155M        180M        331M
Swap:          1.0G         85M        938M

Como posso descrever ou explicar "buffers" na saída de free ?

Eu não tenho nenhum problema (conhecido) com este sistema. Estou apenas surpreso e curioso ao ver que "buffers" é quase tão alto quanto "cache" (155M v.s. 180M). Eu pensei "cache" representou o cache de página do conteúdo do arquivo, e tende a ser a parte mais significativa de "cache / buffers". Estou menos claro para o que são os "buffers".

Por exemplo, comparei isso ao meu laptop, que tem mais memória RAM. No meu laptop, a figura "buffers" é uma ordem de magnitude menor que "cache" (200M v.s. 4G). Se eu tivesse uma compreensão adequada do que eram "buffers", então eu poderia começar a perguntar por que os buffers podem crescer para uma proporção tão grande no sistema menor.

man proc (ignoro a definição hilariamente ultrapassada de "grande"):

Buffers %lu

Relatively temporary storage for raw disk blocks that shouldn't get tremendously large (20MB or so).

Cached %lu

In-memory cache for files read from the disk (the page cache). Doesn't include SwapCached.

$ free -V
free from procps-ng 3.3.12
$ uname -r
4.9.0-6-marvell
$ systemd-detect-virt
none

$ cat /proc/meminfo
MemTotal:         513976 kB
MemFree:           20100 kB
MemAvailable:     339304 kB
Buffers:          159220 kB
Cached:           155536 kB
SwapCached:         2420 kB
Active:           215044 kB
Inactive:         216760 kB
Active(anon):      56556 kB
Inactive(anon):    73280 kB
Active(file):     158488 kB
Inactive(file):   143480 kB
Unevictable:       10760 kB
Mlocked:           10760 kB
HighTotal:             0 kB
HighFree:              0 kB
LowTotal:         513976 kB
LowFree:           20100 kB
SwapTotal:       1048572 kB
SwapFree:         960532 kB
Dirty:               240 kB
Writeback:             0 kB
AnonPages:        126912 kB
Mapped:            40312 kB
Shmem:              9916 kB
Slab:              37580 kB
SReclaimable:      29036 kB
SUnreclaim:         8544 kB
KernelStack:        1472 kB
PageTables:         3108 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:     1305560 kB
Committed_AS:    1155244 kB
VmallocTotal:     507904 kB
VmallocUsed:           0 kB
VmallocChunk:          0 kB

$ sudo slabtop --once
 Active / Total Objects (% used)    : 186139 / 212611 (87.5%)
 Active / Total Slabs (% used)      : 9115 / 9115 (100.0%)
 Active / Total Caches (% used)     : 66 / 92 (71.7%)
 Active / Total Size (% used)       : 31838.34K / 35031.49K (90.9%)
 Minimum / Average / Maximum Object : 0.02K / 0.16K / 4096.00K

  OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME                   
 59968  57222   0%    0.06K    937       64      3748K buffer_head            
 29010  21923   0%    0.13K    967       30      3868K dentry                 
 24306  23842   0%    0.58K   4051        6     16204K ext4_inode_cache       
 22072  20576   0%    0.03K    178      124       712K kmalloc-32             
 10290   9756   0%    0.09K    245       42       980K kmalloc-96             
  9152   4582   0%    0.06K    143       64       572K kmalloc-node           
  9027   8914   0%    0.08K    177       51       708K kernfs_node_cache      
  7007   3830   0%    0.30K    539       13      2156K radix_tree_node        
  5952   4466   0%    0.03K     48      124       192K jbd2_revoke_record_s   
  5889   5870   0%    0.30K    453       13      1812K inode_cache            
  5705   4479   0%    0.02K     35      163       140K file_lock_ctx          
  3844   3464   0%    0.03K     31      124       124K anon_vma               
  3280   3032   0%    0.25K    205       16       820K kmalloc-256            
  2730   2720   0%    0.10K     70       39       280K btrfs_trans_handle     
  2025   1749   0%    0.16K     81       25       324K filp                   
  1952   1844   0%    0.12K     61       32       244K kmalloc-128            
  1826    532   0%    0.05K     22       83        88K trace_event_file       
  1392   1384   0%    0.33K    116       12       464K proc_inode_cache       
  1067   1050   0%    0.34K     97       11       388K shmem_inode_cache      
   987    768   0%    0.19K     47       21       188K kmalloc-192            
   848    757   0%    0.50K    106        8       424K kmalloc-512            
   450    448   0%    0.38K     45       10       180K ubifs_inode_slab       
   297    200   0%    0.04K      3       99        12K eventpoll_pwq          
   288    288 100%    1.00K     72        4       288K kmalloc-1024           
   288    288 100%    0.22K     16       18        64K mnt_cache              
   287    283   0%    1.05K     41        7       328K idr_layer_cache        
   240      8   0%    0.02K      1      240         4K fscrypt_info           
    
por sourcejedi 28.04.2018 / 12:13

2 respostas

8
  1. Qual é a diferença entre "buffer" e o outro cache?
  2. Quando o Linux usa o cache de buffer em vez do cache de páginas?
  3. Por que podemos esperar que o cache de buffer seja maior ou menor?

1. Qual é a diferença entre "buffer" e o outro cache?

É seguro dizer que o cache de buffer é "armazenamento para blocos de disco brutos". Os blocos de disco usados pelo sistema de arquivos podem ser tão pequenos quanto 512 bytes. Isso difere do cache de páginas , usado para dados de arquivos.

O cache da página está vinculado ao tamanho da página da MMU, que normalmente é um mínimo de 4096 bytes. Isso é essencial para o acesso a arquivos mapeados no memmory [ 1 ] [2] e especificamente para carregar páginas de código individuais de programas em execução sob demanda. (Além disso, descarregar páginas quando algo mais precisa do espaço e elas não foram usadas recentemente).

2. Quando o Linux usa o cache de buffer em vez do cache de páginas?

No Linux moderno, seu cache de buffer provavelmente consiste em metadados do sistema de arquivos. Isso inclui o conteúdo do diretório.

Este uso do cache de buffer é dependente do sistema de arquivos, mas inclui o ext4 que é usado pelo sistema em questão.

Buffers [in /proc/meminfo] are in-memory block I/O buffers. They are relatively short-lived. Prior to Linux kernel version 2.4, Linux had separate page and buffer caches. Since 2.4, the page and buffer cache are unified and Buffers is raw disk blocks not represented in the page cache—i.e., not file data.

...

The buffer cache remains, however, as the kernel still needs to perform block I/O in terms of blocks, not pages. As most blocks represent file data, most of the buffer cache is represented by the page cache. But a small amount of block data isn't file backed—metadata and raw block I/O for example—and thus is solely represented by the buffer cache.

- Um par de Quora responde por Robert Love , última atualização em 2013.

Certain file systems, including ext3, ext4, and ocfs2, use the jbd or jbd2 layer to handle their physical block journalling, and this layer fundamentally uses the buffer cache, since it is concerned with controlling when specific file system blocks are allowed to ben written back to the hard drive.

Other file systems may not support file system blocks smaller than 4k. This may make it easier for them to use the page cache for their metadata blocks, although I don't know what happens if you try to mount a btrfs file system formatted with 4k blocks on an architecture such as Power which has 16k pages. I don't know if it will work, or blow up in a spectacular display of sparks. :-)

- Artigo de e-mail por Ted Tso , 2013

A primeira fonte já é citada no StackExchange, como a resposta mais autoritária para essa pergunta. linux - Qual é a coluna de buffers na saída de livre? . A segunda fonte tem detalhes técnicos mais específicos. Ambos os escritores são desenvolvedores Linux que trabalharam com o gerenciamento de memória do kernel Linux.

3. Por que podemos esperar que o cache de buffer seja maior ou menor?

Acontece que o tamanho do diário ext4 para o meu sistema de arquivos é de 128M. Então, isso explica porque 1) o cache de buffer pode se estabilizar em pouco mais de 128M; 2) cache de buffer não é dimensionado proporcionalmente com a maior quantidade de RAM no meu laptop.

Para provar que as anotações do diário usam o cache de buffer, simule um sistema de arquivos em RAM (tmpfs) e compare o uso máximo do buffer para diferentes tamanhos de diário.

# dd if=/dev/zero of=/tmp/t bs=1M count=1000
...
# mkfs.ext4 /tmp/t -J size=256
...
# LANG=C dumpe2fs /tmp/t | grep '^Journal size'
dumpe2fs 1.43.5 (04-Aug-2017)
Journal size:             256M
# mount /tmp/t /mnt
# cd /mnt
# free -w -m
              total        used        free      shared     buffers       cache   available
Mem:           7855        2521        4321         285          66         947        5105
Swap:          7995           0        7995

# for i in $(seq 40000); do dd if=/dev/zero of=t bs=1k count=1 conv=sync status=none; sync t; sync -f t; done
# free -w -m
              total        used        free      shared     buffers       cache   available
Mem:           7855        2523        3872         551         237        1223        4835
Swap:          7995           0        7995
# dd if=/dev/zero of=/tmp/t bs=1M count=1000
...
# mkfs.ext4 /tmp/t -J size=16
...
# LANG=C dumpe2fs /tmp/t | grep '^Journal size'
dumpe2fs 1.43.5 (04-Aug-2017)
Journal size:             16M
# mount /tmp/t /mnt
# cd /mnt
# free -w -m
              total        used        free      shared     buffers       cache   available
Mem:           7855        2507        4337         285          66         943        5118
Swap:          7995           0        7995

# for i in $(seq 40000); do dd if=/dev/zero of=t bs=1k count=1 conv=sync status=none; sync t; sync -f t; done
# free -w -m
              total        used        free      shared     buffers       cache   available
Mem:           7855        2509        4290         315          77         977        5086
Swap:          7995           0        7995

Como cheguei a olhar para o diário

Eu encontrei o e-mail primeiro e fiquei intrigado por enfatizar o write cache. Eu acharia surpreendente se dados "sujos", não-escritos conseguissem atingir 30% da RAM no meu sistema. sudo atop mostra que, em um intervalo de 10 segundos, o sistema em questão grava consistentemente apenas 1 MB. O sistema de arquivos em questão seria capaz de acompanhar mais de 100 vezes essa taxa. (Está em uma unidade de disco rígido USB2, taxa de transferência máxima ~ 20MB / s).

Usar o blktrace ( btrace -w 10 /dev/sda ) confirma que os IOs que estão sendo armazenados em cache devem ser gravados, porque quase não há dados sendo lidos. Também que mysqld é o único processo userspace fazendo IO.

Parei o serviço responsável pelas gravações (icinga2 escrevendo para o mysql) e verifiquei novamente. Eu vi "buffers" cair para menos de 20M - não tenho explicação para isso - e ficar lá. Reiniciar o gravador novamente mostra "buffers" aumentando em ~ 0.1M para cada intervalo de 10 segundos. Eu observei manter essa taxa consistentemente, subindo para 70M e acima.

A execução de echo 3 | sudo tee /proc/sys/vm/drop_caches foi suficiente para reduzir novamente "buffers" para 4,5M. Isso prova que meu acúmulo de buffers é um cache "limpo", que o Linux pode descartar imediatamente quando necessário. Este sistema não está acumulando dados não escritos . ( drop_caches não executa nenhum writeback e, portanto, não pode descartar páginas sujas. Se você quiser executar um teste que limpe o cache primeiro, use o comando sync ).

O diretório mysql inteiro é apenas 150M. Os buffers de acumulação devem representar blocos de metadados das gravações do mysql, mas me surpreendeu pensar que haveria tantos blocos de metadados para esses dados.

    
por 28.04.2018 / 12:40
2

Sua versão de free tem a ideia certa. Por padrão, ele combina buffers e cache em seu relatório. Isso é porque eles são basicamente a mesma coisa. Eles são tanto o computador lembrando na RAM (mais rápido que o armazenamento secundário: discos e SSD), o que já viu ao ler o disco e SSD.

Se o sistema operacional achar que a memória é melhor usada por outra coisa, ele pode liberá-la. Portanto, não se preocupe com buffer e cache.

No entanto, assistir a um DVD pode fazer com que o buffer aumente e libere outro conteúdo de buffer / cache. Portanto, você pode usar o nocache para rodar o DVD player ( se estiver causando um problema ).

    
por 28.04.2018 / 14:54