Proxmox: використання swap зростає — що не так із пам’яттю і як стабілізувати

Було корисно?

На вашому хості Proxmox «досить вільної ОЗП», але використання swap росте так, ніби готується до марафону. Віртуальні машини відчуваються повільними. Навантаження вузла повільно повзає вгору.
І кожний ребут «вирішує проблему» на якийсь час — такий собі тимчасовий трюк із моторошного будинку, а не з дата-центру.

Зростання swap на гіпервізорі рідко містить загадку. Зазвичай це одне з трьох: справжній пам’ятевий тиск, ви налаштували хост так, що reclaim поводиться неправильно, або ви дивитесь на неправильну метрику й женетесь за примарами. Зробімо це знову нудним.

Короткий план діагностики

Якщо у вас є лише 10 хвилин, поки хтось почне пропонувати «просто додайте ОЗП», робіть це в порядку. Ви намагаєтесь відповісти на одне питання:
чи спричинене зростання swap справжнім тиском, патологічним reclaim або неправдивою панеллю?

1) Підтвердіть, що симптом реальний (а не паніка через «cached memory»)

  • Перевірте використання swap на хості та швидкість I/O swap (не лише «скільки використано»).
  • Перевірте пам’ятевий тиск (PSI) і активність kswapd.

2) Визначте джерело тиску

  • Чи з’їдає простір ZFS ARC?
  • Чи ви перевантажили RAM між ВМ або контейнерами?
  • Чи балонування змушує гостьові ОС скидати пам’ять і штовхає хост у хаос reclaim?

3) Визначте стабілізатор

  • Якщо тиск тривалий: зменшіть зобов’язання (пам’ять ВМ), обмежте ARC або додайте ОЗП.
  • Якщо reclaim патологічний: виправте swappiness, watermarks і взаємодію з hugepages/THP; додайте zram, якщо це доречно.
  • Якщо swap «використовується, але тихо»: розгляньте залишити його або поступово звільнити swap без створення шторму.

Операційне правило: використання swap без swap I/O може бути нормальним. Swap із високим swap-in/swap-out — ось де продуктивність вмирає.

Зростання swap — не завжди помилка

Linux опортуністично переміщує холодні анонімні сторінки в swap, щоб звільнити більше ОЗП для page cache і метаданих файлової системи. На робочій станції це може бути вигідно. На гіпервізорі — залежить. Ваші «холодні» сторінки можуть належати процесам qemu, які раптово їх потребуватимуть. Ось тоді ви бачите
коротке зависання ВМ, і користувачі починають вигадувати нові епітети.

Ключове розрізнення:

  • Зайнятість swap: скільки swap використовується зараз.
  • Активність swap: скільки даних рухається в/з swap за секунду.

Зайнятість swap може зростати і залишатися високою місяцями, якщо ядро вивело по-справжньому холодні сторінки й більше їх не потребувало. Це не пожежа.
Активність swap під час робочих годин — це пожежа. Тиха, але все ж пожежа.

Жарт №1: Swap — це як склад. Можна зберігати там речі роками, але коли вам щось терміново треба під час наради — пошкодуєте.

Цікаві факти та історичний контекст

  1. Раніше Linux показував «free memory» як заголовну метрику, і люди роками панікували; сучасні поради підкреслюють «available» пам’ять.
  2. Swappiness не означає просту «агресивність swap»; він впливає на баланс reclaim між анонімними сторінками і файловим кешем, і поведінка змінюється з епохами ядра.
  3. OOM killer — це не баг; це вибір ядра «один процес має померти, щоб система жила», що часто правильно на хості, але болісно у віртуалізації.
  4. ZFS ARC розроблений споживати ОЗП, бо кешування підвищує продуктивність; без обмеження він може витіснити гостей на гіпервізорі.
  5. Pressure Stall Information (PSI) з’явилася, щоб кількісно визначити «час простою» під тиском — нарешті перетворивши «воно відчувається повільно» на вимірюваний сигнал.
  6. cgroups для пам’яті змінили правила гри, дозволивши облік пам’яті та поведінку reclaim на рівні ВМ/контейнера — іноді покращуючи ізоляцію, іноді додаючи сюрпризи.
  7. KSM (Kernel Samepage Merging) був важливим для щільності віртуалізації, але він обмінює CPU на ОЗП і може взаємодіяти з reclaim несподівано.
  8. Transparent Huge Pages були введені заради продуктивності, але у віртуалізації вони можуть збільшувати латентні спайки під час компакції і reclaim.
  9. Параметри swappiness та евристики еволюціонували, бо SSD зробили своп менш катастрофічним, ніж на дисках обертання — проте випадкові операції swap I/O все ще карають затримками.

Як Linux вирішує, що звільняти (і чому Proxmox ускладнює)

Proxmox — це «просто Debian», але в продакшені він ніколи не «просто». Ви запускаєте процеси qemu-kvm (великі споживачі анонімної пам’яті), можливо LXC-контейнери,
і, можливо, ZFS — високопродуктивну файлову систему, яка охоче використовує багато ОЗП. Додайте балонування пам’яті, яке по суті є домовленою
неправдою: «так, гість, у тебе все ще 16 ГБ», тоді як хост потихеньку просить їх назад.

Три важливі категорії: анонімні, файловий кеш і піддаваність reclaim

Коли ОЗП стискається, ядро переважно звільняє пам’ять шляхом:

  • Скидання файлового кешу (легко й швидко, якщо кеш можна відкинути).
  • Запису брудних сторінок на диск (може бути повільно; залежить від сховища).
  • Виведення в swap анонімної пам’яті (сторінки процесів, не пов’язані з файлами).

У віртуалізації пам’ять гостя перетворюється на анонімні сторінки хоста. Це означає, що найбільший споживач ОЗП гіпервізора — саме той тип пам’яті, який
Linux готовий віддати в swap, якщо вважає, що так зробить систему чутливішою. І ви вже бачили, як це закінчується.

Пам’ятевий тиск — це не «мало вільного»

Linux охоче використовує ОЗП під кеш; це не марнотратство. Метрика, на яку варто дивитись — MemAvailable/proc/meminfo) і, ще краще, сигнали PSI,
які показують, чи задачі зупиняються в очікуванні reclaim.

ZFS ускладнює reclaim

ARC у ZFS технічно піддається reclaim, але він не такий самий, як page cache ext4. ARC змагається з гостями за ОЗП. Якщо ARC росте без обмеження,
хост може почати свопити сторінки гостей, тримаючи багато ZFS-кешу. Це компроміс, якого рідко хочеться на гіпервізорі: затримки swap I/O гірші за менший ARC.

Балонування може створити «фальшивий запас»

Балонування — корисний інструмент при свідомому використанні (для еластичності, а не як відмовка). Але якщо ви перевантажуєте й покладаєтесь на балонування як на страховку,
ви можете змусити гості проводити власний reclaim, а хост одночасно робитиме reclaim. Два рівні reclaim. Подвійне задоволення. Половина стабільності.

Цитата (перефразована ідея): «Надія — не стратегія» — часто повторювана операційними лідерами; ставте це як принцип, а не як цитату.

Що зазвичай спричиняє «swap росте» на Proxmox

1) Справжній overcommit: ви виділили більше пам’яті, ніж маєте

Це класика. Ви підсумували «виділену пам’ять» ВМ і виявили, що вона значно перевищує фізичну ОЗП, а потім дивуєтесь, що хост використовує swap.
Хост не помиляється. Ваш калькулятор помилявся.

2) ZFS ARC росте й займає місце гостей

На виділеному сховищі дозволити ARC використовувати більшість пам’яті — добре. На гіпервізорі ARC потребує меж. Інакше ARC перетворюється на «того орендаря»,
що займає всю кухню й ображається, коли його просять поділитися.

3) Swappiness і налаштування reclaim не підходять для гіпервізора

Значення за замовчуванням підходять для загального Linux. Гіпервізори — не загальні системи. Неправильна комбінація може призвести до передчасного свопування сторінок qemu,
коли дешевше було б скидати кеш.

4) Фрагментація пам’яті / проблеми з компакцією (THP і hugepages)

Якщо хосту важко виділити суміжну пам’ять, компакція і reclaim стають гучними. Це може виглядати як «swap росте», але корінна причина — затримки й витрати CPU в шляхах reclaim.

5) Десь відбувається витік, але не там, де ви думаєте

Іноді це справжній витік: агент моніторингу, процес бекапу або контейнер, що втратив контроль. Але частіше це «поступове зростання», спричинене кешем
(ZFS ARC, slab caches), що виглядає як витік у невірній панелі.

6) Повільне сховище робить swap «липким»

Якщо ваш swap-пристрій повільний або завантажений, сторінки, винесені в swap, повільно повертаються. Ядро може тримати їх у swap довше, внаслідок чого використання swap росте
і тримається високим. Не тому, що ядро любить swap — а тому, що ваші диски вас не люблять.

Жарт №2: Ядро не «випадково свопить». Воно свопить із прохолодною впевненістю людини, яка знає, що ви не спланували ємності і хотіло б, щоб ви вивчили урок.

Практичні завдання: команди, виходи, рішення

Нижче — задачі, готові до виконання на полі. Кожна містить: команду, що означає її вихід, і рішення, яке ви приймаєте. Запускайте їх спочатку на хості Proxmox.
Потім, за потреби, у гостьовій системі, що поводиться неправильно.

Завдання 1: Підтвердьте зайнятість swap і пристрої swap

cr0x@server:~$ swapon --show --bytes
NAME       TYPE SIZE        USED       PRIO
/dev/sda3  part 17179869184 4294967296  -2

Значення: У вас є 16 GiB swap розділ і наразі використано 4 GiB.
Рішення: Якщо USED високий, не панікуйте поки що — перевірте активність. Якщо swap на повільному диску, який ділиться зі сховищем ВМ, подумайте про його перенесення.

Завдання 2: Перевірте активність swap (реальна метрика «чи це шкодить?»)

cr0x@server:~$ vmstat 1 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 1  0 4194304 812344  53212 921344   0    0    12    30  400  700  3  2 94  1  0
 2  0 4194304 790112  53044 910020   0    0     0    64  420  760  4  3 92  1  0
 3  1 4194304 120312  52880 302120   0  512   120  2000  800 1500 20 10 55 15  0
 2  2 4194816  90344  52000 280000 128 1024   300  5000 1200 2000 25 12 40 23  0
 1  1 4198912  81200  51000 270000 256 2048   500  8000 1500 2500 22 15 35 28  0

Значення: si/so — це KB/s swap-in/swap-out. У останніх зразках вони ненульові й зростають: активне свопування.
Рішення: Активне свопування означає вплив на продуктивність. Перейдіть до діагностики тиску; плануйте зменшити пам’ятеве навантаження або змінити поведінку reclaim.

Завдання 3: Перевірте MemAvailable і підсумки swap

cr0x@server:~$ grep -E 'MemTotal|MemFree|MemAvailable|SwapTotal|SwapFree' /proc/meminfo
MemTotal:       263989996 kB
MemFree:         1123400 kB
MemAvailable:   34122388 kB
SwapTotal:      16777212 kB
SwapFree:       12582912 kB

Значення: MemFree малий (нормально), MemAvailable близько 32 GiB (хороший запас).
Рішення: Якщо MemAvailable у нормі, але активність swap висока — підозрюйте патології reclaim, поведінку ARC або обмеження по cgroup.

Завдання 4: Прочитайте PSI пам’яті (чи задачі зависають?)

cr0x@server:~$ cat /proc/pressure/memory
some avg10=0.15 avg60=0.20 avg300=0.35 total=18203456
full avg10=0.02 avg60=0.04 avg300=0.05 total=3401120

Значення: «some» — час, коли принаймні одна задача була в стані stall через пам’ять; «full» — коли усі виконувані задачі були в stall.
Немалий «full» означає видимі для користувача затримки.
Рішення: Якщо PSI full підвищується в періоди інцидентів, розглядайте це як реальний пам’ятевий тиск. Припиніть сперечатися про «вільну ОЗП» і виправляйте ємність/налаштування.

Завдання 5: Перевірте, чи kswapd спалює CPU (reclaim працює понад норму)

cr0x@server:~$ top -b -n 1 | head -n 20
top - 10:01:22 up 41 days,  3:12,  1 user,  load average: 6.20, 5.90, 5.10
Tasks: 412 total,   2 running, 410 sleeping,   0 stopped,   0 zombie
%Cpu(s): 22.1 us,  9.3 sy,  0.0 ni, 55.0 id, 13.2 wa,  0.0 hi,  0.4 si,  0.0 st
MiB Mem : 257802.0 total,   1140.2 free, 210000.4 used,  46661.4 buff/cache
MiB Swap:  16384.0 total,   8192.0 free,   8192.0 used.  43000.0 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
  158 root      20   0       0      0      0 R  48.0   0.0  120:11.2 kswapd0
 2210 root      20   0  9820.0m  12.2g  210.0m S  30.0   4.8  300:10.9 qemu-system-x86
  901 root      20   0  2120.0m  10.0g   50.0m S   8.0   4.0   90:22.2 pvestatd

Значення: kswapd0 на ~48% CPU вказує на інтенсивний фоновий reclaim.
Рішення: Ви не просто «використовуєте swap», ви платите CPU і латентністю за це. Дослідіть ARC, overcommit і параметри reclaim.

Завдання 6: Подивіться, що саме в ОЗП (anon vs file vs slab)

cr0x@server:~$ free -h
               total        used        free      shared  buff/cache   available
Mem:           252Gi       205Gi       1.1Gi       2.0Gi        45Gi        42Gi
Swap:           16Gi       8.0Gi       8.0Gi

Значення: Велике використання — нормально; звертайтесь на «available». Тут available 42 GiB, що свідчить, що ви не зажаті — якщо тільки ZFS/ВМ не потребують різкого стрибка.
Рішення: Якщо available низький (<~5–10% ОЗП) і активність swap висока — потрібно зменшити навантаження або додати пам’яті. Якщо available високий, шукати причину, чому swap не звільняється (часто «він не потрібен»).

Завдання 7: Знайдіть топ-споживачів swap (по процесах)

cr0x@server:~$ for pid in $(ls /proc | grep -E '^[0-9]+$'); do awk '/^VmSwap:/ {print $2 " " pid}' pid=$pid /proc/$pid/status 2>/dev/null; done | sort -nr | head
1048576 2210
524288  4120
262144  1987
131072  901
65536   3301

Значення: PID 2210 (ймовірно qemu) має ~1 GiB у swap.
Рішення: Якщо qemu сильно свопить — це проблема на рівні хоста (overcommit/ARC/налаштування). Якщо свопить якийсь демон — виправляйте або обмежуйте цей процес.

Завдання 8: Відобразіть PID qemu в VMID (специфічно для Proxmox)

cr0x@server:~$ ps -p 2210 -o pid,cmd --no-headers
2210 /usr/bin/kvm -id 104 -name vm104 -m 16384 -smp 8 -drive file=/dev/zvol/rpool/vm-104-disk-0,if=virtio,cache=none

Значення: Цей процес, що свопить, — VMID 104 із 16 GiB призначеної пам’яті.
Рішення: Перевірте конфігурацію пам’яті ВМ (ballooning, min/max) і overcommit хоста. Якщо це критична ВМ для бізнесу — віддайте пріоритет стабілізації reclaim хоста.

Завдання 9: Перевірте виділену пам’ять Proxmox проти фізичної (для перевірки)

cr0x@server:~$ qm list
 VMID NAME         STATUS     MEM(MB)    BOOTDISK(GB) PID
 101  app01        running    32768             64.00 2101
 104  db01         running    16384            200.00 2210
 105  cache01      running    32768             32.00 2302
 110  winbuild     running    24576            120.00 2410

Значення: Виділена пам’ять швидко сумується; ballooning може це приховати, але фізика не бреше.
Рішення: Якщо ви близькі або перевантажені фізичною ОЗП — зупиніться. Зменшіть виділення, примусьте ліміти або додайте вузли/ОЗП. «Але гості не використовують її» — звідси починаються інциденти.

Завдання 10: Перевірте налаштування ballooning для ВМ

cr0x@server:~$ qm config 104 | grep -E 'memory|balloon'
balloon: 4096
memory: 16384

Значення: ВМ має 16 GiB максимум, balloon target 4 GiB (дуже агресивне звільнення).
Рішення: Якщо balloon target значно нижчий за реальний робочий набір, ви змушуєте гостьову ОС робити reclaim, а потім хост робитиме reclaim. Розгляньте підняття мінімуму balloon або вимкнення balloon для ВМ, чутливих до затримок.

Завдання 11: Якщо ви використовуєте ZFS — перевірте розмір ARC і тиск ARC

cr0x@server:~$ arcstat 1 1
    time  read  miss  miss%  dmis  dm%  pmis  pm%  mmis  mm%  arcsz     c
10:03:41   220    12      5     3  1.3     9  3.7     0  0.0   96.0G  110.0G

Значення: Розмір ARC ~96 GiB, цільовий cap c ~110 GiB. Це багато на гіпервізорі, залежно від загальної ОЗП і потреб ВМ.
Рішення: Якщо ARC великий, а гості своплять — обмежте ARC. Стабільність гіпервізора важливіша за маргінальний виграш кешу читання.

Завдання 12: Підтвердіть zfs_arc_max (якщо встановлено) і вирішіть, чи обмежувати

cr0x@server:~$ grep -R "zfs_arc_max" /etc/modprobe.d /etc/sysctl.conf /etc/sysctl.d 2>/dev/null
/etc/modprobe.d/zfs.conf:options zfs zfs_arc_max=68719476736

Значення: ARC max встановлено на 64 GiB (в байтах). Добре: принаймні він обмежений.
Рішення: Якщо у вас часті reclaim і активність swap, знизьте zfs_arc_max (обережно), щоб залишити запас для гостей. Якщо ви сховище-важкий і ВМ-мало — тримайте вище.

Завдання 13: Перевірте swappiness ядра і поведінку writeback

cr0x@server:~$ sysctl vm.swappiness vm.dirty_ratio vm.dirty_background_ratio
vm.swappiness = 60
vm.dirty_ratio = 20
vm.dirty_background_ratio = 10

Значення: Swappiness 60 — типовий. Dirty ratios визначають, коли ядро починає форсувати запис.
Рішення: На гіпервізорах поширена практика — знизити swappiness (наприклад, 1–10), щоб зменшити свопування пам’яті qemu, якщо лише ви не знаєте, що своп приносить користь. Налаштуйте dirty ratios, якщо бачите writeback-стали.

Завдання 14: Перевірте major page faults (показник swap-in та пропусків кеша)

cr0x@server:~$ pidstat -r -p 2210 1 3
Linux 6.2.16 (server)  12/26/2025  _x86_64_ (32 CPU)

10:05:12 AM   PID  minflt/s  majflt/s     VSZ     RSS   %MEM  Command
10:05:13 AM  2210   1200.00    45.00 10055680 12582912   4.8  qemu-system-x86
10:05:14 AM  2210   1100.00    60.00 10055680 12583104   4.8  qemu-system-x86
10:05:15 AM  2210   1300.00    55.00 10055680 12583360   4.8  qemu-system-x86

Значення: Major faults (majflt/s) часто пов’язані з дисковим I/O (включаючи swap-in). Ці числа достатньо високі, щоб про них турбуватися.
Рішення: Високі major faults для qemu під навантаженням корелюють зі свопуванням або сильним пам’ятевим тиском. Зменшіть тиск або поліпшіть пристрій swap і поведінку reclaim.

Завдання 15: Перевірте статус THP (може спричиняти проблеми з компакцією/reclaim)

cr0x@server:~$ cat /sys/kernel/mm/transparent_hugepage/enabled
[always] madvise never

Значення: THP встановлено в always. Це може працювати, але в деяких віртуалізаційних навантаженнях збільшує латентні спайки.
Рішення: Якщо ви бачите stalls через компакцію/reclaim, спробуйте madvise замість always і вимірюйте. Не наслідуйте без перевірки: тестуйте на одному вузлі спочатку.

Завдання 16: Дізнайтесь, чи swap знаходиться на повільному або навантаженому сховищі

cr0x@server:~$ lsblk -o NAME,TYPE,SIZE,ROTA,MOUNTPOINTS
NAME   TYPE   SIZE ROTA MOUNTPOINTS
sda    disk   1.8T    1
├─sda1 part   512M    1 /boot/efi
├─sda2 part     1G    1 /boot
└─sda3 part    16G    1 [SWAP]
└─sda4 part   1.8T    1
nvme0n1 disk  1.9T    0
└─nvme0n1p1 part 1.9T    0 /

Значення: Swap на ротаційному диску (ROTA=1), в той час як ОС на NVMe. Це запах продуктивності.
Рішення: Перенесіть swap на швидше сховище (NVMe) або використайте zram для поглинання пікових навантажень. Ротаційний swap на завантаженому гіпервізорі — фабрика затримок.

Завдання 17: Перевірте, чи ви досягаєте лімітів memory cgroup (особливо контейнери)

cr0x@server:~$ systemd-cgtop -m -n 1
Control Group                           Memory Current  Memory Peak  Memory Swap  IO Read  IO Write
/                                         210.0G        211.2G        8.0G        2.1M     30.4M
/system.slice/pve-container@112.service      3.2G          3.4G        1.5G          0B       12K
/system.slice/pve-container@113.service      7.8G          8.0G        2.0G          0B       18K

Значення: Контейнери також можуть використовувати swap; «memory.swap» показує використання swap по cgroup.
Рішення: Якщо один контейнер — головний «споживач» swap, виправте його ліміт або навантаження. Глобальні налаштування хоста не зроблять добре неправильно розмірований контейнер.

Завдання 18: Обережно звільнити swap (коли причина виправлена)

cr0x@server:~$ sudo sysctl -w vm.swappiness=1
vm.swappiness = 1
cr0x@server:~$ sudo swapoff -a && sudo swapon -a
cr0x@server:~$ swapon --show
NAME      TYPE SIZE  USED PRIO
/dev/sda3 part  16G    0B   -2

Значення: Swap очищено та повторно ввімкнено.
Рішення: Робіть це лише коли MemAvailable комфортно високий і активність swap низька. Інакше swapoff може спричинити пам’ятевий шторм і OOM.

Три корпоративні міні-історії зі світу swap

Міні-історія 1: Інцидент через неправильне припущення

Середня SaaS компанія мала Proxmox кластер, який хостив «різні» внутрішні сервіси: CI-runner’и, стек метрик, кілька баз даних без явних власників,
і Windows ВМ, що існувала, бо колись комусь потрібен був Visio. На папері хости мали достатньо ОЗП. Swap все одно повільно зростав, як поганий настрій.

Неправильне припущення було просте: «Якщо free показує десятки гігабайтів доступних, система не може бути під пам’ятевим тиском». Вони дивилися на
MemAvailable і оголосили перемогу. Тим часом користувачі скаржилися на короткі зависання — 30 секунд нічого — а потім усе «надолужувало».

Ключем був PSI. Під час зависань memory PSI «full» різко піковував. kswapd забрав собі CPU-ядро на тривалі періоди. Swap I/O був вимірним, не величезним, але постійним.
Це не була відсутність пам’яті в середньому; це була відсутність пам’яті у потрібний момент, і reclaim не встигав.

Корінь: кілька ВМ мали balloon target значно нижчі за їх реальний робочий набір. Хост агресивно відбирав пам’ять у гостей, гості починали сторінкувати,
і потім хост теж сторінгував. Два рівні сторінгування створили латентні спайки. Виправлення було нудне: відключили balloon для ВМ, чутливих до затримок, встановили реалістичні
мінімум для інших і припинили вірити, що overcommit — це «безкоштовно».

Після виправлення swap «продовжував рости», але активність swap впала практично до нуля. Оце було важливим. Вони перестали перезавантажувати хости як обряд.

Міні-історія 2: Оптимізація, що дала зворотний ефект

Інша команда вирішила «оптимізувати I/O», перемістивши swap на ZFS zvol у тому ж пулі, де лежали диски ВМ, бо це було зручно й знімки милі.
У лабораторії все працювало. У лабораторії фізика іноді спить.

В продакшені, під час м’якого події пам’ятевого тиску (ВМ БД робила одноразовий ребілд індексу), активність swap зросла. ZFS почав працювати інтенсивніше.
ARC зріс, бо навантаження було орієнтоване на читання. Пул завантажився. Swap I/O конкурував із дисковим I/O ВМ. Латентність зросла. Гості загальмували.

Команда відповіла збільшенням розміру swap. Це зменшило OOM, але збільшило час страждань. Вони по суті перетворили «швидку відмову» на
«повільну відмову під спостереженням дашбордів».

Виправлення: перемістили swap з ZFS пулу на виділене швидке локальне сховище (або використали zram для піків). Обмежили ARC. Тримайте swap I/O подалі від черги,
від якої залежать ВМ. Іноді правильна оптимізація — розділити обов’язки, а не точити мікросекунди.

Урок прижився: «Архітектура зручності — улюблений боксер продукції».

Міні-історія 3: Нудна, але правильна практика, що врятувала день

Компанія, близька до фінансів, мала Proxmox кластер, що ніколи не потрапляв на заголовки. Не тому, що він магічний — а тому, що його управляли дисципліновано,
що виглядає неефектно, поки цього не стане не вистачати.

Вони вели простий щотижневий звіт: тенденції MemAvailable по вузлах, середні PSI, швидкості swap I/O і топ-споживачі swap. Не марнославні метрики; ті, що допомагають вчасно помітити повільні зміни. Також політика: виділення пам’яті ВМ не могло перевищувати визначений запас без тикета.

Одного тижня PSI «some» потроху зростав на двох вузлах. Swap I/O залишався низьким, але CPU kswapd підріс. Ще нічого не ламалося. Це найкращий момент для втручання.
Вони знайшли нову ВМ для інгесту логів із пам’яттю, виставленою занадто високою, і ballooning занадто низьким, що викликало тиск хоста під піковим інгестом.

Вони відкоригували пам’ять ВМ, встановили адекватний мінімум balloon і трохи посунули zfs_arc_max. Вузли ніколи не впали з обриву. Ніяких інцидентів. Жодних нічних драм про «чому гіпервізор свопить».
Нудний графік врятував день, бо зробив «майже зламане» видимим.

Якщо ви хочете надійності, вам не потрібні герої. Потрібні ранні сигнали і право діяти.

Типові помилки: симптом → корінь → виправлення

1) Симптом: високий рівень використання swap, але продуктивність нормальна

Корінь: Холодні сторінки були виведені в swap і ніколи не знадобилися знову. Активність swap близька до нуля.

Виправлення: Нічого не робіть. Моніторьте PSI і swap I/O. Не робіть swapoff -a, лише щоб «пізнати чистоту».

2) Симптом: використання swap росте щодня, kswapd високо на CPU, короткі зависання ВМ

Корінь: Тривалий пам’ятевий тиск або цикл reclaim; часто overcommit ВМ плюс ZFS ARC або ballooning.

Виправлення: Зменшити виділення або перемістити ВМ; обмежити ARC; знизити swappiness; вимкнути або обмежити ballooning; перевірити падіння PSI.

3) Симптом: хост має багато MemAvailable, але активність swap висока

Корінь: Дисбаланс reclaim або пам’ятевий тиск на рівні cgroup (контейнери/конфігурації ВМ), або THP/компакція створюють патерни тиску.

Виправлення: Перевірте PSI і використання по cgroup; налаштуйте swappiness; розгляньте THP=madvice; переконайтесь, що swap на швидкому пристрої.

4) Симптом: після додавання swap система перестала OOM-ити, але стала повільною

Корінь: Ви перетворили жорстку відмову на тряску. Swap маскує проблему ємності.

Виправлення: Правильно визначте зобов’язання по RAM; тримайте swap помірним; використовуйте swap як страховку, а не для постійного стану.

5) Симптом: під час бекапів/сканувань свопування піки

Корінь: I/O-індуковані stalls спричиняють затримки writeback і відкладений reclaim; ZFS scrubs можуть змінити поведінку кешу і тиск.

Виправлення: Плануйте важкі I/O операції; обмежте ARC; налаштуйте dirty ratios якщо writeback stalls; переконайтесь, що swap не на тому ж зайнятому пристрої.

6) Симптом: одна ВМ «в порядку», але всі інші повільні

Корінь: Одна ВМ або контейнер штовхає хост у reclaim (пожирач пам’яті), часто через невірно виставлену пам’ять або runaway workload.

Виправлення: Знайдіть топ-споживачів swap; обмежте порушника; виставте реалістичну пам’ять ВМ; ізолюйте шумні навантаження на виділені вузли.

7) Симптом: swap продовжує рости після змін у міграції

Корінь: Зсув локальності пам’яті, ARC прогрівається інакше, або зміни в KSM/THP. Також: сторінки, вже винесені в swap, не повертаються автоматично.

Виправлення: Заново виміряйте активність swap і PSI. Якщо тихо — прийміть це. Якщо ні — налаштуйте і, за потреби, обережно звільніть swap під час вікна технічного обслуговування.

Чеклісти / поетапний план

План поетапно: стабілізувати Proxmox хост, що свопить під навантаженням

  1. Виміряйте активність, а не відчуття.
    Використайте vmstat 1, PSI і pidstat, щоб підтвердити активне свопування і stalls.
  2. Знайдіть джерело тиску.
    Визначте топ-споживачів swap; зіставте PID qemu з VMID; перевірте cgroup контейнерів.
  3. Перевірте зобов’язання.
    Порівняйте фізичну ОЗП із загальною призначеною пам’яттю. Якщо ви без плану перепризначили пам’ять — це провал плану.
  4. Виправте політику ballooning.
    Для чутливих до латентності ВМ: вимкніть balloon або встановіть реалістичний мінімум. Для інших — тримайте balloon консервативним.
  5. Обмежте ZFS ARC, якщо використовуєте ZFS.
    Визначте бюджет: залиште запас для хоста + пікових потреб ВМ. Застосуйте і моніторьте.
  6. Зробіть swap швидким або зменшіть його.
    Помістіть swap на NVMe, якщо потрібен; уникайте розміщення його в тому самому навантаженому пулі, де знаходяться диски ВМ.
  7. Легко налаштуйте reclaim, потім перезміряйте.
    Відрегулюйте swappiness (поширене: 1–10 для гіпервізорів), розгляньте THP=madvice і слідкуйте за PSI і swap I/O.
  8. Тільки тоді звільняйте swap (за бажанням).
    Використовуйте swapoff/swapon у вікні низького навантаження, якщо зайнятість swap дратує або потрібен чистий базовий стан.
  9. Закріпіть запобіжники.
    Тригери на PSI full, швидкість swap I/O і CPU kswapd. Дашборд корисний лише тоді, коли він стимулює дії.

Чекліст: як виглядає «добре» на стабільному Proxmox вузлі

  • MemAvailable залишається вище комфортного порогу під типовим піковим навантаженням (визначте його; не вгадуйте).
  • PSI memory «full» переважно близький до нуля; «some» низький і стабільний.
  • Swap I/O близький до нуля в steady-state; зайнятість swap може бути ненульовою — це прийнятно.
  • kswapd не в топі споживачів CPU.
  • ZFS ARC обмежено (якщо ZFS) і не позбавляє гостей пам’яті.
  • Ballooning використовується свідомо, а не за замовчуванням у хаос.

Чекліст: коли додавати ОЗП, а коли налаштовувати

  • Додайте ОЗП, коли PSI показує стійкі stalls і ви не можете зменшити зобов’язання без бізнес-наслідків.
  • Налаштуйте, коли активність swap висока, але запас є, або коли очевидна одна неправильна конфігурація (ARC/ballooning/розміщення swap).
  • Перепроєктуйте, коли ваша мета щільності вимагає постійного overcommit і у вас немає передбачуваності навантажень. Це стратегічне рішення, не просто sysctl.

Питання і відповіді (FAQ)

1) Чому використання swap продовжує зростати, хоча ОЗП «виглядає нормально»?

Тому що використання swap є «липким». Linux може вивести холодні сторінки в swap і більше не тягнути їх назад, якщо немає потреби. Якщо swap I/O низький і PSI спокійний,
це не обов’язково проблема.

2) Чи варто встановити vm.swappiness=1 на Proxmox?

Часто так — для гіпервізорів, бо свопування пам’яті qemu шкодить латентності. Але не вважайте це чарівною цифрою. Виміряйте swap I/O і PSI до і після зміни.
Якщо у вас навантаження з великим файловим кешем або ZFS, все одно треба керувати ARC і зобов’язаннями.

3) Чи безпечно працювати без swap?

Це «безпечно» у сенсі, що ви швидше отримаєте OOM і жорсткішу відмову. Деякі середовища віддають це перевагу перед thrashing. Більшість продакшн гіпервізорів тримають трохи swap
як аварійну подушку, але планують ємність так, щоб swap не використовувався в нормальному стані.

4) Мій swap використовується, але swap-in/out нульові. Чи треба очищати?

Немає нагальної потреби. Очищення swap повертає ті сторінки в ОЗП, що може спричинити тимчасовий тиск. Якщо хочете чистий базис, звільняйте swap у вікно техобслуговування з великим MemAvailable.

5) Чи «змушує» ZFS ARC свопування?

ARC безпосередньо не змушує свопувати, але конкурує за ОЗП. Якщо дозволити ARC рости великим на гіпервізорі, ядро може віддати анонімні сторінки (ваші ВМ) у swap,
поки ARC залишається великим. Обмеження ARC — поширений крок стабілізації на Proxmox+ZFS.

6) Чи варто розміщувати swap на ZFS zvol?

Можна, але зазвичай не варто на завантаженому гіпервізорі. Swap I/O конкурує з дисковим I/O ВМ і може посилити латентність. Віддавайте перевагу виділеному швидкому локальному сховищу
або zram для поглинання пікових навантажень, залежно від обмежень.

7) Чи хороше або погане балонування пам’яті?

Це інструмент. Хороше, коли ви використовуєте його, щоб повернути справді невикористану пам’ять гостя і задаєте реалістичні мінімуми. Погане, коли на нього покладаються як на костиль для overcommit,
а потім дивуються, чому гості й хост одночасно сторінкують під навантаженням.

8) Як зрозуміти, чи свопування шкодить ВМ?

Шукайте swap I/O на хості (vmstat), підвищені major faults у процесах qemu, PSI memory «full», CPU kswapd і симптоми на рівні ВМ: затримки, підвищений iowait. Саме використання swap — замало.

9) Чи може THP спричинити зростання swap?

THP більше про вартість компакції і reclaim, ніж про зайнятість swap прямо. Але якщо THP=always призводить до частих stalls компакції і churn reclaim,
ви можете побачити більше свопування і латентності. Якщо підозрюєте — спробуйте THP=madvice і виміряйте.

10) Який найнадійніший крок для стабілізації?

Припиніть обманювати систему щодо пам’яті. Тримайте зобов’язання у межах фізичної реальності (з запасом), обмежте ARC якщо ZFS, і зробіть ballooning консервативним.
Потім налагоджуйте swappiness і розміщення swap як доопрацювання.

Висновок: наступні кроки для стабілізації

«Swap росте» лякає лише тоді, коли це поєднується з тиском і активністю. Ваше завдання — розділити поняття зайнятості і тряски,
а потім прибрати причину, через яку хост змушений робити неприємні компроміси.

Зробіть це далі:

  1. Зніміть 10-хвилинний зріз під час піка: vmstat 1, PSI (/proc/pressure/memory), топ-процеси і major faults по qemu.
  2. Зіставте споживачів swap з VMID; перевірте, що ballooning і розміри пам’яті не вигадані.
  3. Якщо ви використовуєте ZFS: обмежте ARC до бюджету, що залишає запас для ВМ.
  4. Перенесіть swap на швидке сховище або використайте zram як буфер для піків; уникайте навантажених пулів.
  5. Встановіть низький swappiness (і збережіть налаштування), коли впевнитесь, що це покращує активність swap і stalls.
  6. Лише після стабілізації: за бажанням очистіть swap у тихий період, щоб скинути базу.

Мета — не «нульовий swap». Мета — «жодних пам’ятевих stall, жодного thrash і передбачувана латентність». Нудьга — це фіча.

← Попередня
MySQL проти PostgreSQL: чому ALTER TABLE стає кошмаром
Наступна →
Паніка ядра: коли Linux публічно каже «ні»

Залишити коментар