30% de la RAM est constituée de «tampons». Qu'Est-ce que c'est?

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

Comment décrire ou expliquer les "tampons" dans la sortie de free?

Je n'ai aucun problème (connu) avec ce système. Je suis seulement surpris et curieux de voir que les "tampons" sont presque aussi élevés que les "cache" (155M contre 180M). Je pensais que "cache" représentait la page cache du contenu du fichier, et a tendance à être la partie la plus importante de "cache / buffers". Je ne sais pas trop à quoi servent les "tampons".

Par exemple, j'ai comparé cela à mon ordinateur portable, qui a plus de RAM. Sur mon ordinateur portable, le chiffre des "tampons" est d'un ordre de grandeur inférieur à celui du "cache" (200M vs 4G). Si j'avais une bonne compréhension de ce qu'étaient des "tampons", je pourrais alors commencer à demander pourquoi les tampons pourraient atteindre une proportion plus grande sur le plus petit système.

man proc (J'ignore la définition hilarante et obsolète de "grand"):

Tampons% lu

Stockage relativement temporaire pour les blocs de disque bruts qui ne devraient pas devenir extrêmement volumineux (environ 20 Mo).

% Lu en cache

Cache en mémoire pour les fichiers lus sur le disque (le cache de page). N'inclut pas 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           
sourcejedi
la source
3
linuxatemyram.com est utile à lire
Basile Starynkevitch

Réponses:

14
  1. Quelle est la différence entre "buffer" et l'autre cache?
  2. Pourquoi voyons-nous cette distinction si en évidence? (Raison historique possible)
  3. À quoi Buffersservent-ils?
  4. Pourquoi pourrait-on s'attendre Buffersen particulier à être plus grand ou plus petit?

1. Quelle est la différence entre "buffer" et l'autre type de cache?

Bufferssignale la quantité de cache de pages utilisée pour les périphériques bloqués. Le noyau doit délibérément soustraire ce montant du reste du cache de pages lors de son rapport Cached.

Voir 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. Pourquoi voyons-nous cette distinction si en évidence? (Raison historique possible)

Le cache de pages fonctionne en unités de la taille de page MMU, généralement un minimum de 4096 octets. Ceci est essentiel pour mmap(), c'est-à-dire l'accès aux fichiers mappés en mémoire. [1] [2] Il est utilisé pour partager des pages de code de programme / bibliothèque chargé entre des processus indépendants et permet de charger des pages individuelles à la demande. (Également pour décharger des pages lorsque quelque chose d'autre a besoin d'espace et qu'elles n'ont pas été utilisées récemment).

[1] E / S mappées en mémoire - Le manuel de la bibliothèque GNU C.
[2] mmap- Wikipédia.

Au début UNIX avait un "cache tampon" de blocs de disque et n'avait pas mmap (). Apparemment, lorsque mmap () a été ajouté pour la première fois, ils ont simplement boulonné le cache de page au-dessus du cache de tampon. C'est aussi désordonné que cela puisse paraître. Finalement, les systèmes d'exploitation basés sur UNIX se sont débarrassés du cache de tampon. Alors maintenant, tout le cache de fichiers est en unités de pages. Les pages sont recherchées par (fichier, décalage), et non par emplacement sur le disque. Cela s'appelait "cache tampon unifié", peut-être parce que les gens connaissaient mieux le "cache tampon". [3]

[3] UBC: un sous-système d'E / S unifiées et de mise en cache mémoire efficace pour NetBSD

"Une torsion intéressante que Linux ajoute est que les numéros de bloc de périphérique où une page est stockée sur le disque sont mis en cache avec la page sous la forme d'une liste de buffer_headstructures. Lorsqu'une page modifiée doit être réécrite sur le disque, les E / S les demandes peuvent être envoyées immédiatement au pilote de périphérique, sans avoir à lire de bloc indirect pour déterminer où les données de la page doivent être écrites. "[3]

Sous Linux 2.2, il y avait un "cache tampon" séparé utilisé pour les écritures, mais pas pour les lectures. "Le cache de pages a utilisé le cache tampon pour réécrire ses données, nécessitant une copie supplémentaire des données et doublant les besoins en mémoire pour certaines charges d'écriture" (?). [4] Ne nous inquiétons pas trop des détails, mais cet historique serait l'une des raisons pour lesquelles Linux rapporte l' Buffersutilisation séparément.

[4] Remplacement de la page dans la gestion de la mémoire Linux 2.4 , Rik van Riel.

En revanche, sous Linux 2.4 et supérieur, la copie supplémentaire n'existe pas. «Le système effectue des E / S de disque directement vers et depuis la page de cache de pages.» [4] Linux 2.4 a été publié en 2001.

3. À quoi Buffersservent-ils?

Les périphériques bloqués sont traités comme des fichiers, tout comme le cache de pages. Ceci est utilisé "pour les métadonnées du système de fichiers et la mise en cache des périphériques de bloc brut". [4] Mais dans les versions actuelles de Linux, les systèmes de fichiers ne copient pas le contenu des fichiers à travers celui-ci, il n'y a donc pas de "double mise en cache".

Je pense que la Bufferspartie du cache de page est le cache de tampon Linux. Bien que certaines sources puissent être en désaccord avec cette terminologie.

La quantité de mémoire tampon utilisée par le système de fichiers, le cas échéant, dépend des détails du système de fichiers spécifique. Le système dans la question utilise ext4. ext3 / ext4 utilise le cache de tampon Linux pour le journal, le contenu du répertoire et d'autres métadonnées.

Certains systèmes de fichiers, y compris ext3, ext4 et ocfs2, utilisent la couche jbd ou jbd2 pour gérer leur journalisation de bloc physique, et cette couche utilise fondamentalement le cache de tampon.

- Article par courrier électronique de Ted Tso , 2013

Avant la version 2.4 du noyau Linux, Linux avait des caches de pages et de tampons séparés. Depuis 2.4, la page et le cache de tampon sont unifiés et Bufferssont des blocs de disque bruts non représentés dans le cache de page, c'est-à-dire pas des données de fichier.

...

Le cache de tampon reste cependant, car le noyau doit encore effectuer des E / S de bloc en termes de blocs, pas de pages. Comme la plupart des blocs représentent des données de fichier, la majeure partie du cache de tampon est représentée par le cache de page. Mais une petite quantité de données de bloc n'est pas sauvegardée sur fichier - métadonnées et E / S de bloc brutes par exemple - et est donc uniquement représentée par le cache de tampon.

- Une paire de réponses Quora par Robert Love , dernière mise à jour 2013.

Les deux auteurs sont des développeurs Linux qui ont travaillé avec la gestion de la mémoire du noyau Linux. La première source est plus spécifique sur les détails techniques. La deuxième source est un résumé plus général, qui pourrait être contredit et obsolète dans certains détails.

Il est vrai que les systèmes de fichiers peuvent effectuer des écritures de métadonnées de page partielle, même si le cache est indexé en pages. Même les processus utilisateur peuvent effectuer des écritures de page partielle lorsqu'ils utilisent write()(par opposition à mmap()), au moins directement sur un périphérique de bloc. Cela ne s'applique qu'aux écritures, pas aux lectures. Lorsque vous lisez le cache de pages, le cache de pages lit toujours les pages complètes.

Linus aimait à dire que le cache de tampon n'est pas nécessaire pour effectuer des écritures de taille bloc et que les systèmes de fichiers peuvent effectuer des écritures de métadonnées de page partielle même avec un cache de page attaché à leurs propres fichiers au lieu du périphérique de bloc. Je suis sûr qu'il a raison de dire que ext2 fait cela. ext3 / ext4 avec son système de journalisation ne fonctionne pas. Il est moins clair quels étaient les problèmes qui ont conduit à cette conception. Les gens contre lesquels il se moquait étaient fatigués d'expliquer.

ext4_readdir () n'a pas été modifié pour satisfaire la diatribe de Linus. Je ne vois pas non plus son approche souhaitée utilisée dans readdir () d'autres systèmes de fichiers. Je pense que XFS utilise également le cache tampon pour les répertoires. bcachefs n'utilise pas du tout le cache de page pour readdir (); il utilise son propre cache pour btrees. Il se peut que je manque quelque chose dans btrfs.

4. Pourquoi pourrait-on s'attendre Buffersen particulier à être plus ou moins grand?

Dans ce cas, il s'avère que la taille du journal ext4 pour mon système de fichiers est de 128 Mo. Cela explique donc pourquoi 1) mon cache tampon peut se stabiliser à un peu plus de 128 Mo; 2) le cache tampon ne s'adapte pas proportionnellement à la plus grande quantité de RAM de mon ordinateur portable.

Pour d'autres causes possibles, voir Quelle est la colonne des tampons dans la sortie de free? Notez que les «tampons» signalés par freeest en fait une combinaison de Buffersmémoire de dalle récupérable.


Pour vérifier que les écritures de journal utilisent le cache de tampon, j'ai simulé un système de fichiers dans une belle RAM rapide (tmpfs) et comparé l'utilisation maximale du tampon pour différentes tailles de 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

Historique de cette réponse: comment j'en suis venu à regarder le journal

J'avais d'abord trouvé l'e-mail de Ted Tso et j'étais intrigué qu'il mettait l'accent sur la mise en cache de l' écriture . Je trouverais surprenant que des données "sales" et non écrites puissent atteindre 30% de RAM sur mon système. sudo atopmontre que sur un intervalle de 10 secondes, le système en question écrit de manière cohérente seulement 1 Mo. Le système de fichiers concerné pourrait suivre plus de 100 fois ce taux. (C'est sur un disque dur USB2, débit maximum ~ 20 Mo / s).

L'utilisation de blktrace ( btrace -w 10 /dev/sda) confirme que les E / S qui sont mises en cache doivent être des écritures, car il n'y a presque pas de données en cours de lecture. C'est également mysqldle seul processus de l' espace utilisateur à effectuer des E / S.

J'ai arrêté le service responsable des écritures (icinga2 écrit sur mysql) et j'ai revérifié. J'ai vu des "tampons" descendre à moins de 20M - je n'ai aucune explication à cela - et y rester. Le redémarrage de l'enregistreur montre à nouveau que les «tampons» augmentent de ~ 0,1 M pour chaque intervalle de 10 secondes. Je l'ai observé maintenir ce taux de manière constante, remontant à 70 millions et plus.

L'exécution a echo 3 | sudo tee /proc/sys/vm/drop_cachesété suffisante pour abaisser à nouveau les "tampons" à 4,5 millions. Cela prouve que mon accumulation de tampons est un cache "propre", que Linux peut supprimer immédiatement en cas de besoin. Ce système n'accumule pas de données non écrites . ( drop_cachesn'effectue aucune réécriture et ne peut donc pas supprimer les pages sales. Si vous vouliez exécuter un test qui nettoyait le cache en premier, vous utiliseriez la synccommande).

Le répertoire mysql entier ne fait que 150M. Les tampons accumulés doivent représenter des blocs de métadonnées des écritures mysql, mais cela m'a surpris de penser qu'il y aurait autant de blocs de métadonnées pour ces données.

sourcejedi
la source
3

Votre version de freea la bonne idée. Par défaut, il combine les tampons et le cache dans son rapport. C'est parce qu'ils sont fondamentalement la même chose. Ils sont tous deux l'ordinateur qui se souvient en RAM (plus rapide que le stockage secondaire: disques et SSD), ce qu'il a déjà vu lors de la lecture du disque et du SSD.

Si le système d'exploitation estime que la mémoire est mieux utilisée par autre chose, il peut la libérer. Par conséquent, ne vous inquiétez pas du tampon et du cache.

Cependant, regarder un DVD peut faire monter le tampon et expulser tout autre contenu de tampon / cache. Par conséquent, vous pouvez utiliser nocache pour exécuter le lecteur DVD ( si cela pose problème ).

ctrl-alt-delor
la source