Il 30% della RAM è "buffer". Che cos'è?


12
$ 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

Come posso descrivere o spiegare "buffer" nell'output di free?

Non ho alcun problema (noto) con questo sistema. Sono solo sorpreso e curioso di vedere che "buffer" è quasi alto come "cache" (155 M contro 180 M). Pensavo che "cache" rappresentasse la cache della pagina del contenuto del file e tendesse ad essere la parte più significativa di "cache / buffer". Sono meno chiaro a cosa servano i "buffer".

Ad esempio, ho confrontato questo con il mio laptop, che ha più RAM. Sul mio laptop la figura "buffer" è un ordine di grandezza inferiore a "cache" (200 M contro 4G). Se avessi una corretta comprensione di cosa fossero i "buffer", allora potrei iniziare a chiedermi perché i buffer potrebbero crescere in una proporzione così grande sul sistema più piccolo.

man proc (Ignoro la definizione esilarantemente datata di "grande"):

Buffer% lu

Archiviazione relativamente temporanea per blocchi di dischi grezzi che non dovrebbero diventare tremendamente grandi (circa 20 MB).

% Lu memorizzato nella cache

Cache in memoria per i file letti dal disco (la cache della pagina). Non 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           

Risposte:


13
  1. Qual è la differenza tra "buffer" e l'altra cache?
  2. Perché vediamo questa distinzione in modo così evidente? (Possibile ragione storica)
  3. A cosa Buffersservono?
  4. Perché potremmo aspettarci Buffersin particolare di essere più o meno grandi?

1. Qual è la differenza tra "buffer" e l'altro tipo di cache?

Buffersriporta la quantità di cache di pagina utilizzata per i dispositivi a blocchi. Il kernel deve sottrarre deliberatamente questo importo dal resto della cache della pagina quando segnala Cached.

Vedi meminfo_proc_show () :

cached = global_node_page_state(NR_FILE_PAGES) -
         total_swapcache_pages() - i.bufferram;
...

show_val_kb(m, "MemTotal:       ", i.totalram);
show_val_kb(m, "MemFree:        ", i.freeram);
show_val_kb(m, "MemAvailable:   ", available);
show_val_kb(m, "Buffers:        ", i.bufferram);
show_val_kb(m, "Cached:         ", cached);

2. Perché vediamo questa distinzione in modo così evidente? (Possibile ragione storica)

La cache della pagina funziona in unità della dimensione della pagina MMU, in genere un minimo di 4096 byte. Questo è essenziale per l' mmap()accesso ai file mappato in memoria. [1] [2] Viene utilizzato per condividere pagine del codice di libreria / programma caricato tra processi indipendenti e consentire il caricamento di singole pagine su richiesta. (Anche per scaricare pagine quando qualcos'altro ha bisogno di spazio e non sono state utilizzate di recente).

[1] I / O mappati in memoria - Il manuale della libreria GNU C.
[2] mmap- Wikipedia.

I primi UNIX avevano una "cache buffer" di blocchi del disco e non avevano mmap (). Apparentemente quando mmap () è stato aggiunto per la prima volta, hanno semplicemente bloccato la cache della pagina in cima alla cache del buffer. Questo è disordinato come sembra. Alla fine, il sistema operativo basato su UNIX si è sbarazzato della cache del buffer. Quindi ora tutta la cache dei file è in unità di pagine. Le pagine vengono cercate per (file, offset), non per posizione sul disco. Questo è stato chiamato "cache buffer unificata", forse perché le persone avevano più familiarità con "cache buffer". [3]

[3] UBC: un efficiente sottosistema unificato di I / O e memorizzazione nella cache di memoria per NetBSD

"Una svolta interessante che Linux aggiunge è che i numeri di blocco del dispositivo in cui una pagina è memorizzata su disco sono memorizzati nella cache con la pagina sotto forma di un elenco di buffer_headstrutture. Quando una pagina modificata deve essere riscritta su disco, l'I / O le richieste possono essere inviate immediatamente al driver del dispositivo, senza la necessità di leggere alcun blocco indiretto per determinare dove devono essere scritti i dati della pagina. "[3]

In Linux 2.2 c'era una "cache buffer" separata usata per le scritture, ma non per le letture. "La cache della pagina ha utilizzato la cache del buffer per riscrivere i suoi dati, necessitando di una copia aggiuntiva dei dati e raddoppiando i requisiti di memoria per alcuni carichi di scrittura" (?). [4] Non preoccupiamoci troppo dei dettagli, ma questa storia sarebbe uno dei motivi per cui Linux ne segnala l' Buffersutilizzo separatamente.

[4] Sostituzione della pagina nella gestione della memoria di Linux 2.4 , Rik van Riel.

Al contrario, in Linux 2.4 e versioni successive, la copia aggiuntiva non esiste. "Il sistema esegue l'IO del disco direttamente da e verso la pagina della cache della pagina." [4] Linux 2.4 è stato rilasciato nel 2001.

3. A cosa Buffersservono?

I dispositivi a blocchi sono trattati come file e quindi hanno cache della pagina. Viene utilizzato "per i metadati del filesystem e la memorizzazione nella cache di dispositivi a blocchi grezzi". [4] Ma nelle attuali versioni di Linux, i filesystem non copiano il contenuto dei file attraverso di esso, quindi non c'è "doppia memorizzazione nella cache".

Penso alla Buffersparte della cache della pagina come alla cache del buffer Linux. Sebbene alcune fonti potrebbero non essere d'accordo con questa terminologia.

La quantità di cache buffer utilizzata dal filesystem, se presente, dipende dai dettagli del file system specifico. Il sistema nella domanda utilizza ext4. ext3 / ext4 utilizzano la cache del buffer Linux per il journal, per i contenuti della directory e alcuni altri metadati.

Alcuni file system, inclusi ext3, ext4 e ocfs2, utilizzano il layer jbd o jbd2 per gestire il journaling dei blocchi fisici e questo layer utilizza fondamentalmente la cache del buffer.

- Articolo di posta elettronica di Ted Tso , 2013

Prima della versione 2.4 del kernel di Linux, Linux aveva cache di pagina e buffer separate. Dalla versione 2.4, la cache della pagina e del buffer sono unificate e Bufferssono blocchi di dischi grezzi non rappresentati nella cache della pagina, ovvero non dati di file.

...

La cache del buffer rimane, tuttavia, poiché il kernel deve ancora eseguire l'I / O dei blocchi in termini di blocchi, non di pagine. Poiché la maggior parte dei blocchi rappresenta i dati dei file, la maggior parte della cache del buffer è rappresentata dalla cache della pagina. Ma una piccola quantità di dati di blocco non è supportata da file, ad esempio metadati e I / O a blocchi non elaborati, e quindi è rappresentata esclusivamente dalla cache del buffer.

- Una coppia di risposte Quora di Robert Love , ultimo aggiornamento 2013.

Entrambi gli autori sono sviluppatori Linux che hanno lavorato con la gestione della memoria del kernel Linux. La prima fonte è più specifica sui dettagli tecnici. La seconda fonte è un riassunto più generale, che potrebbe essere contraddetto e obsoleto in alcuni dettagli.

È vero che i filesystem possono eseguire scritture di metadati a pagina parziale, anche se la cache è indicizzata in pagine. Anche i processi utente possono eseguire scritture di pagine parziali quando usano write()(al contrario di mmap()), almeno direttamente su un dispositivo a blocchi. Questo vale solo per le scritture, non per le letture. Quando leggi la cache delle pagine, la cache delle pagine legge sempre le pagine intere.

A Linus piaceva affermare che la cache del buffer non è necessaria per eseguire scritture di dimensioni a blocchi e che i filesystem possono eseguire scritture di metadati a pagina parziale anche con cache di pagina collegata ai propri file anziché al dispositivo a blocchi. Sono sicuro che abbia ragione a dire che ext2 fa questo. ext3 / ext4 con il suo sistema di journaling no. È meno chiaro quali siano stati i problemi che hanno portato a questo progetto. Le persone a cui stava sfidando si stancarono di spiegare.

ext4_readdir () non è stato modificato per soddisfare il rant di Linus. Non vedo neanche il suo approccio desiderato usato in readdir () di altri filesystem. Penso che XFS usi anche la cache buffer per le directory. bcachefs non utilizza affatto la cache della pagina per readdir (); utilizza la propria cache per i btrees. Potrebbe mancare qualcosa in btrfs.

4. Perché potremmo aspettarci Buffersin particolare di essere più o meno grandi?

In questo caso risulta che la dimensione del journal ext4 per il mio filesystem è 128M. Quindi questo spiega perché 1) la mia cache buffer può stabilizzarsi a poco più di 128M; 2) la cache buffer non si ridimensiona proporzionalmente con la maggiore quantità di RAM sul mio laptop.

Per alcune altre possibili cause, vedi Qual è la colonna buffer nell'output da libero? Si noti che i "buffer" segnalati in freerealtà sono una combinazione di Bufferse memoria della lastra recuperabile.


Per verificare che le scritture di diario utilizzino la cache del buffer, ho simulato un filesystem in una RAM veloce (tmpfs) e ho confrontato l'utilizzo massimo del buffer per diverse dimensioni del diario.

# 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

Storia di questa risposta: come sono arrivato a guardare il diario

Avevo trovato e-mail di Ted Tso prima, ed è stato incuriosito che ha sottolineato write cache. Troverei sorprendente se i dati "sporchi" e non scritti fossero in grado di raggiungere il 30% di RAM sul mio sistema. sudo atopmostra che in un intervallo di 10 secondi, il sistema in questione scrive costantemente solo 1 MB. Il filesystem in questione sarebbe in grado di tenere il passo con oltre 100 volte questa velocità. (È su un disco rigido USB2, capacità massima ~ 20 MB / s).

L'uso di blktrace ( btrace -w 10 /dev/sda) conferma che gli IO che vengono memorizzati nella cache devono essere scritti, poiché quasi non vengono letti dati. Inoltre questo mysqldè l'unico processo di userspace che esegue IO.

Ho interrotto il servizio responsabile delle scritture (icinga2 scrivendo a mysql) e ricontrollato. Ho visto "buffer" scendere a meno di 20M - non ho spiegazioni per questo - e rimanere lì. Riavviando nuovamente il writer, i "buffer" aumentano di ~ 0,1 M per ogni intervallo di 10 secondi. Ho osservato che mantiene questo ritmo costantemente, risalendo a 70M e oltre.

La corsa echo 3 | sudo tee /proc/sys/vm/drop_cachesera sufficiente per abbassare nuovamente i "buffer", a 4,5M. Ciò dimostra che il mio accumulo di buffer è una cache "pulita", che Linux può rilasciare immediatamente quando richiesto. Questo sistema non sta accumulando dati non scritti . ( drop_cachesnon esegue alcun writeback e quindi non può eliminare le pagine sporche. Se si desidera eseguire un test che ha prima pulito la cache, si utilizzerà il synccomando).

L'intera directory mysql è solo 150M. I buffer di accumulo devono rappresentare blocchi di metadati dalle scritture mysql, ma mi ha sorpreso pensare che ci sarebbero così tanti blocchi di metadati per questi dati.


3

La tua versione di freeha l'idea giusta. Per impostazione predefinita, combina buffer e cache nel suo report. Questo perché sono sostanzialmente la stessa cosa. Sono entrambi i computer che ricordano nella RAM (più veloce di quello secondario: dischi e SSD), ciò che ha già visto durante la lettura di dischi e SSD.

Se il sistema operativo ritiene che la memoria sia utilizzata meglio da qualcos'altro, può liberarla. Pertanto non preoccuparti di buffer e cache.

Tuttavia, la visione di un DVD può far aumentare il buffer ed eliminare altri contenuti buffer / cache. Pertanto è possibile utilizzare nocache per eseguire il lettore DVD ( se sta causando un problema ).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.