No Linux, qual é a diferença entre "buffers" e "cache" relatados pelo comando free?


73

Essa é uma pergunta antiga que eu tenho visto de tempos em tempos. Meu entendimento é bastante limitado (tendo lido sobre as diferenças há muito tempo, mas os factóides envolvidos nunca realmente ficaram emperrados).

Como eu entendo,

  • Buffers

    São utilizados por programas com operações de E / S ativas, ou seja, dados aguardando gravação no disco

  • Cache

    É o resultado de operações de E / S concluídas, ou seja, buffers que foram liberados ou dados lidos no disco para atender a uma solicitação.

Posso obter uma explicação clara para a posteridade?



É mais como os metadados encontrados nos buffers, não está relacionado aos io buffers. Alguns dos buffers do kernel são contabilizados no alocador de laje, mas não contam para buffers ou memória cache.
Eckes

Respostas:


42

O total "em cache" também incluirá outras alocações de memória, como qualquer item de arquivo tmpfs. Para ver isso de fato, tente:

mkdir t
mount -t tmpfs none t
dd if=/dev/zero of=t/zero.file bs=10240 count=10240
sync; echo 3 > /proc/sys/vm/drop_caches; free -m
umount t
sync; echo 3 > /proc/sys/vm/drop_caches; free -m

e você verá o valor do "cache" cair nos 100Mb que copiou para o sistema de arquivos baseado em ram (assumindo que havia RAM livre suficiente, você poderá encontrar alguns deles acabados em troca se a máquina já estiver comprometida demais em termos de termos) uso de memória). O "sync; echo 3> / proc / sys / vm / drop_caches" antes de cada chamada para liberar deve gravar qualquer coisa pendente em todos os buffers de gravação (a sincronização) e limpar todos os blocos de disco em cache / em buffer da memória para que o free apenas leia outros alocações no valor "em cache".

A RAM usada pelas máquinas virtuais (como as que estão sendo executadas no VMWare) também pode ser contada no valor "em cache" do free, assim como a RAM usada pelos arquivos mapeados na memória atualmente abertos (isso varia dependendo do hipervisor / versão que você está usando e possivelmente entre versões do kernel também).

Portanto, não é tão simples como "os buffers contam com gravações pendentes de arquivos / rede e contagens em cache recentemente armazenadas em blocos de leitura / gravação mantidos na RAM para salvar futuras leituras físicas", embora, para a maioria dos propósitos, essa descrição mais simples funcione.


11
+1 para nuances interessantes. Esse é o tipo de informação que estou procurando. De fato, suspeito que os números sejam tão complicados, tão envolvidos em tantas atividades diferentes, que sejam, na melhor das hipóteses, indicadores gerais.
Avery Payne

Eu não acho que a RAM usada pelas máquinas virtuais seja contada como "armazenada em cache", pelo menos para o qemu-kvm. Percebo que no meu host KVM, o valor do cache não é pequeno demais para estar correto (a 1,9 Gig), mas não muda se eu destruir / iniciar uma das minhas VMs. Também não muda se eu executar o truque de montagem tmpfs em uma das VMs. Criei uma partição 800Meg tmpfs lá e "em cache" mostrou os valores adequados na VM, mas ela não foi alterada no host da VM. Mas o valor "usado" encolheu / cresceu quando destruí / iniciei minha VM.
Mike S

... Executei testes em um host da VM Centos 7.2.1511 executando o kernel 3.10.0-327.
Mike S

@MikeS: Como diferentes soluções de virtualização lidam com a memória pode variar, de fato, como o kernel mede vários usos da memória pode mudar entre as principais versões.
precisa

@MikeS: No que diz respeito a "executar o truque de montagem tmpfs em uma das VMs" - I que não afetará as leituras do host se elas não estiverem mostrando outro mem usado pela VM. Eu vejo o efeito em uma própria VM KVM: antes do dd free = 2020, depois do dd free = 1899, depois do drop fs free = 2001 (a diferença de 19 Mb ocorre devido a outros processos na VM, não estava ociosa quando executei o teste). O host pode não ver a alteração: provavelmente a memória ainda está alocada para a VM, embora esteja livre para uso pelos processos na VM.
precisa


5

Eu estava procurando uma descrição mais clara sobre o buffer e encontrei em "Professional Linux® Kernel Architecture 2008"

Capítulo 16: Cache de página e de buffer

Interação

A criação de um link entre páginas e buffers serve pouco se não houver benefícios para outras partes do kernel. Como já observado, algumas operações de transferência de e para dispositivos de bloco podem precisar ser executadas em unidades cujo tamanho depende do tamanho do bloco dos dispositivos subjacentes, enquanto muitas partes do kernel preferem executar operações de E / S com granularidade de página, pois facilita muito as coisas - especialmente em termos de gerenciamento de memória. Nesse cenário, os buffers atuam como intermediários entre os dois mundos.


3

Explicado pelo RedHat :

Páginas de cache:

Um cache é a parte da memória que armazena dados de forma transparente, para que solicitações futuras desses dados possam ser atendidas mais rapidamente. Essa memória é utilizada pelo kernel para armazenar em cache os dados do disco e melhorar o desempenho de E / S.

O kernel do Linux é construído de tal maneira que utilizará o máximo de RAM possível para armazenar informações em cache de seus sistemas e discos de arquivos locais e remotos. À medida que o tempo passa por várias leituras e gravações, são executadas no sistema, o kernel tenta manter os dados armazenados na memória para os vários processos em execução no sistema ou os dados dos processos relevantes que seriam usados ​​no futuro próximo. O cache não é recuperado no momento em que o processo é interrompido / sai; no entanto, quando os outros processos exigem mais memória do que a memória disponível livre, o kernel executará heurísticas para recuperar a memória, armazenando os dados do cache e alocando essa memória para o novo processo.

Quando qualquer tipo de arquivo / dado é solicitado, o kernel procurará uma cópia da parte do arquivo em que o usuário está atuando e, se essa cópia não existir, alocará uma nova página de memória cache e a preencherá com o conteúdo apropriado é lido do disco.

Os dados armazenados em um cache podem ser valores calculados anteriormente ou duplicados de valores originais armazenados em outro local do disco. Quando alguns dados são solicitados, o cache é primeiro verificado para ver se contém esses dados. Os dados podem ser recuperados mais rapidamente do cache do que de sua origem de origem.

Os segmentos de memória compartilhada do SysV também são contabilizados como um cache, embora não representem dados nos discos. Pode-se verificar o tamanho dos segmentos de memória compartilhada usando o comando ipcs -m e verificando a coluna de bytes.

Buffers:

Buffers são a representação do bloco de disco dos dados armazenados nos caches da página. Buffers contém os metadados dos arquivos / dados que residem no cache da página. Exemplo: Quando há uma solicitação de qualquer dado presente no cache da página, primeiro o kernel verifica os dados nos buffers que contêm os metadados que apontam para os arquivos / dados reais contidos nos caches da página. Uma vez que os metadados conhecem o endereço de bloco real do arquivo, ele é captado pelo kernel para processamento.


2

Liberando buffer / cache

Aviso Isso explica um método robusto não recomendado no servidor de produção! Então você está avisado, não me culpe se algo der errado.

Para entender, você pode forçar seu sistema a delegar o máximo de memória possível do cacheque soltar o arquivo em cache:

Preâmbulo

Antes de fazer o teste, você pode abrir outra janela e clicar:

$ vmstat -n 1
procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa
 0  1  39132  59740  39892 1038820    0    0     1     0    3    3  5 13 81  1
 1  0  39132  59140  40076 1038812    0    0   184     0 10566 2157 27 15 48 11
...

para acompanhar a evolução do swap em tempo real.

Nota: Você deve descartar o máximo de discos livres no diretório atual, pois possui mem + swap

A demo
$ free
         total       used       free     shared    buffers     cached
Mem:       2064396    2004320      60076          0      90740     945964
-/+ buffers/cache:     967616    1096780
Swap:      3145720      38812    3106908

$ tot=0
$ while read -a line;do
      [[ "${line%:}" =~ ^(Swap|Mem)Total$ ]] && ((tot+=2*${line[1]}))
    done </proc/meminfo
$ echo $tot
10420232

$ dd if=/dev/zero of=veryBigFile count=$tot
10420232+0 records in
10420232+0 records out
5335158784 bytes (5.3 GB) copied, 109.526 s, 48.7 MB/s

$ cat >/dev/null veryBigFile

$ free
             total       used       free     shared    buffers     cached
Mem:       2064396    2010160      54236          0      41568    1039636
-/+ buffers/cache:     928956    1135440
Swap:      3145720      39132    3106588

$ rm veryBigFile 

$ free
         total       used       free     shared    buffers     cached
Mem:       2064396    1005104    1059292          0      41840      48124
-/+ buffers/cache:     915140    1149256
Swap:      3145720      39132    3106588

Nota, o host no qual eu fiz isso é fortemente usado. Isso será mais significativo em uma máquina realmente silenciosa.


11
-1 se eu pudesse. Isso é (A) irrelevante para a pergunta e (B) uma maneira terrivelmente violenta de acionar a limpeza do cache. Existem formas diretas para fazer o último, por isso não é defensável para enganar o sistema em conformidade por meio de spam-lo com dados até que ele libera como um efeito colateral
underscore_d

Oh meu Deus! Por favor, nunca faça isso em servidores reais!
precisa saber é o seguinte

@Tamerlaha Eu concordo, mas por favor, releia o primeiro parágrafo: você está avisado, não me culpe ! O objetivo disso é mostrar a implicação de buffer / cache.
F. Hauri
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.