У меня есть PostgreSQL-управляемый веб-сервис на двух серверах Debian, один - vhost с ядром Linux 3.2.0-2 с 2 ГБ ОЗУ, а другой - с выделенным сервером с ядром Linux 2.6.26-1 с 6 ГБ ОЗУ. Несмотря на то, что приложение занимает очень мало места в памяти, с течением времени кэш-память заполняется до определенного объема, при котором процессы выгружаются, увеличивая нагрузку на систему, в конце концов заканчивая нехваткой памяти и в конечном итоге сбой ядра (одинаковое поведение в обеих системах, только разные периоды времени). До сбоев free -m
сообщает что-то похожее на:
$ free -m
total used free shared buffers cached
Mem: 1978 1583 394 0 147 1208
-/+ buffers/cache: 227 1751
Если я перезагружаю систему, она работает в течение некоторого времени (часто недели или месяцы, но иногда только дни), пока кэш не будет снова заполнен. После перезагрузки бесплатный отчет free -m
:
$ free -m
total used free shared buffers cached
Mem: 1978 452 1526 0 6 302
-/+ buffers/cache: 143 1835
Для меня было бы приемлемо, если бы сервер несколько замедлялся из-за дискового ввода-вывода, если есть пики из-за чрезмерного использования, но недопустимо, чтобы система зависала тогда и когда, потому что кэш-память диска не используется процессами, если они временно нужно больше памяти.
Так что на одном сервере я вообще отключил подкачку (поскольку при перестановке нагрузка достигает 300–400 (в виде цепной реакции, если процессы прекращаются), делая систему непригодной даже для удаленного входа в систему, чтобы инициировать перезагрузку. Кроме того, я установил параметр настройки ядра vm.swappiness=0
и vm.overcommit_memory=2
как рекомендовано в руководстве по высокопроизводительной настройке PostgreSQL, чтобы заставить ядро освобождать память из кэша и избегать чрезмерной фиксации.
Но это, похоже, не дает желаемого эффекта - приведенный выше вывод free
не показывает сужающегося кэша вообще, в то время как программы снова начинают аварийно завершать работу при no memory available
сообщений об ошибке памяти (вышеприведенный вывод free
генерируется через несколько секунд после первого no memory available
сообщения появились в системном журнале после примерно двух месяцев бесперебойной работы).
Есть ли шанс избежать этого чрезмерного кэширования, чтобы иметь возможность использовать память для приложений, а не для дискового ввода-вывода?
Увеличение физической памяти не помогло, так как в системе с 6 ГБ я рано или поздно получаю те же результаты, когда к службе подключается больше клиентов (это сервер авторизации в точке доступа для свободного публичного использования с неизвестным количеством пользователей, и мне нужно придерживаться с двумя серверами на некоторое время по разным причинам). На виртуальном хосте я сначала использовал 1 ГБ, теперь 2 ГБ, что является пределом для моего виртуального хоста, и все, что я получил до сих пор, - это увеличение объема кэш-памяти, но не памяти для процессов. Так ли это должно работать на Linux? Всего 12% памяти на процессы? Или вышеупомянутые предложения из книги HPT неверны?
Заранее спасибо за любую подсказку!
Привет Майкл, да, кажется, так. Я также подумал, что кеш-память ядра должна быть освобождена, если приложениям пользователя требуется больше памяти. Но посмотрите на этот вывод free(1)
я иногда замечал, когда система снова перестала отвечать, что является признаком того, что ситуация приводит к тому, что убийца OOM рано или поздно получает предупреждение:
total used free shared buffers cached
Mem: 1978 981 997 0 142 638
-/+ buffers/cache: 200 1777
Swap: 0 0 0
Я могу видеть, как free Mem
уменьшается до нуля, в то время как -/+ buffers/cache
все еще показывает некоторое высокое значение, прежде чем системы в конечном итоге рухнут. Я немедленно очистил кеш, sync
и записав 3 в /proc/sys/vm/drop_caches
привело к освобождению памяти ядра:
total used free shared buffers cached
Mem: 1978 481 1496 0 1 283
-/+ buffers/cache: 196 1782
Swap: 0 0 0
Поэтому в качестве обходного пути я время от времени очищаю кеш вручную. К сожалению, я не могу просто обновить операционную систему в производственной системе, но мне приходится менять системы перед обновлениями, чтобы обеспечить доступность 99%. Тестирование ядер в нашей промежуточной системе возможно, но бесполезно, поскольку описанная ситуация появится только через некоторое время в нашей производственной системе, обслуживающей десятки тысяч запросов на вход в систему каждый день.
Кстати, это вывод free -m
на сегодня:
total used free shared buffers cached
Mem: 1978 1107 871 0 146 753
-/+ buffers/cache: 207 1771
Swap: 0 0 0
Если я правильно понимаю, приложения и ядро используют от 190 до 227 МБ, тогда как буферы и кэш-память занимают остальную часть памяти. Я уверен, что проблема не связана с каким-либо приложением, так как ничего не изменится, если я перезапущу приложения, но это помогает очистить кэш вручную.