До основного вмісту

Ліміти CPU і пам’яті службі: cgroups v2 і systemd

VDS / VPS · 09.11.2026 · 5 хв читання

Що дають ліміти cgroups і systemd

Ліміти cgroups дозволяють обмежити службі процесор, пам’ять, введення-виведення і кількість процесів, не змінюючи її код: потрібні директиви пишуться в юніт systemd, а ядро стежить за їх виконанням. Так одна служба, що зірвалася, не забере ресурси в решти. Створення самої служби описане в статті як створити службу systemd.

ДирективаЩо обмежуєЗначення
CPUQuota=стелю часу процесоравідсотки: 20% — не більше 20% часу одного ядра, понад 100% — час кількох ядер
CPUWeight=частку процесора за конкуренціївід 1 до 10000, за замовчуванням 100
MemoryHigh=м’який поріг пам’ятібайти із суфіксами K, M, G, T, відсоток або infinity
MemoryMax=жорсткий ліміт пам’ятіті самі одиниці
MemorySwapMax=ліміт використання swapбайти, відсоток від розміру swap або infinity
IOWeight=частку блочного введення-виведеннявід 1 до 10000, за замовчуванням 100
TasksMax=кількість завдань у юнітічисло, відсоток або infinity

Значення — за man systemd.resource-control. Версію systemd перевірте командою systemctl --version: сторінка man описує останню версію.

Як перевірити, що у вас cgroup v2

Перевірка одна: якщо існує файл /sys/fs/cgroup/cgroup.controllers, система використовує cgroup v2. За документацією Kubernetes і проєкту rootlesscontaine.rs v2 увімкнена за замовчуванням у Debian 11 і новіших, Ubuntu 21.10 і новіших (рекомендується 22.04 LTS і новіші), RHEL 9 і новіших, Fedora 31 і новіших.

Процесор: CPUQuota і CPUWeight

CPUQuota= ставить жорстку стелю: 20% означає, що процеси служби ніколи не отримають понад 20% часу одного ядра, а значення понад 100% дає час кількох ядер, наприклад 200% — двох. CPUWeight= стелі не ставить і працює лише за конкуренції: вільний процесор служба отримає цілком.

CPUWeight= приймає значення від 1 до 10000, за замовчуванням 100, і ділить процесор між службами одного слайса пропорційно вагам.

Пам’ять: MemoryHigh, MemoryMax і swap

MemoryMax= — жорсткий ліміт: якщо вкластися не вдається, OOM-killer викликається всередині юніта. MemoryHigh= — м’який поріг: процеси сильно уповільнюються і в них відбирають пам’ять, але OOM-killer не викликається. Документація systemd радить основним механізмом робити MemoryHigh=, а MemoryMax= тримати як останню лінію оборони.

На практиці це означає: надто низький MemoryHigh= проявиться як повільна служба, надто низький MemoryMax= — як убита. Як OOM-killer обирає жертву, розібрано в статті OOM-killer у Linux.

MemorySwapMax= задає абсолютний ліміт використання swap службою: значення 0 забороняє їй swap зовсім. Про swap — у статті налаштування swap у Linux.

Введення-виведення і кількість процесів

IOWeight= ділить пропускну здатність блочного введення-виведення між службами одного слайса пропорційно вазі, від 1 до 10000, за замовчуванням 100. TasksMax= обмежує кількість завдань у юніті; значення за замовчуванням береться з DefaultTasksMax= у systemd-system.conf. Ефект IOWeight= залежить від пристрою та налаштувань ядра, перевіряйте його виміром.

Як застосувати ліміти: drop-in за кроками

Найкращий спосіб — drop-in: невеликий файл у каталозі /etc/systemd/system/<служба>.service.d/, який доповнює юніт і не чіпає оригінал. Команда systemctl edit створює його сама, а systemctl edit --full відкриває повну копію юніта. Значення нижче приблизні: підберіть їх під свою службу і перевірте результат на тестовому екземплярі.

  1. Створіть файл limits.conf у каталозі drop-in або виконайте sudo systemctl edit myapp.service.
  2. Впишіть директиви в секцію [Service], як у прикладі нижче.
  3. Виконайте sudo systemctl daemon-reload.
  4. Перезапустіть службу: sudo systemctl restart myapp.service.
# /etc/systemd/system/myapp.service.d/limits.conf
[Service]
CPUQuota=50%
CPUWeight=50
MemoryAccounting=1
MemoryHigh=512M
MemoryMax=768M
MemorySwapMax=0
IOAccounting=1
IOWeight=50
TasksMax=200

MemoryAccounting=1 і IOAccounting=1 вмикають облік для systemd-cgtop. MemoryHigh= стоїть нижче за MemoryMax=, щоб спершу спрацювало уповільнення, і лише потім убивство.

Як подивитися результат

Чинні значення показує systemctl show, а навантаження по групах — systemd-cgtop: він впорядковує cgroup за навантаженням на процесор, пам’ять або диск. Дивитися результат варто одразу після перезапуску служби і ще раз під навантаженням. Дані неповні, поки для потрібних служб не ввімкнені MemoryAccounting=1 та IOAccounting=1.

sudo systemctl daemon-reload
sudo systemctl restart myapp.service
systemctl show myapp.service -p MemoryHigh -p MemoryMax -p MemorySwapMax -p TasksMax
systemctl show myapp.service | grep -i cpuquota
systemd-cgtop

Ім’я властивості квоти в systemctl show може відрізнятися від імені директиви, тому шукаємо за cpuquota. Якщо служба гальмує і після лімітів, переходьте до профілювання: профілювання продуктивності Linux.

Ліміти для звичайного користувача

Для сеансу звичайного користувача, не root, за замовчуванням делегуються лише контролери memory і pids; cpu та io потрібно делегувати окремо. Це з документації проєкту rootlesscontaine.rs, а не з man systemd, і значення за замовчуванням залежить від дистрибутива: дивіться /lib/systemd/system/user@.service.

# /etc/systemd/system/user@.service.d/delegate.conf
[Service]
Delegate=cpu cpuset io memory pids

Після створення файла виконайте systemctl daemon-reload і перезайдіть у сеанс або перезавантажте сервер. Контролер cpuset вимагає systemd 244 або новішої версії. Для системних служб, які запускає root, делегування не потрібне: вистачає директив у юніті.

Часті запитання

CPUQuota=100% — це весь сервер?

Ні. 100% — це час одного ядра. Служба з CPUQuota=100% не займе понад одне ядро, а щоб дати їй два ядра, ставлять 200%.

З чого почати, якщо я не знаю, скільки пам’яті потрібно службі?

З вимірювання: увімкніть облік і поспостерігайте за службою в systemd-cgtop під звичайним навантаженням. Потім поставте MemoryHigh= із запасом над типовим значенням, а MemoryMax= — вище за нього.

Що робити клієнтам ZevsHost?

На спільному хостингу лімітами ресурсів керує панель, налаштовувати нічого не потрібно. На VPS і виділеному сервері службами керуєте ви: файл drop-in з лімітами пише сам власник сервера.

Чи була стаття корисною?
← Назад до бази знань Поставити питання підтримці