Настройка Swap и OOM Killer для управления памятью

Сервис падает именно в пик нагрузки, когда память заканчивается за секунды. Мы настраиваем подкачку и управление памятью под ключ: разбираем профиль потребления, задаём пороги и передаём регламенты вашей команде. Аварийные перезапуски уходят, отклик остаётся предсказуемым.
Часто задаваемые вопросы

Настройка swap Linux: почему сервис падает при пике памяти

Аварийный перезапуск сервиса случается в разгар пиковой нагрузки на сервер, хотя мониторинг в этот же момент показывает свободную память. Это не ошибка графиков: нехватка оперативной памяти проявляется не в общем объёме, а в доступности страниц в нужной зоне и в способности ядра выделить непрерывный участок. В логах Linux это выглядит так: oom killer завершил процесс, а супервизор поднял его заново.

Жертву ядро выбирает по oom_score с поправкой oom_score_adj, и чаще всего ей становится основной рабочий процесс, а не тот, кто накопил утечку: у долгоживущего сервиса выше потребление — выше и шанс попасть под завершение. Перезапуск возвращает соединения, но теряет недописанные транзакции, а через несколько минут картина повторяется, если причину не устранили.

Настройка swap Linux в этой схеме — не «добавить медленной памяти», а выдать ядру буфер времени: выгрузить холодные страницы вместо немедленного завершения процесса на первом же пике. vm.swappiness определяет, насколько охотно вытесняются анонимные страницы, а лимиты cgroup и режим vm.overcommit_memory — кому и сколько вообще разрешено занять.

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

Эффект управляемой подкачки: отклик и стабильность

Эффект управляемой подкачки видно не по графику свободной памяти, а по числу инцидентов. После того как swap и политика реакции на нехватку памяти настроены под профиль нагрузки, сервис на пиках уходит в предсказуемую деградацию: часть операций замедляется, но процессы не гибнут и не тянут за собой соседние. Ниже — проверки, по которым мы принимаем работу.

  • Аварийные перезапуски. Число падений процессов по нехватке памяти падает на порядок: вместо десятков событий остаются единичные, и каждое разбирается как аномалия, а не как фон.
  • Предсказуемая деградация. Под пиком растёт время ответа, но очереди не рвутся: холодные страницы уходят в подкачку, горячий рабочий набор остаётся в памяти, отказ сервиса не наступает.
  • Ровный отклик на всплесках. Порог свободных страниц и агрессивность вытеснения выставлены под нагрузку, поэтому короткие bursts проходят без провалов — сервис замедляется плавно, а не обрывается.
  • Изоляция последствий. Лимиты памяти для групп процессов и ранний убийца по давлению на память разбираются только с проблемным сервисом; соседи на той же машине не теряют доступность.
  • Снятый класс инцидентов. Ночные подъёмы и страницы дежурного из-за падений по памяти уходят из потока — остаются задачи на плановое расширение, а не на тушение.
  • Быстрый возврат. После пика сервис входит в рабочий режим за десятки секунд, без повторного прогрева кэша и ручного вмешательства.

Каждый пункт проверяем на стенде с воспроизводимым профилем нагрузки: снимаем метрики до и после, сравниваем частоту перезапусков и поведение на пределе. Так эффект подкачки становится измеримым, а не декларативным.

Способы организации подкачки: сравнение и ограничения

Выбор носителя подкачки определяет не только доступный объём, но и время отклика в момент исчерпания памяти. Ядро опрашивает активные области подкачки в порядке убывания приоритета, поэтому swap-файл на быстром локальном накопителе и ёмкий раздел на медленном массиве спокойно сосуществуют: горячие страницы уходят на быстрый, холодные — на объёмный. Ошибка начинается там, где под подкачку отдают носитель, не рассчитанный на постоянную запись.

Вариант Когда подходит Ограничения
Swap-файл на локальном накопителе Быстро развернуть, изменить размер, добавить вторую область Требует свободного места в файловой системе, при изменении размера фрагментируется
Отдельный раздел подкачки Предсказуемая задержка, серверы без гибернации, СУБД Размер фиксируется при разметке, меняется только переразбивкой
Сжатая подкачка в оперативной памяти Малопамятные виртуальные машины, узлы без локального диска Тратит процессорные такты, не спасает при настоящем дефиците памяти, не переживает перезагрузку
Том на менеджере логических томов Нужно менять размер на ходу без остановки служб Дополнительный слой абстракции, снапшоты незаметно съедают место
Область на удалённом блочном устройстве Кластеры без локальных дисков, аварийный резерв Сетевая задержка делает её бесполезной под нагрузкой

Приоритет областей подкачки задаётся явно — в записи файловой системы или ключом при подключении, — иначе порядок заполнения окажется случайным. Подбор swappiness ведут по профилю нагрузки: для сервисов с большим файловым кэшем значение снижают, для виртуальных машин и тонких клиентов поднимают. Решение принимают не по вкусу, а по счётчикам промахов страничных отказов и данным о давлении на память — тогда подкачка закрывает пики, а не маскирует нехватку памяти.

Порядок работ: от аудита памяти до передачи регламентов

Начинаем не с правки конфигурации, а с фактов: без профиля потребления любая настройка параметров памяти превращается в угадывание. Такой порядок исключает типовой сценарий, когда подкачку включают «на всякий случай» и получают просадку отклика или внезапный перезапуск сервиса в час пик.

  1. Аудит потребления памяти. Снимаем метрики по процессам и группам: пиковое и среднее потребление, доля анонимных страниц, поведение в часы нагрузки. Отдельно смотрим, кто удерживает память после всплеска.
  2. Схема размещения подкачки. Определяем, нужен ли файл подкачки или отдельный раздел, на каком носителе и какого размера. Фиксируем, какие данные допустимо вытеснять, а какие обязаны оставаться в оперативной памяти.
  3. Настройка порогов и аварийного завершения. Задаём интенсивность вытеснения, лимиты для групп процессов и приоритеты, по которым ядро выбирает жертву при нехватке памяти. Явные приоритеты надёжнее автоматического выбора.
  4. Проверка под нагрузкой. Прогоняем сценарии с искусственным дефицитом памяти и смотрим результат: растёт ли задержка отклика, срабатывает ли аварийное завершение и какие процессы гибнут первыми.
  5. Наблюдаемость. Ставим оповещения на приближение к лимитам, на рост вытеснения и на факт аварийного завершения — инцидент становится виден до того, как упадёт сервис.
  6. Передача регламентов. Отдаём схему размещения подкачки, значения параметров с обоснованием, процедуру отката и чек-лист действий при резком росте потребления.

Комплект документов и конфигураций после внедрения

После внедрения у команды остаются не только рабочие настройки, но и документы, по которым их можно менять и передавать без нас. Ниже — перечень артефактов, которые заказчик получает вместе с результатом. Каждый рассчитан на дежурного инженера, который откроет его в момент инцидента, а не «когда-нибудь прочитаем».

  • Конфигурация подкачки — файл или раздел с записью в fstab, значения vm.swappiness, overcommit и cache_pressure, рядом комментарий: почему выбрано такое поведение и что изменится при возврате к значениям по умолчанию.
  • Политики по сервисам — лимиты памяти в cgroup и приоритеты oom_score_adj: кто получает шанс выжить под давлением, кого ядро освобождает первым.
  • Схема размещения — на каком узле и носителе лежит область подкачки, как она соотносится с томами данных и где узкие места по дисковым операциям.
  • Регламент дежурной смены — пошаговые действия при росте потребления памяти и срабатывании OOM Killer: что смотреть, что перезапускать, когда звать старшего инженера.
  • Документация по памяти — профиль потребления по сервисам, границы нормы, типовые причины роста и журнал изменений настроек.
  • Проверки и план отката — метрики, оповещения и команды диагностики в готовом виде плюс порядок возврата предыдущего профиля, если изменения ухудшили поведение сервиса.

Отдельно фиксируем владельцев: кто в вашей команде пересматривает лимиты при росте нагрузки и по каким признакам запускается пересмотр.

Кейс: устранение аварийных перезапусков при пиках

Сервис под нагрузкой вёл себя ровно, но в пиковые часы упирался в память. Ядро, не найдя свободных страниц, аварийно завершало самые тяжёлые процессы — вместе с ними уходил весь узел. Итог: семь инцидентов в месяц, каждый с ручным разбором; восстановление занимало до 45 минут, и часть запросов в это окно терялась.

Что изменили

Разделили два разных сценария — короткий всплеск и устойчивую нехватку памяти. Под всплески отвели область подкачки на отдельном томе: она даёт ядру запас, чтобы дождаться освобождения памяти, а не завершать процессы. Для контейнеров задали жёсткие лимиты и порядок завершения — первым уходит фоновый обработчик, фронтальный сервис остаётся в строю.

За потреблением следили через Prometheus: алерт на устойчивый рост настроен так, чтобы срабатывать раньше аварийного механизма. Это дало разбор причины до сбоя, а не после.

Изменения закрепляли тремя месяцами наблюдений. Сводка до и после:

Показатель До После
Аварийные перезапуски сервиса 7 в месяц 1 за квартал
Время восстановления сервиса до 45 минут вручную до 3 минут автоматически
Пики, поглощённые подкачкой не измерялись 9 из 10
Ночные вызовы дежурного 4–6 в месяц 0

Подкачка при этом не маскирует утечку: если потребление растёт линейно, приходит алерт, и причину разбирают до того, как закончится запас.

Чем swap-файл отличается от отдельного раздела?

С точки зрения ядра разницы почти нет: и файл, и раздел после инициализации становятся блочным устройством, которое подключается одной командой. Разница проявляется в том, как этот объём создаётся, меняется и переживает пересборку диска.

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

Файл подкачки живёт в существующей файловой системе. Его создают и подключают на ходу, размер меняют без остановки сервисов, а несколько файлов с разными приоритетами позволяют разложить нагрузку по разным дискам. Ограничения наследуются от файловой системы: на части сетевых и копирующих хранилищ такой файл не работает, а при гибернации требует ручного расчёта смещения.

На разметку это влияет напрямую: раздел отъедает место заранее и заставляет планировать схему при установке, файл оставляет разметку плоской и даёт подгонять объём подкачки под реальную нагрузку. Отсюда и выбор: физические серверы с гибернацией — раздел; виртуальные машины, хосты контейнеров и облако — файл, потому что менять разметку там дороже, чем убрать или добавить файл.

Частые вопросы по поведению системы при нехватке памяти

Перед стартом работ всплывают одни и те же сомнения: не начнёт ли сервис падать чаще, не просядет ли отклик, что изменится в контейнерах и можно ли обойтись без перезагрузки узла. Часть вопросов снимается на диагностике — по счётчикам убийств процессов, статистике vmstat и лимитам cgroup видно, что происходит сейчас и чем это грозит под нагрузкой.

Как понять, что сервис упал именно из-за памяти?

Запись в журнале ядра называет процесс-жертву и причину — исчерпание памяти узла или лимита группы. Если строки об убийстве нет, а процесс всё равно завершился, причину ищем в приложении: утечка, собственный ограничитель, ошибка в обработке пика. Разница принципиальна: в одном случае настраиваем ядро, в другом правим код.

Нужна ли подкачка, если оперативной памяти хватает?

Подкачка не ускоряет работу, но держит запас на пике: редко используемые страницы уходят на диск вместо запуска убийства процесса. Отключать её стоит только там, где важна предсказуемая задержка, — и тогда лимиты задаются жёстче, с явным резервом под пиковую нагрузку.

Не станет ли сервис работать медленнее?

Пока активные страницы остаются в памяти, отклик не меняется. Просадка начинается при активном вытеснении: её видно по полям ввода-вывода в vmstat и по росту времени ответа. Поэтому значение swappiness подбирают под профиль нагрузки, а не оставляют унаследованным.

Как это работает в контейнерах и применяется ли без перезагрузки?

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

Обсудим задачу и вернёмся с планом внедрения

Старт всегда одинаковый: сначала разбор ситуации, потом оценка и план внедрения, и только затем изменения на живых серверах. Мы не трогаем параметры памяти «по ощущениям» — сначала нужно увидеть, как swap и механизм аварийного завершения процессов ведут себя под вашей реальной нагрузкой. Для этого достаточно описания задачи и доступа к наблюдениям за системой, а не полного доступа к продакшену на первом шаге.

  • Разбор ситуации. Фиксируем, какие сервисы живут на хосте, какие у них пики потребления памяти и что уже происходило: были ли перезапуски, «замирания» под нагрузкой, внезапные падения процессов.
  • Сбор исходных данных. Смотрим текущие параметры подкачки, лимиты памяти для контейнеров и служб, историю срабатываний аварийного завершения процессов. Это отвечает на вопрос, где именно теряется память.
  • Оценка работ. Определяем объём изменений, порядок шагов, окна для правок и точки отката. Вы получаете оценку и план до того, как что-то поменяется на серверах.
  • План внедрения. Согласуем, какие пороги и приоритеты выставляем, какие процессы защищаем от завершения, как настраиваем аварийное освобождение памяти, чтобы оно било по нужной цели.
  • Внедрение и проверка. Меняем конфигурацию, прогоняем нагрузочный профиль и убеждаемся, что под пиком система не уходит в перезапуск. Результат — предсказуемое поведение вместо внезапных падений.
  • Передача. Отдаём конфигурации, схему принятых решений и метрики, по которым изменения видно на графиках.

Чтобы начать, опишите задачу: что за сервисы, какие симптомы беспокоят и что уже пробовали. Вернёмся с оценкой и планом внедрения — без обязательств запускать работы сразу.

Наши компетенции:

Последние работы

  • Разработка сайта компании B2B ADVANCE
    Разработка сайта компании B2B ADVANCE
    1542
  • Разработка веб-приложения для компании FEEDME
    Разработка веб-приложения для компании FEEDME
    1393
  • Разработка веб-сайта для компании БЕЛФИНГРУПП
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    1081
  • Разработка интернет магазина для компании FURNORO
    Разработка интернет магазина для компании FURNORO
    1368
  • Разработка логотипа компании B2B Advance
    Разработка логотипа компании B2B Advance
    815
  • Разработка веб-приложения для компании Enviok
    Разработка веб-приложения для компании Enviok
    1139