Нужен ли swap на VPS и как правильно настроить размер
Узнайте, когда swap-файл предотвращает срабатывание OOM killer на серверах с малым объемом RAM. Разбираем расчет размера файла, параметры vm.swappiness и преимущества zram.
Нужен ли вашему VPS swap?
Большинство образов облачных серверов поставляются без swap, и для небольшого VPS ответ обычно утвердительный: добавьте swap-файл. Swap не превращает сервер с 1 GB оперативной памяти в сервер с 2 GB. Он предоставляет ядру место для выгрузки неактивных анонимных страниц памяти, что позволяет сохранить эффективность page cache и делает OOM killer (out of memory killer — процедуру ядра, которая выбирает процесс и завершает его для освобождения памяти) крайней мерой, а не первым средством.
Кратко: на сервере, где работают несколько долгоживущих сервисов, небольшой swap-файл стоит занимаемого им места на диске. На сервере, где один процесс регулярно пытается выделить больше памяти, чем есть во всей системе, swap вас не спасёт, а лишь сделает сбой более медленным и труднодиагностируемым. Остальная часть этого руководства посвящена тому, как различить эти два случая, а также двум аспектам стоимости, которые проявляются только на VPS.
Все приведённые ниже команды требуют прав root на вашем сервере, поэтому выполняйте их непосредственно там, а не копируйте вывод с чужих машин.
Что на самом деле делает swap, а чего он не делает
Память в Linux бывает двух типов. Страницы, привязанные к файлам (file backed pages), являются копиями данных, которые уже существуют на диске: это ваши программы и все файлы, которые вы недавно читали. Эта совокупность страниц называется page cache. Анонимные страницы (anonymous pages) — это память, не имеющая под собой файла: куча (heap) и стек (stack), а также большая часть того, что база данных выделяет во время выполнения.
Когда памяти не хватает, ядро должно освободить страницы. Чистую страницу, привязанную к файлу, освободить легко, так как копия на диске уже существует и страницу можно будет считать позже. С анонимной страницей так поступить нельзя, поскольку её единственная копия находится в RAM. Без swap у ядра есть только два варианта действий с анонимной памятью: оставить её или завершить процесс, которому она принадлежит.
Сервер без swap всё равно выполняет подкачку страниц (paging). Он просто делает это не с той памятью. Под нагрузкой ядро уменьшает page cache, вытесняя файловые страницы, которые скоро снова понадобятся, включая исполняемый код запущенных программ. Эти страницы возвращаются через major page faults. Вы увидите операции чтения с диска в столбце bi утилиты vmstat и растущий счетчик pgmajfault в /proc/vmstat, в то время как si и so всё время будут оставаться на нуле. Система начинает «буксовать» (thrashing), а счетчики swap при этом ничего не показывают.
Swap не увеличивает ёмкость памяти. Если рабочий набор (working set), то есть страницы, к которым происходит реальное обращение, больше объема RAM, то swap превращает принудительное завершение процесса из-за нехватки памяти (OOM kill) в очень медленную работу сервера. Иногда это именно тот компромисс, который вам нужен, так как на медленный сервер можно зайти и исправить проблему, в то время как «убитую» базу данных восстановить сложнее. Иногда это хуже, так как медленный сервер продолжает проваливать проверки работоспособности (health checks), удерживая при этом все соединения открытыми. Решите, что для вас важнее, прежде чем добавлять swap.
Почему облачные образы поставляются без swap?
Это осознанный выбор. Один и тот же образ должен загружаться на любом тарифном плане провайдера, поэтому фиксированный раздел swap расходовал бы место на диске на младших тарифах и был бы бесполезен на старших. Скорость работы swap также зависит от типа хранилища под гостевой системой, о котором образ заранее знать не может. Кроме того, создатели образов оптимизируют их для предсказуемого поведения: процесс, который сразу завершается с ошибкой, диагностировать в масштабах парка серверов проще, чем машину, которая продолжает работать, но отвечает на каждый запрос с задержкой в несколько секунд.
Эти причины актуальны для одноразовых машин. VPS, который вы используете постоянно, — это другое дело. Вы ремонтируете его, а не заменяете, поэтому несколько секунд ожидания из-за подкачки обычно лучше, чем принудительно завершенный сервис. Воспринимайте отсутствие swap как настройку по умолчанию, созданную для чужого сценария использования.
Файл подкачки или раздел подкачки на VPS?
Используйте файл. Изменение размера раздела на работающей корневой файловой системе сопряжено с риском и не дает преимуществ. Файл создается и удаляется стандартными командами, а его размер можно изменить позже, не затрагивая таблицу разделов.
Скорость не является решающим фактором. Во время swapon ядро один раз считывает карту экстентов файла, а затем передает операции ввода-вывода напрямую на блочное устройство, поэтому файловая система не участвует в процессе записи каждой страницы в память или на диск. На одном и том же диске файл подкачки и раздел подкачки работают одинаково.
Следует учитывать два ограничения. Не размещайте swap на сетевых файловых системах, таких как NFS (network file system). В файловой системе btrfs для файла подкачки должны быть отключены функции copy on write и сжатие, поэтому btrfs предоставляет собственную утилиту для его создания.
Как добавить файл подкачки (swap) в Ubuntu или Debian
Перед внесением любых изменений проверьте текущее состояние системы.
swapon --show
free -h
findmnt -no FSTYPE /Пустой вывод команды swapon --show означает отсутствие swap, что является стандартным состоянием для свежего образа облачного сервера. Команда findmnt выводит тип корневой файловой системы, от которого зависит способ создания файла. Для ext4, используемой в большинстве облачных образов, команда fallocate является безопасной.
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfileКоманда chmod выполняется перед mkswap намеренно. Если пропустить этот шаг, mkswap выдаст предупреждение: mkswap: /swapfile: insecure permissions 0644, fix with: chmod 0600 /swapfile. Файл подкачки, доступный для чтения всем пользователям, позволяет любому пользователю системы прочитать данные, выгруженные из оперативной памяти другими процессами. Успешное выполнение mkswap подтверждает размер файла строкой вида Setting up swapspace version 1, size = 2 GiB (2147479552 bytes).
В файловых системах xfs или btrfs последняя команда может завершиться с ошибкой swapon: /swapfile: swapon failed: Invalid argument. В XFS это происходит из-за того, что fallocate оставляет незаписанные экстенты, поэтому необходимо выполнить запись байтов принудительно.
sudo dd if=/dev/zero of=/swapfile bs=1M count=2048 status=progressВ btrfs причиной является механизм copy-on-write, поэтому текущая версия btrfs-progs автоматически устанавливает необходимые флаги.
sudo btrfs filesystem mkswapfile --size 2g /swapfileВ любом случае завершите настройку командами chmod 600, mkswap (где это применимо) и swapon, после чего проверьте результат.
swapon --show
free -hКоманда swapon --show должна отобразить /swapfile с типом file и заданным размером, а free -h должна показать строку Swap с почти нулевым использованием. Нулевое использование swap на свежей системе — это норма. Ядро перемещает страницы в файл подкачки только при необходимости.
Настройте автоматическое монтирование при загрузке и сразу проверьте корректность записи.
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
sudo swapoff /swapfile
sudo swapon -a
swapon --showКоманда swapon -a считывает файл /etc/fstab, поэтому ошибка в строке проявится немедленно. Опечатка, которую вы не проверили сразу, обнаружится во время незапланированной перезагрузки, когда система запустится без swap, который вы планировали использовать.
Чтобы удалить swap впоследствии, выполните sudo swapoff /swapfile, удалите строку из fstab, а затем sudo rm /swapfile. Команда swapoff должна сначала считать все выгруженные страницы обратно в RAM, поэтому на сильно загруженной системе она может завершиться с ошибкой swapoff: /swapfile: swapoff failed: Cannot allocate memory. Освободите часть оперативной памяти и повторите попытку.
Какого размера должен быть файл подкачки (swap)?
Задача swap — хранить неактивные анонимные страницы памяти. Поэтому важным параметром является объем фактически простаивающей оперативной памяти, а не общий объем RAM, выделенный тарифным планом. Объем простаивающей памяти не растет пропорционально размеру плана, поэтому с увеличением объема RAM множитель уменьшается. Это правило используется в данном руководстве.
The data behind this chart
[
{
"label": "1 GB plan",
"swap_gb": 2,
"swap_x_ram": 2
},
{
"label": "2 GB plan",
"swap_gb": 2,
"swap_x_ram": 1
},
{
"label": "4 GB plan",
"swap_gb": 2,
"swap_x_ram": 0.5
},
{
"label": "8 GB plan",
"swap_gb": 4,
"swap_x_ram": 0.5
},
{
"label": "16 GB plan",
"swap_gb": 4,
"swap_x_ram": 0.25
}
]Для самого младшего тарифного плана размер swap составляет 2 GB, что соответствует 2 от объема RAM. Это необходимо, так как на сервере с 1 GB памяти запас ресурсов минимален, и любой скачок нагрузки приводит к срабатыванию OOM killer. В верхней части таблицы размер файла ограничен 4 GB, или 0.25 от объема RAM. Причина в том, что выгрузка такого объема данных на общее хранилище занимает слишком много времени, из-за чего сервер фактически перестает отвечать. Уменьшите эти значения, если дисковое пространство ограничено, так как файл подкачки занимает реальное место на диске.
Классическая рекомендация создавать swap размером равным или большим, чем RAM, актуальна только для гибернации, при которой образ всей памяти записывается на диск. VPS не поддерживает гибернацию, поэтому данное правило к вам не относится.
На что на самом деле влияет параметр vm.swappiness?
vm.swappiness — это не процент оперативной памяти и не пороговое значение. Это относительная стоимость, которую ядро назначает при вытеснении анонимных страниц памяти по сравнению со страницами файлового кэша. Значение по умолчанию — 60. При его уменьшении ядро охотнее очищает файловый кэш. При увеличении — ядро предпочитает вытеснять анонимную память в swap.
Это компромисс, работающий в обе стороны. При vm.swappiness = 10 база данных удерживает больше своих выделенных областей в оперативной памяти, но платит за это необходимостью повторного чтения файлов, которые были только что удалены из кэша. На сервере, основная задача которого — отдача файлов, это неверный подход, так как именно файловый кэш выполняет там полезную работу.
Установка значения 0 не отключает swap. Она предписывает ядру избегать вытеснения анонимных страниц до тех пор, пока память почти не закончится, что приближает срабатывание OOM killer, а не отдаляет его. Если вы хотите полностью отказаться от swap, удалите файл подкачки.
sysctl vm.swappiness
printf 'vm.swappiness = 10\n' | sudo tee /etc/sysctl.d/99-swappiness.conf
sudo sysctl --system
sysctl vm.swappinessОбычная команда sysctl -w действует только до следующей перезагрузки, после чего настройки сбрасываются, поэтому записывайте параметры в файл в каталоге /etc/sysctl.d/. Начиная с версии 5.8, ядра поддерживают значения от 0 до 200. Значения выше 100 имеют смысл только в том случае, если скорость swap сопоставима со скоростью RAM, что подразумевает использование zram.
zram: swap, использующий CPU вместо диска
zram — это сжатое блочное устройство, работающее в оперативной памяти. Используйте его в качестве swap: страницы, которые должны были быть записаны на диск, сжимаются и остаются в памяти. Это исключает дисковый ввод-вывод и не расходует дисковую квоту. Платой за это является процессорное время, затрачиваемое на каждую операцию записи и чтения страницы, а также объем RAM, занятый сжатыми данными, которые теперь недоступны для ваших приложений.
Коэффициенты сжатия от 2:1 до 3:1 — это типичные показатели для анонимных страниц памяти; ваши собственные значения отображаются командой zramctl в столбцах DATA и COMPR. Измеряйте показатели, а не полагайтесь на средние значения, так как некоторые рабочие нагрузки содержат данные, которые практически не сжимаются.
sudo apt install zram-toolsУстановите параметры ALGO=zstd и PERCENT=25 в файле /etc/default/zramswap, затем перезапустите службу и проверьте результат.
sudo systemctl restart zramswap
zramctl
swapon --showЗначение PERCENT представляет собой долю от общего объема RAM, поэтому установка 25 на сервере с 4 GB памяти зарезервирует до 1 GB под сжатые страницы. Начните с малых значений и увеличивайте их только в том случае, если zramctl показывает заполнение устройства. Параметр PRIORITY в том же файле определяет приоритет заполнения swap ядром: более высокое значение имеет преимущество. Дисковый файл подкачки, добавленный стандартной командой swapon, получает отрицательный приоритет, поэтому zram используется в первую очередь, а файл подкачки принимает излишки. Команда swapon --show выводит оба значения в столбце PRIO. В дистрибутивах, использующих systemd-zram-generator вместо zram-tools, те же настройки находятся в /etc/systemd/zram-generator.conf.
zram подходит для серверов с запасом по CPU и нехваткой дискового пространства. Это неверный выбор, если процессорные ресурсы уже ограничены, так как операции сжатия будут конкурировать с приложениями за процессорное время.
Две ловушки swap, характерные только для VPS
Первая ловушка — диск. Swap-файл объёмом 2 GB сразу занимает 2 GB дискового пространства вашего тарифного плана, так как место должно быть выделено заранее. df -h / немедленно уменьшается на этот объём и не восстанавливается, пока вы не удалите файл. На младших тарифах это заметная часть диска, а переполнение корневой файловой системы приводит к гораздо более серьёзным последствиям, чем отсутствие swap. Этот файл также учитывается в выводе du, что стоит помнить при поиске свободного места и расхождениях в данных df и du о занятом пространстве.
Вторая ловушка — задержки (latency). Ваш swap I/O направляется в хранилище, которое хост делит с другими виртуальными машинами, и вы не видите их нагрузку изнутри своей системы. Вы видите только результат: операция чтения страницы, которая обычно выполняется быстро, иногда занимает гораздо больше времени, и процесс, ожидающий её, останавливается до завершения передачи. Это та же логика, что и в случае с CPU steal time на общем хосте, но применительно к очереди диска, а не к очереди выполнения процессов. Измеряйте показатели на своём сервере, так как любые опубликованные данные о задержках описывают ситуацию у других соседей по хосту.
Как понять, что использование swap вредит системе?
Использование swap само по себе не является проблемой. Проблемой является интенсивный обмен данными с ним. Если на сервере несколько сотен мегабайт находятся в swap, но активность подкачки отсутствует, это значит, что система просто выгрузила данные, к которым никто не обращался часами. Это ожидаемое поведение.
Следите за скоростью обмена, а не за общими объемами.
vmstat 1 5si и so — это количество кибибайт в секунду, записываемых в swap и считываемых из него. На исправной системе эти значения близки к нулю, независимо от того, что показывает столбец swpd. Постоянные значения so при одновременном росте si означают, что страницы постоянно записываются на диск и тут же считываются обратно — это состояние «пробуксовки» (thrashing).
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
2 3 1048572 38210 4096 61440 912 1180 2210 1290 1402 2890 9 7 12 72 0Этот пример показывает систему, испытывающую проблемы, и самый явный признак здесь находится не в столбцах swap. Это wa со значением 72, что означает, что процессор большую часть времени ожидал завершения операций ввода-вывода (I/O), а b со значением 3 указывает на то, что три процесса заблокированы.
PSI (pressure stall information) отвечает на этот вопрос более прямо.
cat /proc/pressure/memorysome avg10=8.42 avg60=5.11 avg300=2.03 total=1284729
full avg10=3.10 avg60=1.94 avg300=0.71 total=498210some avg10=8.42 означает, что за последние 10 секунд как минимум одна задача была приостановлена в ожидании памяти в течение 8.42 процента времени. full учитывает время, когда все неактивные задачи были приостановлены, поэтому устойчивое значение full — это уже измеримый ущерб, а не просто предупреждение. Если файл отсутствует, значит, в вашем ядре PSI отключен по умолчанию, и для его работы требуется параметр psi=1 в командной строке ядра.
Чтобы увидеть, какие процессы удерживают страницы в swap:
sudo awk '/^Name:/{n=$2} /^VmSwap:/ && $2+0 > 0 {printf "%10d kB %s\n", $2, n}' /proc/[0-9]*/status | sort -rn | headЧтобы узнать, срабатывал ли OOM killer:
sudo journalctl -k --grep "Out of memory"Событие выглядит как Out of memory: Killed process 2199 (mysqld) total-vm:1275860kB, anon-rss:129252kB, file-rss:0kB, shmem-rss:0kB, UID:114 pgtables:504kB oom_score_adj:0, а лог сервиса за ту же секунду содержит Main process exited, code=killed, status=9/KILL. Если вы увидели такие строки на сервере без swap, добавление swap-файла — это самый простой и дешевый способ решения проблемы.
Когда swap — неверное решение
Swap помогает выиграть время при временной или некритичной нехватке оперативной памяти. Он бесполезен для процесса, который разрастается до тех пор, пока не завершится аварийно. Более того, swap затрудняет мониторинг такого сбоя, так как сервер тратит лишние минуты на подкачку страниц вместо того, чтобы быстро завершить процесс и перезапустить его.
Вместо этого ограничьте потребление ресурсов процессом. Юнит systemd поддерживает параметры MemoryMax= и MemorySwapMax= в drop-in файле. Это позволяет ограничить память и CPU для сервиса в systemd без внесения изменений в само приложение. У контейнеров есть аналогичные механизмы управления на уровень выше. Их настройка — это способ предотвратить ситуацию, когда один сервис Compose занимает все ресурсы сервера. Оба метода приводят к завершению процесса с понятной записью в логах, которую легко найти, вместо того чтобы позволять ядру выбирать жертву на основе OOM score.
Выполняйте эту настройку, пока сервер новый и нагрузка на него минимальна. Создание файла подкачки и установка лимита памяти занимают несколько минут. Эти действия должны быть частью стандартного процесса настройки, описанного в руководстве первые десять минут работы с новым VPS.
FAQ
Станет ли VPS с 1 ГБ ОЗУ работать как VPS с 2 ГБ, если добавить swap?
Нет. Swap работает значительно медленнее оперативной памяти, и ядро перемещает туда только те страницы, которые считает неактивными. Swap дает запас на случай кратковременных всплесков нагрузки и место для хранения памяти, которая была выделена, но не используется. Если рабочая нагрузка активно читает и записывает больше памяти, чем есть в системе, swap превращает завершение процесса по нехватке памяти (OOM kill) в постоянный обмен данными с диском (paging). Сервер остается в рабочем состоянии, но отвечает настолько медленно, что пользоваться им невозможно. В таком случае добавьте ОЗУ или ограничьте потребление памяти процессом.
Сколько swap нужно для VPS с 1 ГБ или 2 ГБ ОЗУ?
2 ГБ достаточно для обоих случаев, и после этого объема нет необходимости увеличивать swap пропорционально росту ОЗУ. Swap хранит неактивные анонимные страницы, и объем действительно неиспользуемой памяти на сервере не растет так же, как общий объем ОЗУ. Старое правило «в два раза больше ОЗУ» пришло из практики гибернации, которая записывает весь образ памяти на диск, но VPS никогда не переходит в режим гибернации. Увеличение swap сверх 4 ГБ в основном лишь отсрочит неизбежный сбой, который будет происходить медленно на диске, разделяемом с другими виртуальными машинами.
Правильно ли устанавливать vm.swappiness в 0, чтобы отключить использование swap?
Нет, это не дает того эффекта, который подразумевает название. vm.swappiness = 0 не отключает swap. Этот параметр лишь указывает ядру избегать вытеснения анонимных страниц до тех пор, пока память почти не закончится, что повышает вероятность OOM kill, а не снижает её. Кроме того, это переносит всю нагрузку по освобождению памяти на page cache, из-за чего чтение файлов чаще обращается к диску. Если вы хотите полностью отказаться от swap, выполните sudo swapoff -a и удалите соответствующую строку из fstab. Если вы хотите уменьшить использование swap, попробуйте vm.swappiness = 10 и сравните столбцы si и so в выводе vmstat до и после изменений.
Стоит ли использовать zram вместо swap-файла?
Используйте zram, если у вас есть запас по процессору и мало свободного места на диске, а swap-файл — если ситуация обратная. zram сжимает страницы и хранит их в ОЗУ, что позволяет полностью избежать операций ввода-вывода на диск, но требует затрат ресурсов процессора при каждой записи и чтении страницы. Кроме того, занимаемое место отнимается у приложений. На VPS с ограниченным лимитом CPU эти затраты ложатся на ресурс, которого вам и так не хватает. Использование обоих вариантов — нормальная практика: установите для zram более высокий приоритет с помощью PRIORITY в /etc/default/zramswap и оставьте swap-файл на диске в качестве резервного хранилища для переполнения.
Почему сработал OOM killer, если команда free показывала наличие свободной памяти?
free показывает состояние на конкретный момент, а выделение памяти происходит мгновенно. Процесс, запрашивающий большой блок памяти быстрее, чем система успевает её освобождать, будет завершен, даже если средние показатели выглядели нормальными. Изучите лог ядра с помощью sudo journalctl -k --grep "Out of memory": там указан завершенный процесс и объем занимаемой им памяти в момент инцидента. Затем проверьте, не было ли завершение вызвано лимитом cgroup, а не нехваткой памяти на всей машине. Контейнер или systemd-юнит с установленным параметром MemoryMax= завершается при достижении собственного лимита, даже если на хосте еще есть свободная память.