Top.Mail.Ru
OSEN-НИЙ SAAALEСкидка 50% на виртуальный хостинг и VDS
до 30.11.2025 Подробнее
Выберите продукт

Память на малом VDS без сюрпризов: swap, zram, vm.overcommit и OOM‑killer на практике

Малый VDS часто упирается в память: PHP‑FPM, базы, кэш и воркеры делят считанные гигабайты. Ошибка Killed в логах и зависания — признаки нехватки RAM и работы OOM‑killer. Разбираем практику: swap и zram, безопасный overcommit, swappiness, приоритеты и тестирование под нагрузкой.
Память на малом VDS без сюрпризов: swap, zram, vm.overcommit и OOM‑killer на практике

Когда на малом VDS внезапно «умирает» процесс, в системном журнале часто виден след: OOM‑killer. Это не баг, а защитный механизм ядра Linux: когда оперативная память заканчивается, ядро принудительно завершает наименее «ценный» процесс. Задача администратора — сделать так, чтобы до этого не доходило, а если уж дошло — выжил хотя бы SSH и критичные сервисы.

Как Linux использует память: короткий ликбез

В Linux RAM — не просто «свободно/занято». Значительную часть занимает кэш страниц (page cache) и кеши dentry/inode. Они выталкиваются первыми при росте нагрузки, поэтому «свободной» памяти может быть мало, но система работает стабильно. Нестабильность начинается, когда:

  • растут анонимные страницы (heap/stack процессов);
  • падает эффективность освобождения кэшей;
  • нет swap или он исчерпан;
  • жесткие лимиты (cgroups) срабатывают раньше, чем общая система.

Отсюда инструменты: swap (включая компрессированный zram), параметры sysctl (vm.overcommit_memory, vm.swappiness и другие), а также осознанная изоляция сервисов в cgroup через systemd. Если ваш проект на виртуальном хостинге уже упирается в RAM, рассмотрите переход на VDS — это даст контроль над ядром, swap и cgroup.

Swap: зачем, сколько и как

Swap — это страховка от кратковременных пиков. Он не заменяет RAM и не «ускоряет» сервер, но дает ядру пространство для «холодных» страниц, снижая шанс OOM. Для малых VDS практична связка: компрессированный zram как быстрый swap в памяти плюс небольшой swap‑файл на диске.

Базовый рецепт swap‑файла

sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
sudo swapon --show

Сделайте swap постоянным через /etc/fstab:

/swapfile none swap sw,pri=10 0 0

Рекомендации по размеру: на малом VDS (1–4 ГБ RAM) начните с 0.5–1× от RAM суммарно, учитывая zram (ниже), и смотрите по реальной нагрузке. Для баз данных и latency‑критичных систем держите swap умеренным и следите за I/O.

ZRAM: компрессированный swap в ОЗУ

zram создает блок‑устройство в оперативной памяти, где данные хранятся в сжатом виде. Сжатие (LZ4/ZSTD) даёт «виртуальное» увеличение доступной памяти при низких задержках. Типовой сценарий: zram со старшим приоритетом, дисковый swap с младшим.

Вариант 1: zram‑tools (Debian/Ubuntu)

sudo apt update
sudo apt install zram-tools

Отредактируйте /etc/default/zramswap (если файла нет, создайте):

ALGO=zstd
PERCENT=50
PRIORITY=100

Примените:

sudo systemctl enable zramswap --now
sudo zramctl
sudo swapon --show

PERCENT=50 означает «создать zram размером 50% от RAM». Для 2 ГБ RAM это ~1 ГБ сжатого swap, который фактически влезет в меньший объём за счёт компрессии.

Вариант 2: zram‑generator (RHEL/Fedora/новые дистрибутивы)

sudo dnf install zram-generator

Создайте /etc/systemd/zram-generator.conf:

[zram0]
zram-size = ram / 2
compression-algorithm = zstd
swap-priority = 100

Активируйте:

sudo systemctl daemon-reload
sudo systemctl restart systemd-zram-setup@zram0.service
sudo zramctl
sudo swapon --show

Одновременный zram и дисковый swap: приоритеты

Убедитесь, что у zram приоритет выше (например, 100), а у дискового swap ниже (например, 10). Тогда ядро сперва использует быстрый компрессированный swap и только затем — медленный диск.

Настройка zram и swap на Linux VDS

Sysctl‑параметры: пресеты без фанатизма

Создайте файл /etc/sysctl.d/99-memory.conf и задайте базовые значения. Два проверенных профиля:

Профиль A: универсальный малый VDS (веб‑приложение, очереди, небольшая БД)

vm.swappiness = 80
vm.vfs_cache_pressure = 100
vm.overcommit_memory = 2
vm.overcommit_ratio = 120
vm.min_free_kbytes = 65536
vm.page-cluster = 0

Пояснения:

  • vm.swappiness=80 — позволяет активнее выносить «холодные» страницы в zram, снижая вероятность резкого OOM.
  • vm.overcommit_memory=2 и vm.overcommit_ratio=120 — строгий контроль overcommit: ядро не обещает программам больше памяти, чем доступно по формуле (RAM + swap × ratio). Это уменьшает риск внезапного OOM.
  • vm.page-cluster=0 — уменьшает «чтение пачками» при подкачке, что полезно для интерактивности на медленном диске.

Профиль B: latency‑чувствительные сервисы

vm.swappiness = 20
vm.vfs_cache_pressure = 200
vm.overcommit_memory = 2
vm.overcommit_ratio = 100
vm.min_free_kbytes = 131072
vm.page-cluster = 1

Идея: меньше полагаться на swap, агрессивнее чистить кеши, держать чуть больший «воздушный зазор» свободной памяти. Применение настроек:

sudo sysctl --system
FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

vm.overcommit_memory без страха

vm.overcommit_memory имеет три режима:

  • 0 — эвристика ядра (может быть непредсказуемой на малых VDS).
  • 1 — разрешить любой overcommit (максимальный риск OOM).
  • 2 — ограничивать выделение в пределах расчётного лимита (vm.overcommit_ratio).

На малом VDS безопаснее режим 2. Он откажет в выделении памяти раньше (например, malloc() вернёт ошибку), чем сервер уйдёт в своп‑шторм и OOM. Это легче отлавливать в приложении и логах.

OOM‑killer: понять и приручить

Когда памяти не хватает, OOM‑killer выбирает жертву по баллам (oom_score). На результат можно влиять через oom_score_adj (от −1000 до 1000). Чем меньше, тем «ценнее» процесс для системы.

Защитим SSH и критичные демоны

Сделайте systemd‑override для SSH:

sudo systemctl edit sshd

В открывшемся редакторе добавьте:

[Service]
OOMScoreAdjust=-900

Перезапустите:

sudo systemctl daemon-reload
sudo systemctl restart sshd

Проверьте:

cat /proc/$(pidof sshd)/oom_score_adj

Аналогично можно защитить прокси, watchdog или легкий админский агент. Не злоупотребляйте: если «неубиваемых» процессов много, OOM‑killer выберет что‑то другое, возможно важное.

Ограничения по памяти на уровень сервиса

systemd позволяет задавать cgroup‑лимиты и реакцию на OOM:

[Service]
MemoryMax=512M
MemoryHigh=384M
OOMPolicy=restart

MemoryHigh сигнализирует ядру дросселировать процесс при приближении к лимиту, MemoryMax — жесткий предел. OOMPolicy задает поведение systemd при OOM внутри cgroup (например, перезапустить сервис).

PHP‑FPM, воркеры и «тихие пожиратели RAM»

Частая причина OOM — слишком много процессов. Для PHP‑FPM, Node.js/PM2, Python‑воркеров и Java‑сервисов пересчитайте пулы и ограничьте рост:

  • PHP‑FPM: подберите pm, pm.max_children и лимиты памяти расширений.
  • Node.js: учтите дефолтные лимиты V8 и используйте --max-old-space-size где нужно.
  • Python/uwsgi/gunicorn: контролируйте число воркеров и используйте перезапуски по памяти.

Лучший способ — задать разумный предел на уровне systemd через MemoryMax и наблюдать фактическое потребление.

Мониторинг и диагностика memory pressure

Минимальный набор команд для наблюдения:

free -h
vmstat 1

Топ прожорливых процессов и их OOM‑метрики:

ps -eo pid,cmd,pmem,rss,oom_score,oom_score_adj --sort=-rss | head -n 20

Pressure Stall Information (PSI) показывает «время под давлением»:

cat /proc/pressure/memory

Строки some и full растут — значит, задачи ждут память, а система «давится». Ищите всплески перед инцидентами.

Логи OOM‑killer в dmesg/journal:

dmesg -T | grep -i oom
journalctl -k -g OOM -n 100

Мониторинг PSI и памяти в Linux

Тест под нагрузкой: лучше сломать на стенде

Инструменты для репродукции проблем памяти:

sudo apt install stress-ng
stress-ng --vm 1 --vm-bytes 80% --timeout 60s

Или проверка на ошибки RAM:

sudo apt install memtester
sudo memtester 256M 1

Параллельно смотрите PSI, swap‑активность и отклики сервисов. Если под нагрузкой система резко уходит в swap на диск — уменьшите swappiness или увеличьте долю zram. Если ловите OOM — проверьте vm.overcommit*, лимиты cgroup и размер swap. Быстрый стенд для таких экспериментов удобнее поднять на отдельном VDS.

Практический пресет для малого VDS: пошагово

  1. Включите zram (50% RAM, приоритет 100).
  2. Добавьте небольшой дисковый swap‑файл (0.5–1 ГБ, приоритет 10).
  3. Примените профиль sysctl: vm.overcommit_memory=2, vm.overcommit_ratio=120, swappiness=80, page-cluster=0.
  4. Задайте OOMScoreAdjust=-900 для SSH и одного‑двух критичных сервисов.
  5. Ограничьте прожорливые службы через MemoryHigh/MemoryMax.
  6. Протестируйте stress-ng, наблюдайте PSI и логи OOM.
  7. Зафиксируйте изменения в конфигурациях, перезагрузите и убедитесь, что всё поднимается автоматически.

Тонкости и подводные камни

  • Дисковый swap на медленном SSD/HDD может вызывать задержки. Делайте ставку на zram, а диск оставляйте как «вторую линию».
  • Слишком высокий swappiness без zram приведет к «липкому» дисковому swap и лагам.
  • Жесткий overcommit (vm.overcommit_memory=2) может ломать запуск редких приложений, ожидающих «много памяти на старте». Решение — временно ослабить лимит или поднять vm.overcommit_ratio.
  • Не защищайте от OOM всё подряд. Смысл в том, чтобы ядро могло безопасно выгрузить наименее важное.
  • Следите за journalctl: если видите постоянные предупреждения о throttling по MemoryHigh, значит, лимит слишком tight.

Планируете переезд и подбор панели управления? Смотрите сравнение актуальных панелей для VDS: что выбрать для администрирования, и пошаговую инструкцию по миграции с шареда: как переехать на VDS без простоев.

Итог

На малом VDS стабильность достигается комбинацией мер: быстрый компрессированный swap через zram, аккуратный дисковый swap, строгий vm.overcommit_memory=2 с разумным vm.overcommit_ratio, корректный swappiness и явные границы для прожорливых сервисов через cgroup. Добавьте защиту SSH от OOM, наблюдайте PSI и тестируйте под нагрузкой — и «внезапные Kill» уйдут в прошлое.

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

Поделиться статьей

Вам будет интересно

Hardening сервисов на VDS: sandbox опции systemd — ProtectSystem, PrivateTmp, CapabilityBoundingSet OpenAI Статья написана AI Fastfox

Hardening сервисов на VDS: sandbox опции systemd — ProtectSystem, PrivateTmp, CapabilityBoundingSet

Как ограничить права Linux‑сервисов на VDS с помощью sandbox‑опций systemd. Разбираем ProtectSystem, PrivateTmp, CapabilityBoundin ...
Wildcard DNS и превью‑стенды: поддомены на каждую ветку Git через Nginx map на VDS OpenAI Статья написана AI Fastfox

Wildcard DNS и превью‑стенды: поддомены на каждую ветку Git через Nginx map на VDS

Показываю рабочую схему превью‑стендов: одна VDS, wildcard DNS на dev‑домен, Nginx с map и скрипты, поднимающие приложения на уник ...
Умный кэш Nginx для API и внешних бэкендов: proxy_cache, stale‑while‑revalidate и cache lock OpenAI Статья написана AI Fastfox

Умный кэш Nginx для API и внешних бэкендов: proxy_cache, stale‑while‑revalidate и cache lock

Как снизить латентность и нагрузку на внешние бэкенды, не ломая логику API? Разберём боевые паттерны Nginx: proxy_cache, ключи и T ...