GNU/Linux >> Linux Esercitazione >  >> Linux

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

  1. Qual ​​è la differenza tra i "buffer" e l'altro tipo di cache?
  2. Perché questa distinzione è così importante? Perché alcune persone dicono "buffer cache" quando parlano di contenuti di file memorizzati nella cache?
  3. Cosa sono Buffers usato per?
  4. Perché potremmo aspettarci Buffers in particolare per essere più grande o più piccolo?

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

Buffers mostra la quantità di cache della pagina utilizzata per i dispositivi a blocchi. I "dispositivi a blocchi" sono il tipo più comune di dispositivi di memorizzazione dei dati.

Il kernel deve deliberatamente sottrarre questa quantità dal resto della cache della pagina quando riporta Cached . Vedere 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é questa distinzione è così importante? Perché alcune persone dicono "buffer cache" quando parlano di contenuti di file memorizzati nella cache?

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

[1] I/O mappato 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 aggiunto la cache della pagina come nuovo livello in cima. Questo è disordinato come sembra. Alla fine, i sistemi operativi basati su UNIX si sono sbarazzati della cache buffer separata. 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 la "cache buffer".[3]

[3] UBC:un efficiente sottosistema di I/O unificato e 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 vengono memorizzati nella cache con la pagina sotto forma di un elenco di buffer_head strutture. Quando una pagina modificata deve essere riscritta su disco, le richieste di I/O 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 cronologia sarebbe una delle ragioni per cui Linux riporta Buffers utilizzo 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 extra non esiste. "Il sistema esegue l'IO su disco direttamente da e verso la pagina della cache della pagina."[4] Linux 2.4 è stato rilasciato nel 2001.

3. Cosa sono Buffers usato per?

I dispositivi a blocchi sono trattati come file, così come la cache delle pagine. 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'è "doppio caching".

Penso al Buffers parte della cache della pagina come buffer cache di Linux. Alcune fonti potrebbero non essere d'accordo con questa terminologia.

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

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

-- Articolo via e-mail di Ted Tso, 2013

Prima della versione 2.4 del kernel Linux, Linux disponeva di pagine separate e buffer cache. Dalla versione 2.4, la pagina e la cache del buffer sono unificate e Buffers sono blocchi di disco non elaborati 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 a blocchi in termini di blocchi, non di pagine. Poiché la maggior parte dei blocchi rappresenta i dati del file, la maggior parte della cache del buffer è rappresentata dalla cache della pagina. Ma una piccola quantità di dati a blocchi non è supportata da file, ad esempio metadati e I/O a blocchi grezzi, e quindi è rappresentata esclusivamente dalla cache del buffer.

-- Un paio 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 sommario più generale, che potrebbe essere contraddetto e obsoleto in alcuni dettagli.

È vero che i filesystem possono eseguire scritture di metadati di pagine parziali, 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 a un dispositivo a blocchi. Questo vale solo per le scritture, non per le letture. Quando leggi la cache della pagina, la cache della pagina legge sempre pagine intere.

A Linus piaceva inveire sul fatto che la cache del buffer non è necessaria per eseguire scritture di dimensioni di blocco e che i filesystem possono eseguire scritture di metadati di pagine parziali anche con la cache delle pagine allegata ai propri file anziché al dispositivo a blocchi. Sono sicuro che ha ragione a dire che ext2 fa questo. ext3/ext4 con il suo sistema di journaling no. È meno chiaro quali fossero i problemi che hanno portato a questo progetto. Le persone con cui stava inveendo si sono stancate di dare spiegazioni.

ext4_readdir() non è stato modificato per soddisfare lo sproloquio di Linus. Non vedo nemmeno il suo approccio desiderato utilizzato in readdir() di altri filesystem. Penso che XFS utilizzi anche la cache del buffer per le directory. bcachefs non usa affatto la cache della pagina per readdir(); utilizza la propria cache per btrees. Non sono sicuro di btrfs.

4. Perché potremmo aspettarci Buffers in particolare per essere più grande o più piccolo?

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 del buffer non si ridimensiona proporzionalmente con la maggiore quantità di RAM sul mio laptop.

Per alcune altre possibili cause, vedere Qual è la colonna dei buffer nell'output da free? Nota che i "buffer" riportati da free è in realtà una combinazione di Buffers e memoria lastra del kernel recuperabile.

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

# 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 per primo l'e-mail di Ted Tso ed ero incuriosito dal fatto che enfatizzasse scrivi memorizzazione nella cache. Troverei sorprendente se "sporco", non scritto i dati sono stati in grado di raggiungere il 30% della RAM sul mio sistema. sudo atop mostra 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à. (Si trova su un disco rigido USB2, throughput massimo ~20 MB/s).

Usando blktrace (btrace -w 10 /dev/sda ) conferma che gli IO che vengono memorizzati nella cache devono essere scritti, perché non ci sono quasi dati da leggere. Anche quel mysqld è l'unico spazio utente processo che esegue IO.

Ho interrotto il servizio responsabile delle scritture (icinga2 scrivendo su mysql) e ho ricontrollato. Ho visto i "buffer" scendere a meno di 20 milioni - non ho spiegazioni per questo - e rimanere lì. Il riavvio dello scrittore mostra che i "buffer" aumentano di ~ 0,1 milioni per ogni intervallo di 10 secondi. Ho osservato che mantiene costantemente questo tasso, risalendo a 70 milioni e oltre.

Esecuzione di echo 3 | sudo tee /proc/sys/vm/drop_caches è stato sufficiente per abbassare nuovamente i "cuscinetti", a 4,5 milioni. Ciò dimostra che il mio accumulo di buffer è una cache "pulita", che Linux può rilasciare immediatamente quando richiesto. Questo sistema non sta accumulando non scritto dati. (drop_caches non esegue alcun writeback e quindi non può eliminare pagine sporche. Se volessi eseguire un test che pulisce prima la cache, dovresti usare sync comando).

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


La tua versione di free ha l'idea giusta. Per impostazione predefinita, combina buffer e cache nel suo rapporto. Questo perché sono fondamentalmente la stessa cosa. Sono entrambi il computer che ricorda nella RAM (più veloce della memoria secondaria: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. Quindi non preoccuparti di buffer e cache.

Tuttavia, la visione di un DVD può causare l'aumento del buffer e l'eliminazione di altri contenuti buffer/cache. Pertanto puoi utilizzare nocache per eseguire il lettore DVD (se sta causando un problema ).


Linux
  1. Cosa significano i numeri in una pagina uomo?

  2. Qual è il modo per conoscere le dimensioni della cache L1, L2, L3 e della RAM in Linux?

  3. Linux:come dare RAM alla cache del filesystem?

  4. Qual è la differenza tra memoria buffer e cache in Linux?

  5. Cosa sono la pagina mappata in memoria e la pagina anonima?

Che cos'è l'avvelenamento della cache DNS?

Come cancellare la cache di memoria RAM e il buffer e lo spazio di scambio su Linux

Gestore della cache per cPanel

Cosa succede quando un file che è stato impaginato al 100% nella cache della pagina viene modificato da un altro processo

Memorizzazione nella cache/precaricamento di file su Linux nella RAM

Significato della riga buffer/cache nell'output di free