30% оперативной памяти составляют «буферы». Что это?

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

Как я могу описать или объяснить "буферы" в выводе free?

У меня нет (известных) проблем с этой системой. Я только удивлен и любопытно видеть, что «буферы» почти так же высоки, как «кэш» (155M против 180M). Я думал, что «кеш» представляет собой кеш страниц содержимого файла и, как правило, является наиболее значимой частью «кеша / буферов». Мне менее понятно, для чего нужны «буферы».

Например, я сравнил это с моим ноутбуком, который имеет больше оперативной памяти. На моем ноутбуке число «буферов» на порядок меньше, чем «кэш» (200M против 4G). Если бы у меня было правильное понимание того, что такое «буферы», я мог бы начать спрашивать, почему буферы могут увеличиваться до такой большой пропорции в меньшей системе.

man proc (Я игнорирую смешно устаревшее определение «большой»):

Буферы% lu

Относительно временное хранилище для необработанных дисковых блоков, которые не должны быть очень большими (20 МБ или около того).

Кэшированный% lu

Кэш в памяти для файлов, читаемых с диска (кеш страниц). Не включает 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
источник
3
linuxatemyram.com полезно почитать
Василий Старынкевич

Ответы:

13
  1. В чем разница между «буфером» и другим кешем?
  2. Почему мы видим это различие так заметно? (Возможная историческая причина)
  3. Для чего Buffersиспользуются?
  4. Почему мы можем ожидать, Buffersв частности, быть больше или меньше?

1. В чем разница между «буфером» и кешем другого типа?

Buffersсообщает объем кеш страницы, используемый для блочных устройств. Ядро должно сознательно вычесть это количество из остальной части кэша страниц, когда оно сообщает Cached.

Смотрите 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. Почему мы видим это различие так заметно? (Возможная историческая причина)

Кэш страниц работает в единицах размера страницы MMU, обычно не менее 4096 байт. Это важно для mmap()доступа к файлу с отображением в памяти. [1] [2] Он используется для обмена страницами загруженного кода программы / библиотеки между независимыми процессами и позволяет загружать отдельные страницы по требованию. (Также для выгрузки страниц, когда кому-то еще нужно место, и они недавно не использовались).

[1] Отображение в памяти ввода-вывода - руководство по библиотеке GNU C.
[2] mmap- Википедия.

В ранних версиях UNIX был «буферный кеш» дисковых блоков и не было mmap (). Очевидно, когда mmap () был впервые добавлен, они просто запирали кэш страницы поверх кеша буфера. Это так грязно, как кажется. В конце концов ОС на базе UNIX избавилась от буферного кеша. Так что теперь весь файловый кеш находится в единицах страниц. Страницы ищутся по (файлу, смещению), а не по месту на диске. Это было названо «унифицированным буферным кешем», возможно, потому что люди были более знакомы с «буферным кешем». [3]

[3] UBC: эффективная подсистема ввода-вывода и кэширования памяти для NetBSD

«Один интересный поворот, который добавляет Linux, заключается в том, что номера блоков устройств, где страница хранится на диске, кэшируются вместе со страницей в форме списка buffer_headструктур. Когда измененная страница должна быть записана обратно на диск, ввод / вывод запросы могут быть отправлены драйверу устройства сразу, без необходимости считывания каких-либо косвенных блоков, чтобы определить, куда должны быть записаны данные страницы. "[3]

В Linux 2.2 был отдельный «буферный кеш», используемый для записи, но не для чтения. «Кэш страницы использовал буферный кэш для записи своих данных, нуждаясь в дополнительной копии данных, и удваивая требования к памяти для некоторых нагрузок записи» (?). [4] Давайте не будем сильно беспокоиться о деталях, но эта история будет одной из причин, почему Linux сообщает об Buffersиспользовании отдельно.

[4] Замена страницы в Linux 2.4, управление памятью , Рик ван Риэль.

Напротив, в Linux 2.4 и выше, дополнительная копия не существует. «Система выполняет дисковый ввод-вывод непосредственно со страницы кэша страниц». [4] Linux 2.4 был выпущен в 2001 году.

3. Для чего Buffersиспользуются?

Блочные устройства обрабатываются как файлы и поэтому имеют кеш страниц. Это используется «для метаданных файловой системы и кэширования необработанных блочных устройств». [4] Но в текущих версиях Linux файловые системы не копируют содержимое файла через него, поэтому «двойное кэширование» отсутствует.

Я думаю, что Buffersчасть кэша страниц является буферным кэшем Linux. Хотя некоторые источники могут не согласиться с этой терминологией.

Размер буферного кеша, который используется файловой системой, зависит от деталей конкретной файловой системы. Система, о которой идет речь, использует ext4. ext3 / ext4 используют буферный кеш Linux для журнала, для содержимого каталога и некоторых других метаданных.

Некоторые файловые системы, включая ext3, ext4 и ocfs2, используют уровень jbd или jbd2 для обработки журналирования своих физических блоков, и этот уровень в основном использует буферный кеш.

- Послать статью по Ted Цо , 2013

До версии 2.4 ядра Linux в Linux были отдельные кэши страниц и буферов. Начиная с версии 2.4, кэш страницы и буфера унифицирован и Buffersпредставляет собой необработанные дисковые блоки, которые не представлены в кеше страницы, т. Е. Не являются данными файла.

...

Однако буферный кэш остается, поскольку ядру все еще необходимо выполнять блок ввода-вывода в терминах блоков, а не страниц. Поскольку большинство блоков представляют данные файла, большая часть кэша буфера представлена ​​кэшем страницы. Но небольшой объем блочных данных не поддерживается файлом - например, метаданные и ввод-вывод необработанных блоков - и, таким образом, представлен исключительно буферным кешем.

- Пара ответов Quora от Роберта Лава , последнее обновление 2013 года.

Оба автора являются разработчиками Linux, которые работали с управлением памятью ядра Linux. Первый источник более конкретен о технических деталях. Второй источник - это более общее резюме, которое может противоречить и устареть в некоторых деталях.

Это правда, что файловые системы могут выполнять частичную запись метаданных страницы, даже если кэш индексируется по страницам. Даже пользовательские процессы могут выполнять частичную запись страниц, когда они используют write()(в отличие от mmap()), по крайней мере, напрямую на блочное устройство. Это относится только к записи, а не к чтению. Когда вы читаете кеш страниц, кеш страниц всегда читает полные страницы.

Линус любил разглагольствовать, что буферный кеш не требуется для выполнения записей размером с блок, и что файловые системы могут выполнять частичную запись метаданных страницы, даже если кеш страниц прикреплен к их собственным файлам вместо блочного устройства. Я уверен, что он прав, что ext2 делает это. ext3 / ext4 с его журналирующей системой нет. Менее понятно, какие проблемы привели к этому дизайну. Люди, на которых он разглагольствовал, устали объяснять.

ext4_readdir () не был изменен для удовлетворения разглагольствования Линуса. Я не вижу его желаемого подхода, используемого в readdir () других файловых систем. Я думаю, что XFS также использует буферный кеш для каталогов. bcachefs вообще не использует кеш страниц для readdir (); он использует свой собственный кеш для btrees. Я мог бы что-то упустить в btrfs.

4. Почему мы можем ожидать, Buffersв частности, быть больше или меньше?

В этом случае оказывается, что размер журнала ext4 для моей файловой системы составляет 128M. Это объясняет, почему 1) мой буферный кэш может стабилизироваться на уровне чуть более 128 МБ; 2) буферный кэш не масштабируется пропорционально большему объему оперативной памяти на моем ноутбуке.

Другие возможные причины см. В разделе « Что такое столбец буферов в выводе free»? Обратите внимание, что «буферы», о которых сообщается, на freeсамом деле являются комбинацией Buffersи восстанавливаемой памятью блоков.


Чтобы убедиться, что записи журнала используют буферный кэш, я смоделировал файловую систему в хорошей быстрой оперативной памяти (tmpfs) и сравнил максимальное использование буфера для журналов разных размеров.

# 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

История этого ответа: как я пришел посмотреть журнал

Сначала я нашел электронную почту Теда Цо, и был заинтригован тем, что она подчеркивает кэширование записи . Было бы удивительно, если бы «грязные» неписанные данные могли достигать 30% оперативной памяти в моей системе. sudo atopпоказывает, что в течение 10-секундного интервала рассматриваемая система последовательно записывает только 1 МБ. Соответствующая файловая система сможет поддерживать скорость более чем в 100 раз. (Это на жестком диске USB2, максимальная пропускная способность ~ 20 МБ / с).

Использование blktrace ( btrace -w 10 /dev/sda) подтверждает, что кэшируемые IO должны быть записаны, потому что данные почти не читаются. Кроме того, mysqldэто единственный процесс в пользовательском пространстве, который выполняет IO.

Я остановил службу, ответственную за запись (запись icinga2 в mysql) и перепроверил. Я видел, как «буферы» упали до 20M - у меня нет объяснений этому - и остаюсь там. При перезапуске устройства записи «буферы» увеличиваются на ~ 0.1M за каждые 10 секунд. Я наблюдал, как он постоянно поддерживает эту скорость, поднимаясь обратно до 70 м и выше.

Работы echo 3 | sudo tee /proc/sys/vm/drop_cachesбыло достаточно, чтобы снова снизить «буферы» до 4,5М. Это доказывает, что мое накопление буферов является «чистым» кешем, который Linux может немедленно удалить при необходимости. Эта система не накапливает неписанные данные. ( drop_cachesне выполняет обратной записи и, следовательно, не может удалить грязные страницы. Если вы хотите запустить тест, который сначала очистил кэш, вы должны использовать syncкоманду).

Весь каталог mysql только 150M. Накопительные буферы должны представлять блоки метаданных из записей mysql, но меня удивило, что для этих данных будет так много блоков метаданных.

sourcejedi
источник
3

Ваша версия freeимеет правильную идею. По умолчанию он объединяет буферы и кеш в своем отчете. Это потому, что они в основном одно и то же. Они оба запоминают в оперативной памяти (быстрее, чем вторичное хранилище: диски и SSD) то, что он уже видел при чтении дисков и SSD.

Если операционная система чувствует, что память лучше используется чем-то другим, она может освободить ее. Поэтому не беспокойтесь о буфере и кеше.

Однако просмотр DVD может привести к увеличению буфера и исключению другого содержимого буфера / кэша. Поэтому вы можете использовать nocache для запуска проигрывателя DVD ( если это вызывает проблемы ).

Ctrl-Alt-Делор
источник