Подробный гайд: Решение проблемы OOM в Linux: Swap как надежный буфер защиты памяти
Многие системные администраторы и разработчики считают Swap (файл подкачки) «злом» и стараются его отключить, но в реальности Swap — это критически важный буфер безопасности, который спасает серверы от хаотичного завершения процессов через OOM-killer.
Ниже представлен подробный гайд по настройке, тонкой настройке (tuning) и мониторингу Swap для предотвращения Out-Of-Memory (OOM) ситуаций.
1. Механика: Как Swap спасает от OOM-killer
Когда физическая RAM заполняется, ядру Linux нужно решить, куда деть новые данные. У него есть два пути:
- Сбросить файловый кэш (Page Cache): Освободить память, занятую кэшем дисковых операций.
- Сбросить анонимную память (Swap out): Переместить неактивные (cold) страницы памяти процессов на диск в Swap.
Если Swap не настроен или его не хватает, ядро переходит к крайним мерам: вызывает OOM-killer. Алгоритм OOM-killer оценивает каждый процесс (по oom_score) и безжалостно убивает тот, который потребляет больше всего памяти (часто это база данных или критичный микросервис), чтобы спасти ядро от паники.
Swap выступает буфером, давая системе время: он поглощает пиковые нагрузки, позволяя ядру вытеснить на диск то, что не используется прямо сейчас, и сохранить активные процессы живыми.
2. Шаг 1: Диагностика текущего состояния
Прежде чем что-то менять, нужно понять текущую ситуацию.
Выполните следующие команды:
# Посмотреть общее использование RAM и Swap
free -h
# Проверить, какие swap-разделы/файлы активны
swapon --show
# Проверить, были ли уже случаи срабатывания OOM-killer
dmesg -T | grep -i oom
3. Шаг 2: Создание и подключение Swap-файла
В современных реалиях swap-файл предпочтительнее swap-раздела, так как его размер можно легко изменить без переразметки диска. Допустим, нам нужно создать буфер размером 4 ГБ.
# 1. Создаем файл размером 4GB (используем fallocate для скорости)
sudo fallocate -l 4G /swapfile
# Если fallocate выдает ошибку (например, на некоторых файловых системах), используйте dd:
# sudo dd if=/dev/zero of=/swapfile bs=1M count=4096
# 2. Выставляем строгие права доступа (только root может читать/писать)
sudo chmod 600 /swapfile
# 3. Форматируем файл как swap
sudo mkswap /swapfile
# 4. Активируем swap
sudo swapon /swapfile
# 5. Добавляем в /etc/fstab для автоматического монтирования при загрузке
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
4. Шаг 3: Тонкая настройка (Tuning) — самое важное!
Просто создать Swap недостаточно. Нужно сказать ядру, как активно его использовать. За это отвечает параметр vm.swappiness.
Понимание vm.swappiness
Значение варьируется от 0 до 100 (по умолчанию обычно 60).
* 60 (Дефолт):
Ядро стремится использовать swap, даже если в RAM еще есть свободное место. Хорошо для десктопов, но плохо для серверов (вызывает лишние дисковые I/O).
* 10 (Рекомендуется для серверов/БД):
Ядро будет использовать swap только когда RAM заполнится почти полностью, выступая именно как буфер против OOM.
* 1 (Минимальное использование):
Swap будет использован только в самом крайнем случае, чтобы избежать OOM.
* 0 (Только для старых ядер < 3.5):
Полностью отключает swap. В современных ядрах 0 означает "избегать swap до последнего", но не отключает его полностью.
Как изменить:
# Проверить текущее значение
cat /proc/sys/vm/swappiness
# Изменить временно (до перезагрузки)
sudo sysctl vm.swappiness=10
# Сделать постоянно:
echo "vm.swappiness=10" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
Дополнительный параметр: vfs_cache_pressure
Этот параметр контролирует склонность ядра к вытеснению из кэша структур данных файловой системы (inode и dentry).
- По умолчанию:
100. - Если у вас сервер с огромным количеством мелких файлов (например, почтовик или веб-сервер), уменьшите значение до
50, чтобы ядро держало метаданные в RAM, а не сбрасывало их.
sudo sysctl vm.vfs_cache_pressure=50
echo "vm.vfs_cache_pressure=50" | sudo tee -a /etc/sysctl.conf
5. Шаг 4: Продвинутый уровень — Zram / Zswap
Если вы хотите выжать максимум из буферизации без сильного удара по дисковой подсистеме (особенно если диск — не самый быстрый NVMe), рассмотрите использование Zswap или Zram.
- Zswap — это легковесный сжатый кэш для swap-страниц. Вместо того чтобы сразу писать страницу на диск, ядро сжимает ее и кладет в динамически выделяемую память (RAM). На диск страница уйдет только если сжатый кэш переполнится. Это кратно снижает I/O и ускоряет работу.
- Zram — создает swap-раздел прямо в RAM, который сжимает данные на лету. Физический диск не используется вообще.
Включение Zswap (если поддерживается ядром):
echo 1 | sudo tee /sys/module/zswap/parameters/enabled
6. Шаг 5: Защита критичных процессов (Если Swap всё же заполнился)
Если утечка памяти настолько сильна, что она съедает и RAM, и Swap, OOM-killer всё равно сработает. Но мы можем защитить критичные процессы (например, sshd, чтобы не потерять доступ, или postgresql).
За это отвечает параметр oom_score_adj (от -1000 до 1000):
-1000— полностью запрещает убивать процесс через OOM-killer.1000— процесс будет убит первым.
Как защитить SSH:
# Находим PID sshd
pidof sshd
# Устанавливаем максимальную защиту
echo -1000 | sudo tee /proc/<PID>/oom_score_adj
Примечание:
Для перманентного эффекта это нужно прописывать в systemd-юнитах через параметр OOMScoreAdjust=-1000 в секции [Service].
7. Мониторинг и предотвращение
Чтобы Swap работал как буфер, а не как постоянная рабочая область, нужно мониторить его использование.
1. Базовый мониторинг в реальном времени:
vmstat 1
Смотрите на колонки si (swap in) и so (swap out). Если они постоянно не нулевые — системе хронически не хватает RAM, и Swap работает не как буфер, а как основная память (что убивает производительность).
2. Алертинг:
Настройте алерт в Prometheus/Grafana или Zabbix на заполнение Swap более чем на 20-30%. Это триггер для того, чтобы найти утечку памяти или добавить RAM.
Важно
- Всегда оставляйте небольшой Swap (хотя бы 1-2 ГБ) даже на серверах с 64+ ГБ RAM. Это спасет от случайных пиков и предотвратит падение критичных сервисов.
- Используйте
swappiness=10на продакшн-серверах. Это заставит Swap работать именно как аварийный буфер, а не как активная память. - Swap на SSD работает отлично, но следите за износом (TBW). Если пиковые нагрузки частые, лучше использовать Zram/Zswap.
- Помните: Swap не лечит утечки памяти (memory leaks). Он лишь откладивает момент смерти процесса, давая вам время заметить проблему и перезапустить сервис до того, как сработает OOM-killer.
Мы делимся этой технической информацией, чтобы помочь вам в решении задач — используйте её с пониманием. Статья носит рекомендательный характер, поэтому, пожалуйста, применяйте описанные методы осмотрительно.