VDS и Серверы 10 мин чтения 2026-09-04

OOM Killer убивает MySQL и Nginx: правильная настройка Swap и zRAM на VDS с 1–2 ГБ RAM

Что делать, если на недорогом VDS с 1–2 ГБ RAM база данных MySQL или веб-сервер Nginx внезапно падают с Out of Memory, а сервер зависает намертво? Разбираем настройку сверхбыстрого сжатия памяти zRAM, аварийного Swapfile и тюнинг ядра Linux.

Инженерная редакция SysKit Проверено инженерами SysKit.ru

Знакомая картина для каждого, кто держит сайты или сервисы на недорогом VDS с 1–2 ГБ оперативной памяти: в 3 часа ночи запускается плановый бэкап или приходит внезапный наплыв поисковых краулеров, память забивается под 100%, и ядро Linux без предупреждения прибивает процесс базы данных mysqld или воркеры PHP/Node.js. В браузерах клиентов загорается ошибка 502 Bad Gateway или Error establishing a database connection, а консоль SSH перестает отзываться.

⚠️ Типичная ошибка администратора:

Первое, что делает большинство вебмастеров в такой ситуации — наспех создает классический файл подкачки /swapfile на 2–4 ГБ командой fallocate. Но при реальном скачке нагрузки диск захлебывается в операциях ввода-вывода (I/O wait подскакивает до 80–95%), процессор уходит в непрерывный троттлинг, и сервер зависает намертво на десятки минут вместо спасительного сброса нагрузки.

1. Анатомия сбоя: как Linux OOM Killer выбирает жертвой MySQL или Nginx

Когда в системе физически заканчивается свободная оперативная память и ядро больше не может выделить ни одной страницы под буферы приложений, срабатывает защитный механизм ядра — Out of Memory (OOM) Killer. Его единственная задача — предотвратить полный крах всей операционной системы ценой мгновенного уничтожения одного из работающих процессов.

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

sudo dmesg -T | grep -E -i "oom|out of memory|killed process"

В логе ядра вы увидите красноречивые строки следующего вида:

[Fri Sep  4 03:14:22 2026] Out of memory: Killed process 14205 (mysqld) total-vm:1845220kB, anon-rss:921440kB, file-rss:0kB, shmem-rss:0kB, UID:112 pgtables:2104kB oom_score_adj:0

Как ядро выбирает «жертву»? Каждый процесс в Linux имеет специальный внутренний рейтинг — oom_score (число от 0 до 1000). Чем больше страниц оперативной памяти занимает процесс и чем меньше привилегий имеет его владелец, тем выше его балл. Именно поэтому MySQL / MariaDB, PostgreSQL, Java или PHP-FPM pool почти всегда оказываются на первой строчке расстрельного списка ядра — они держат в RAM кэши таблиц, пулы соединений и буферы сортировки.

2. Почему классический Swap на диске часто делает только хуже

Казалось бы, решение очевидно — включить подкачку на диск (Swap). Однако на серверах начального уровня (1–2 vCPU, 1–2 GB RAM) стандартный swapfile нередко превращается в мину замедленного действия:

  • Колоссальная разница в скорости: Даже самый быстрый NVMe-накопитель корпоративного класса с задержкой 50–100 мкс уступает шине оперативной памяти DDR4/DDR5 (задержка 50–70 нс) более чем в 1000 раз.
  • Катастрофический I/O Thrashing: Когда ядро пытается одновременно читать и писать сотни мегабайт сжатых страниц на диск, очередь ввода-вывода блокирует выполнение любых системных потоков. В этот момент vCPU занят не обработкой HTTP-запросов, а ожиданием ответа от дискового контроллера (параметр %iowait в утилите top).
  • Износ NVMe накопителя: Постоянные циклы записи и перезаписи страниц памяти в файл подкачки быстро вырабатывают ресурс TBW виртуального диска, из-за чего облачный провайдер может ограничить IOPS вашего тарифа.

3. Что такое zRAM: виртуальное сжатие памяти на лету без износа NVMe

zRAM — это встроенный модуль ядра Linux, который создает сжатое блочное устройство прямо в оперативной памяти сервера. Вместо того чтобы сбрасывать неактивные страницы RAM на медленный NVMe/SSD диск, ядро мгновенно сжимает их с помощью сверхбыстрых алгоритмов компрессии (ZSTD или LZ4) и сохраняет в специально выделенном сегменте той же самой оперативной памяти.

Критерий Классический Swap на диске Сжатая память zRAM
Скорость доступа 1–3 ГБ/с (NVMe) с высокой задержкой 15–40 ГБ/с (широкая шина RAM)
Влияние на I/O wait Вызывает скачок до 80–95% Строго 0% (диск вообще не задействуется)
Коэффициент сжатия 1:1 (страницы сохраняются как есть) 2.2:1 – 3.0:1 (в зависимости от данных)
Нагрузка на vCPU Минимальная (но CPU простаивает в I/O) 1–3% vCPU при сжатии и распаковке
Поведение при пиках Зависание сервера (Thrashing) Плавное обслуживание запросов

💡 Реальный эффект на VDS с 1 ГБ RAM:

При выделении 1 ГБ под устройство zRAM с алгоритмом ZSTD средний коэффициент сжатия текстовых структур баз данных и логов составляет около 2.5:1. Это означает, что в 400 МБ физической RAM вы можете уместить около 1 ГБ данных, высвободив ценную физическую память под активные буферы Nginx и MySQL без единого обращения к диску.

4. Пошаговая настройка zRAM на Ubuntu 24.04 и Debian 12

Для надежного управления устройствами zRAM в Debian-подобных дистрибутивах используется пакет zram-tools, который автоматически настраивает системный сервис под управлением systemd.

Шаг 4.1: Установка пакета

Обновите списки пакетов и установите утилиту:

sudo apt update && sudo apt install -y zram-tools

Шаг 4.2: Конфигурация параметров сжатия

Откройте файл конфигурации /etc/default/zramswap в вашем любимом редакторе:

sudo nano /etc/default/zramswap

Приведите конфигурационный файл к следующему выверенному виду:

# Включаем создание пула zRAM при загрузке
ALGO=zstd

# Процент от общего объема физической RAM, отдаваемый под пул сжатия.
# Для VDS 1–2 GB оптимально значение 75-100%
PERCENT=100

# Максимальный приоритет swap для zRAM (чтобы страницы шли сначала сюда, а не на диск)
PRIORITY=100

Пояснения по алгоритму:

  • ALGO=zstd — современный стандарт в ядрах Linux 6.x. Обеспечивает наивысший коэффициент сжатия при высокой скорости.
  • ALGO=lz4 — альтернатива для одноядерных VDS со слабым процессором (минимальная нагрузка на CPU, но чуть меньший процент сжатия).

Шаг 4.3: Перезапуск и проверка статуса

Перезапустите службу zramswap:

sudo systemctl restart zramswap
sudo systemctl enable zramswap

Проверьте активность сжатого устройства с помощью утилиты zramctl:

zramctl

Вывод должен выглядеть следующим образом:

NAME       ALGORITHM DISKSIZE  DATA COMPR TOTAL STREAMS MOUNTPOINT
/dev/zram0 zstd            1G    0B    0B    4K       1 [SWAP]

5. Создание аварийного Swapfile на NVMe со вторичным приоритетом

Почему одного zRAM может быть недостаточно? Если всплеск потребления памяти превысит объем zRAM, сервер снова окажется в ситуации OOM. Поэтому профессиональный подход заключается в двухуровневой архитектуре подкачки:

  1. Уровень 1 (Приоритет 100): Сжатый пул /dev/zram0 в памяти. Обслуживает 99% всех скачков.
  2. Уровень 2 (Приоритет 10): Классический файл /swapfile на NVMe-накопителе объемом 1–2 ГБ. Он выполняет роль «подушки безопасности» и используется ядром только тогда, когда zRAM заполнится полностью.

Создаем аварийный файл подкачки на 2 ГБ:

# Создаем файл заданного размера
sudo fallocate -l 2G /swapfile

# Выставляем строгие права безопасности (чтение только root)
sudo chmod 600 /swapfile

# Инициализируем пространство подкачки
sudo mkswap /swapfile

# Активируем swap с низким приоритетом (например, priority 10)
sudo swapon -p 10 /swapfile

Закрепляем аварийный swap в fstab:

Откройте /etc/fstab и добавьте строку с явным указанием приоритета pri=10:

echo "/swapfile none swap sw,pri=10 0 0" | sudo tee -a /etc/fstab

Теперь выполните команду swapon --show. Вы увидите идеальную многоуровневую структуру:

NAME       TYPE      SIZE USED PRIO
/dev/zram0 partition   1G   0B  100
/swapfile  file        2G   0B   10

💡 Как работает эта связка:

Ядро Linux всегда отправляет вытесняемые страницы в swap-устройство с наивысшим приоритетом (PRIO=100). Вся нагрузка ложится на мгновенный zRAM в оперативной памяти. Если же произойдет аномальная перегрузка, ядро не вызовет OOM Killer, а плавно начнет сбрасывать излишки на медленный NVMe (PRIO=10), сохранив доступность SSH и процессы баз данных.

6. Тонкий тюнинг ядра в sysctl.conf: swappiness, vfs_cache_pressure и watermark

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

Создайте файл пользовательских настроек ядра /etc/sysctl.d/99-zram-tuning.conf:

sudo nano /etc/sysctl.d/99-zram-tuning.conf

Вставьте следующие параметры с комментариями инженеров:

# 1. Агрессивное использование swap (для zRAM это выгодно, страницы мгновенно жмутся в RAM)
vm.swappiness = 100

# 2. Баланс между кэшированием inode/dentry файловой системы и памятью процессов
vm.vfs_cache_pressure = 50

# 3. Предотвращение резких всплесков при нехватке памяти (упреждающее освобождение страниц)
vm.watermark_boost_factor = 0
vm.watermark_scale_factor = 125

# 4. Защита от избыточного выделения виртуальной памяти без подтверждения
vm.overcommit_memory = 0

Примените параметры на лету без перезагрузки сервера:

sudo sysctl --system

7. Защита критических служб от OOM Killer через oom_score_adj и systemd

Даже при наличии zRAM и swapfile полезно застраховать ключевые службы сервера (например, SSH-сервер и MySQL) от аварийного уничтожения при пиковом потреблении памяти вспомогательными скриптами.

Параметр oom_score_adj принимает значения от -1000 (полный запрет убийства процесса) до +1000 (уничтожить в первую очередь). Значение -100 или -200 надежно убережет сервис от случайной ликвидации.

Защита службы SSH (sshd):

Чтобы вы никогда не потеряли доступ к серверу по SSH в момент нехватки памяти, создайте drop-in оверлей для systemd:

sudo systemctl edit ssh.service

Добавьте строки:

[Service]
OOMScoreAdjust=-500

Защита базы данных MySQL / MariaDB:

Аналогично защищаем демон MySQL:

sudo systemctl edit mysql.service
[Service]
OOMScoreAdjust=-200

Примените изменения в systemd:

sudo systemctl daemon-reload
sudo systemctl restart ssh mysql

8. Стресс-тестирование связки и мониторинг памяти

Никогда не оставляйте сервер на продакшене без предварительной проверки настроек. Протестируем поведение подсистемы памяти утилитой stress-ng:

# Устанавливаем стресс-утилиту
sudo apt install -y stress-ng

# Запускаем выделение 1.5 ГБ памяти на 30 секунд в реальном времени
stress-ng --vm 1 --vm-bytes 1500M --timeout 30s --metrics-brief

В соседнем окне терминала запустите мониторинг zramctl и free -h. Вы наглядно увидите, как:

  1. Устройство /dev/zram0 плавно заполняется сжатыми данными.
  2. Показатель COMPR в разы меньше реального объема данных DATA.
  3. SSH-сессия остается абсолютно отзывчивой, а в логах dmesg отсутствуют записи о вызове OOM Killer.

🎯 Готовая инфраструктура для стабильных проектов

Если проект вырос из базового тарифа с 1 ГБ RAM, а нагрузка базы данных продолжает расти, лучшим инженерным решением будет своевременный апгрейд на современный VDS с быстрыми ядрами AMD EPYC и NVMe-дисками корпоративного уровня.

Развернуть надежный VDS для продакшена →

Рекомендуемые VDS-провайдеры

Отказоустойчивые сервера с быстрыми NVMe и каналом до 1 Гбит/с

Мощные процессоры AMD EPYC и NVMe

Timeweb Cloud VDS

Сверхбыстрые NVMe диски до 3000 МБ/с, идеальны для запуска стеков с базами данных и zRAM. Почасовая оплата, мгновенные снапшоты и гибкое масштабирование RAM в 1 клик.

Конфигурация
от 1 vCPU / 2 GB RAM / 30 GB NVMe
Премиум каналы и надежность Tier III
🔷

Selectel Cloud VPS

Выделенные KVM-ресурсы с гарантированной частотой процессоров. Чистая изоляция ядер и честные лимиты без оверселлинга для продуктивных нагрузок.

Конфигурация
от 1 vCPU / 2 GB RAM / 25 GB NVMe
Автобэкапы и стабильность 24/7
🟠

Beget VPS

Простое управление, изолированные ресурсы KVM, бесплатные ежедневные бэкапы всего сервера и отзывчивая техническая поддержка сисадминов.

Конфигурация
от 1 vCPU / 2 GB RAM / 35 GB NVMe

Вопросы и ответы (FAQ)

Популярные вопросы вебмастеров и сисадминов по данной теме

Чем zRAM отличается от zswap и что лучше выбрать для недорогого VDS?
zRAM создает виртуальное блочное устройство swap прямо в оперативной памяти и не требует обязательного наличия файла подкачки на диске. zswap — это кэш сжатия перед физическим дисковым swap (он требует наличия swapfile на SSD/NVMe). Для VDS с 1–2 ГБ RAM связка zRAM (приоритет 100) + резервный swapfile (приоритет 10) проще в настройке, стабильнее работает в Ubuntu/Debian и гарантирует отсутствие деградации ввода-вывода диска.
Не приведет ли постоянное сжатие данных в zRAM к высокой нагрузке на процессор?
Нет. Современные алгоритмы компрессии ZSTD и LZ4 оптимизированы для минимальных затрат процессорного времени. В типичном веб-стеке (Nginx + PHP-FPM + MySQL) операции сжатия и распаковки занимают от 0.5% до 2% вычислительной мощности одного vCPU, что несоизмеримо меньше, чем 80-90% I/O wait при работе обычного медленного swapfile на диске.
Какой объем пула zRAM задать для сервера с 1 ГБ и 2 ГБ оперативной памяти?
Рекомендуется задавать PERCENT=100 (то есть 100% от размера физической памяти: 1 ГБ zRAM для сервера с 1 ГБ RAM и 2 ГБ zRAM для 2 ГБ RAM). Поскольку данные сжимаются со средним коэффициентом 2.2–2.5:1, фактически занятый объем физической памяти под сжатый пул составит около 400–450 МБ на каждый гигабайт сжатых данных.

Читайте также в блоге SysKit

Смежные руководства и полезные технические статьи