В Linux, в чем разница между «буферами» и «кешем», о которых сообщает команда free?

74

Это старый вопрос, который я видел время от времени. Мое понимание этого довольно ограничено (прочитав о различиях давным-давно, но фактоид (ы), вовлеченные никогда не застрял).

Как я понимаю,

  • Буферы

    Используются программами с активными операциями ввода-вывода, т.е. данными, ожидающими записи на диск

  • кэш

    Является результатом завершенных операций ввода-вывода, то есть буферов, которые были сброшены или данные считаны с диска для удовлетворения запроса.

Могу ли я получить четкое объяснение для потомков?

Эйвери Пэйн
источник
1
stackoverflow.com/questions/6345020/…
Сиро Сантилли 新疆 改造 中心 法轮功 六四 事件
Это больше похоже на метаданные, которые вы найдете в буферах, это не связано с буферами ввода-вывода. Некоторые из буферов ядра учитываются в распределителе slab, но вообще не учитываются в буферах или кэш-памяти.
eckes

Ответы:

42

«Кэшированный» итог также будет включать в себя некоторые другие выделения памяти, такие как любые файловые системы tmpfs. Чтобы увидеть это, попробуйте:

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

и вы увидите падение значения «кеша» на 100 Мбайт, которые вы скопировали в файловую систему на базе оперативной памяти (при условии, что было достаточно свободной оперативной памяти, вы можете обнаружить, что некоторые из них оказались в состоянии подкачки, если машина уже перегружена в терминах использования памяти). «Sync; echo 3> / proc / sys / vm / drop_caches» перед каждым вызовом free должен записывать что-либо ожидающее во всех буферах записи (sync) и очищать все блоки кэшированных / буферизованных дисков из памяти, так что free будет читать только другие выделения в «кэшированном» значении.

Оперативная память, используемая виртуальными машинами (например, работающими под VMWare), также может учитываться в свободном «кэшированном» значении, как и оперативная память, используемая в настоящее время открытыми отображенными в память файлами (это зависит от используемого вами гипервизора / версии и возможно, между версиями ядра тоже).

Так что это не так просто, как «подсчет буферов в ожидании файловых / сетевых записей и кэширование подсчета недавно прочитанных / записанных блоков, хранящихся в ОЗУ для сохранения будущих физических чтений», хотя для большинства целей подойдет это более простое описание.

Дэвид Спиллетт
источник
1
+1 за интересные нюансы. Это та информация, которую я ищу. На самом деле, я подозреваю, что цифры настолько запутаны, настолько вовлечены в столь много разных видов деятельности, что в лучшем случае они являются общими показателями.
Эйвери Пейн
Я не думаю, что оперативная память, используемая виртуальными машинами, считается "кэшированной", по крайней мере, для qemu-kvm. Я замечаю, что на моем хосте KVM значение кеша не только слишком мало, чтобы быть правильным (в 1,9 Гб), но оно не меняется, если я уничтожаю / запускаю одну из моих виртуальных машин. Это также не изменится, если я выполню трюк монтирования tmpfs на одной из виртуальных машин. Я создал раздел 800Meg tmpfs там, и «кэшированный» показал правильные значения на виртуальной машине, но он не изменился на хосте виртуальной машины. Но «использованное» значение уменьшилось / выросло, когда я уничтожил / запустил свою ВМ.
Майк С
... Я выполнил тесты на хосте Centos 7.2.1511 с ядром 3.10.0-327.
Майк С
@MikeS: то, как разные решения для виртуализации обрабатывают память, может различаться, в действительности, то, как ядро ​​измеряет различные варианты использования памяти, может изменяться между основными версиями.
Дэвид Спиллетт
@MikeS: Что касается «выполнить трюк монтирования tmpfs на одной из виртуальных машин» - я не повлию на показания хоста, если они не отображают другие mem, используемые виртуальной машиной. Я вижу эффект в самой виртуальной машине KVM: до dd free = 2020, после dd free = 1899, после drop fs free = 2001 (разница в 19 Мб будет из-за других процессов на виртуальной машине, она не была простаивала, когда я запускал тест). Хост может не увидеть изменения: память, вероятно, все еще выделена для ВМ, даже если она свободна для использования процессами в ВМ.
Дэвид Спиллетт
8

Каверзный вопрос. Когда вы вычисляете свободное пространство, вам действительно нужно добавить буфер и кешировать оба. Это то, что я мог найти

Буфер - это то, что еще не «записано» на диск. Кеш - это то, что было «прочитано» с диска и сохранено для последующего использования.

http://visualbasic.ittoolbox.com/documents/difference-between-buffer-and-cache-12135

Viky
источник
5

Я искал более четкое описание о буфере, и я нашел в "Professional Linux® Kernel Architecture 2008"

Глава 16. Кэш страницы и буфера

взаимодействие

Установка связи между страницами и буферами бесполезна, если для других частей ядра нет преимуществ. Как уже отмечалось, некоторые операции передачи на блочные устройства и с них могут потребоваться в блоках, размер которых зависит от размера блока базовых устройств, тогда как многие части ядра предпочитают выполнять операции ввода-вывода с гранулярностью страниц, так как это делает вещи намного проще - особенно с точки зрения управления памятью. В этом сценарии буферы действуют как посредники между двумя мирами.

c4f4t0r
источник
3

Объяснено RedHat :

Страницы кэша:

Кеш - это часть памяти, которая прозрачно хранит данные, чтобы в будущем запросы на эти данные могли обслуживаться быстрее. Эта память используется ядром для кэширования данных на диске и повышения производительности ввода-вывода.

Ядро Linux построено таким образом, что оно будет использовать как можно больше оперативной памяти для кэширования информации из ваших локальных и удаленных файловых систем и дисков. Поскольку время проходит через различные операции чтения и записи, выполняемые в системе, ядро ​​пытается сохранить данные, хранящиеся в памяти, для различных процессов, выполняющихся в системе, или данные соответствующих процессов, которые будут использоваться в ближайшем будущем. Кэш не восстанавливается в тот момент, когда процесс получает останов / выход, однако, когда другим процессам требуется больше памяти, чем свободной доступной памяти, ядро ​​запускает эвристику для восстановления памяти путем хранения данных кэша и выделения этой памяти новому процессу.

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

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

Сегменты разделяемой памяти SysV также учитываются как кеш, хотя они не представляют никаких данных на дисках. Проверить размер сегментов разделяемой памяти можно с помощью команды ipcs -m и проверки столбца байтов.

Буферы:

Буферы представляют собой блочные представления данных, которые хранятся в кешах страниц. Буферы содержат метаданные файлов / данных, которые находятся в кэше страницы. Пример: когда есть запрос любых данных, которые присутствуют в кэше страницы, сначала ядро ​​проверяет данные в буферах, которые содержат метаданные, которые указывают на фактические файлы / данные, содержащиеся в кэше страницы. Как только из метаданных известен фактический адрес блока файла, он берется ядром для обработки.

Иджаз Ахмад Хан
источник
2

Освобождение буфера / кеша

Предупреждение Это объясняет сильный метод, не рекомендуемый на производственном сервере! Так что вы предупреждены, не вините меня, если что-то пойдет не так.

Для понимания, вы могли бы заставить свою систему делегировать как можно больше памяти, чтобы cacheотбросить кэшированный файл:

преамбула

Перед выполнением теста вы можете открыть еще одно окно:

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

для последующей эволюции свопа в реальном времени.

Примечание: вы должны удалить столько свободного диска в текущем каталоге, у вас есть mem + swap

Демо
$ 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, хост, на котором я это сделал, сильно используется. Это будет более значительным на действительно тихой машине.

Ф. Хаури
источник
1
-1 если бы мог. Это (А) не имеет отношения к заданному вопросу и (Б) ужасно тупым способом запуска очистки кеша. Существуют прямые способы сделать последнее, поэтому нельзя оправдать, чтобы система подчинялась, рассылая данные с помощью спама, пока он не станет побочным эффектом
underscore_d
О, черт возьми! Пожалуйста, никогда не делайте этого на реальных серверах!
Тамерлаха
@ Тамерлаха Я согласен, но, пожалуйста, перечитайте первый абзац: вы предупреждены, не вините меня ! Цель этого - показать значение буфера / кэша.
Ф. Хаури