Назад | Перейти на главную страницу

Использование очень высоких буферов ОЗУ после изменения размера / перезагрузки экземпляра

Вчера днем ​​мы изменили размер одного из наших экземпляров Linode (CentOS 5.7, 64-разрядная версия) с 4 ГБ до 12 ГБ. Сразу после перезагрузки я заметил, что использование памяти для буферов было безумно высокий - выше, чем я когда-либо видел на любой машине, которой я касался. Даже на моих наиболее часто используемых серверах я редко вижу, чтобы использование буфера превышало ~ 200 МБ. На этом сервере текущее использование буфера два порядка выше, чем раньше, мы изменили размер и перезагрузились.

Вот график памяти munin с данными до и после миграции:

Данные, отображаемые munin, подтверждаются выводом "free":

[erik@host ~]$ free -m
             total       used       free     shared    buffers     cached
Mem:         11967      10146       1820          0       7374       1132
-/+ buffers/cache:       1639      10327
Swap:          255          0        255

Теперь я хорошо осведомлен об использовании ядром неиспользуемой памяти для кеширования, но мое понимание буферов таково, что буферы разные. Они используются для временного хранения записей, пока они не будут зафиксированы на диске. Это правильное понимание? На этом сервере очень мало операций ввода-вывода диска (это веб-сервер apache / php, база данных находится в другом месте, поэтому только операции ввода-вывода по существу - это access_logs), и поэтому я бы ожидал, что использование буфера будет довольно низким.

Вот график сетевого трафика за тот же период времени:

Как видите, существенного изменения трафика до и после изменения размера нет.

Во время перезагрузки изменились три вещи, о которых я знаю:

  1. Мы взяли 4 дополнительных ядра, которые Linode выдал ранее на этой неделе, доведя общее количество ядер до 8.
  2. Мы работаем с «последним 64-битным» ядром, которое сейчас - 3.7.10-x86_64-linode30. Раньше мы, кажется, были на 3.0.18.
  3. Мы перешли с 4 ГБ ОЗУ на 12 ГБ.

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

У меня есть пара вопросов:

  1. Кто-нибудь из вас использует ядро ​​3.7.10, и если да, видели ли вы подобное изменение?
  2. Какие инструменты доступны для проверки буферов ядра и их размеров?
  3. Я предполагаю, что, как и кеш, ядро ​​освободит эту память, когда она понадобится другим приложениям. Это верно?

Чтобы прояснить этот момент:

[Буферы] используются для временного хранения записей, пока они не будут зафиксированы на диске. Это правильное понимание?

Нет, не так.

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

Если приложению необходимо выполнить запись в этот файл, тогда запись выполняется в файл в ОЗУ, что происходит быстро, и ядро ​​отмечает эти страницы памяти как «грязные». Что касается приложения, запись завершена, и приложение может вернуться к своим действиям.

В дальнейшем ядро ​​обрабатывает сброс грязных страниц на диск. Вы можете принудительно очистить все грязные страницы с помощью sync или вы увидите, что демоны очистки (pdflush или bdflush) время от времени просыпаются.

Вы можете в любой момент увидеть количество грязной памяти с помощью cat /proc/meminfo | grep Dirty.

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

Файловый кеш может быть освобожден, если процессы запрашивают дополнительные выделения виртуальной памяти. Сегменты общей памяти и tmpfs также сообщаются как «кеш», но их нельзя освободить, как файловый кеш.

Обычно «буферы» - это выделение памяти запущенными процессами. Посмотреть в top -a или подобное и посмотрите, какой процесс занимает большую часть ОЗУ.