Усунення проблем продуктивності Proxmox: CPU steal, IO wait, ZFS ARC і шумні сусіди

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

Проблеми з продуктивністю в Proxmox майже ніколи не з’являються у вигляді одного чистого повідомлення про помилку. Вони виявляються як «база даних ніби пригальмовує», «RDP лагає», «вузли Kubernetes постійно багаторазово перепідключаються», або «чому навантаження хоста 60, коли CPU 10%?» Ви отримаєте суперечливі графіки й впевнені теорії від кожного в кімнаті.

Це польовий посібник, щоб розблокувати глуху точку. Ми відокремимо CPU steal від IO wait, зіставимо поведінку ZFS ARC із реальною затримкою та відшукаємо ту саму шумну VM, яка перетворює ваш вузол на мікрохвильовку у спільному офісі.

Швидкий план діагностики

Щоб знайти вузьке місце, не потрібна панель з 40 графіками. Потрібні три правильні перевірки в правильному порядку і дисципліна припинити гадати.

По-перше: підтвердьте, який саме тип «повільно» це (CPU contention проти сховища проти тиску пам’яті)

  • Хост здається повільним, але CPU виглядає низьким: підозрюйте IO wait, steal time або відновлення пам’яті (swap/kswapd).
  • У VM CPU зашкалює, але на хості CPU ні: підозрюйте обмеження CPU, steal time або невідповідність топології vCPU.
  • Все «добре», доки не почнеться резервне копіювання/реплікація: підозрюйте насичення вводу-виводу та поведінку ZFS transaction group.

По-друге: визначте обмежувач на хості (короткі команди, що не брешуть)

Запустіть на вузлі Proxmox ці команди:

  • Миттєва знімка CPU + steal + iowait: mpstat -P ALL 1 5
  • Тиск пам’яті / swap / reclaim: vmstat 1 10
  • Затримки диска та черги: iostat -x 1 10
  • Поведінка ZFS pool: zpool iostat -v 1 10

По-третє: зіставте з винуватцем — VM або робочим навантаженням

  • VM з найбільшим CPU: qm list + ps -eo pid,cmd,%cpu --sort=-%cpu | head + зіставлення QEMU PID’ів
  • VM з найбільшим IO: iotop -oPa та pvesh get /nodes/$(hostname)/qemu --output-format json
  • Найбільше джерело тиску пам’яті: метрики ballooning і swap на хості, а також «хто виділяє page cache»

Якщо робити тільки одне: виберіть один хост, одне 10‑хвилинне вікно і зафіксуйте наведені знімки. Це ваша базова істина. Все інше — думки.

Ментальна модель, яка тримає вас чесними

Проблеми продуктивності Proxmox зазвичай належать до одного з чотирьох типів:

  1. CPU contention: vCPU хочуть виконуватися; планувальник не встигає видати їм час. На VM це часто проявляється як steal time.
  2. Затримки сховища: CPU простає, бо потоки чекають на диск. Це IO wait, і це не проблема CPU — це проблема конвеєра сховища.
  3. Тиск пам’яті: ARC, page cache, анонімна пам’ять і ballooning конкурують за RAM. Якщо хост свопить, усе стає «таємниче повільним».
  4. Ефекти шумного сусіда: одна VM насичує IO, заливає CPU перериваннями або викликає патологічне write amplification у ZFS, що карає всіх.

Трюк — не змішувати симптоми. Load average включає завдання, що готові до виконання та завдання в незмінному стані D (чекають на IO). Ось чому ви можете мати load 40 і майже простаючий CPU. Це не «Linux бреше». Це ви задали нечітке питання і отримали чесну відповідь.

Одна цитата, яку варто приклеїти до монітора: Парафраз ідеї Демінга: без даних ви — ще одна людина з думкою. Це болісно доречно, коли три команди сперечаються, чи «це мережева проблема».

Цікаві факти та історія, які можна використати

  1. Steal time з’явився на ранньому етапі віртуалізації, щоб кількісно вимірювати, як часто гість був готовий, але гіпервізор запланував когось іншого. Це індикатор боргу планування, не баг гостя.
  2. Linux load average передує сучасним IO-стекам; він рахує задачі в D‑стані, тому важка затримка на диску надуває load, навіть якщо CPU відпочиває.
  3. ZFS ARC — це не «просто кеш». Це самоадаптивний споживач пам’яті з кількома списками (MRU/MFU тощо), і він охоче займає RAM, поки хтось не змусить його інакше поводитися.
  4. ZFS проєктувався з пріоритетом цілісності даних (copy-on-write, контрольні суми, транзакційна семантика). Налаштування продуктивності реальні, але завжди з податком на цілісність.
  5. IOPS стали бізнес-метрикою через віртуалізацію: коли багато малих випадкових потоків IO ділять диски, пропускна здатність перестає бути вузьким місцем, а домінує латентність.
  6. Write amplification — не тільки для SSD. Файлові системи з copy-on-write також можуть посилювати записи, особливо при малих синхронних записах і фрагментації.
  7. Virtio не завжди був стандартом. Парaвіртуалізовані драйвери з’явилися, щоб уникнути емулювання; неправильна модель диска/контролера все ще шкодить продуктивності.
  8. Зміна частоти CPU може імітувати «випадкову продуктивність». Якщо governor агресивно знижує частоту, ваше «те саме навантаження» стає іншим кожну хвилину.
  9. Ballooning вирішив економіку overcommit, але приніс новий режим відмов: хост виглядає «нормально», поки гостьові ОС б’ються, бо біль болю делеговано їм.

CPU steal: коли гість готовий, але не може виконатися

CPU steal — це час, коли vCPU VM хотіла виконуватися, але не змогла, бо планувальник хоста (або інший рівень) не виділив їй CPU. На «залізі» steal майже нульовий. У віртуалізації steal — це визнання: «я в стані конкуренції».

Як проявляється steal і як він може вас обдурити

  • Всередині VM top показує високий %st, але %us не шалений.
  • Застосунки таймаутаються, хоча графіки «використання CPU» виглядають помірковано.
  • Інтерактивна затримка погана: eхо клавіш у SSH повільне, cron‑завдання виконуються із запізненням.

Steal — це не «VM використовує занадто багато CPU». Це «VM не отримує CPU, коли їй потрібно». Це важливо при ухваленні рішення додати ядра, перемістити VM або припинити overcommit.

Типові причини steal у Proxmox

  • Надмірний overcommit: sum(vCPU) значно перевищує фізичні ядра і пікові навантаження збігаються.
  • Обмеження CPU і shares: cgroup‑квоти або CPU units Proxmox можуть змушувати VM голодувати під час конкуренції.
  • NUMA/топологічна невідповідність: великі VM, що охоплюють сокети, доступ до віддаленої пам’яті та кеш‑промахи створюють відчуття «повільного CPU», навіть без великого steal.
  • Частота CPU зафіксована низько: виглядає як конкуренція, поводиться як конкуренція, але фактично це просто занижена тактова частота.

Практична порада: якщо ви бачите стійкий steal вище кількох відсотків під час інциденту, вважайте це реальною проблемою. Переривчастий steal не фатальний; стійкий — так.

Жарт №1: Якщо у вашої VM 30% steal, вона не «краде» — вона чемно чекає, поки хтось інший вкрав її обідні гроші.

IO wait: CPU простає, бо сховище повільне

IO wait означає, що CPU нічого не міг виконувати, бо потоки блоковані на IO. Це не те, що CPU «завантажений». Це те, що CPU безробітний, поки сховище псує всім вихідні дані вихідного вікенду.

Що викликає спайки IO wait у Proxmox

  • Резервні копії/снапшоти/реплікація, що створюють інтенсивні послідовні читання змішані з випадковими записами.
  • Синхронні записи від баз даних або налаштувань NFS, які примушують флешувати.
  • Перевантаження глибини черги на SATA SSD або HDD масивах: латентність зростає до того, як пропускна здатність виглядатиме насиченою.
  • Поведінка ZFS TXG: сплески записів на межах commit можуть виглядати як періодичні затримки.
  • Тонкопровайджене сховище або майже заповнені пули, що призводять до фрагментації й повільніших алокацій.

Як інтерпретувати iowait без самообману

Високий відсоток iowait каже вам: «сховище обмежує прогрес». Це не каже, чи винуватець — пул, контролер, прошивка SSD, файловська система гостя чи одна VM, яка б’є sync‑записами.

Зосередьтеся на метриках латентності: await, svctm (менш корисний на сучасних ядрах), розмір черги й поведінка ZFS по vdev. Графіки пропускної здатності — це заспокійливі оманки, якщо ваш робочий навантаження чутливе до латентності.

ZFS ARC: кеш, тиск пам’яті та пастка swap

ZFS ARC — потужна функція для продуктивності і частий козел відпущення. Він кешує читання, метадані і може радикально зменшити IO на диску. Але на вузлі віртуалізації ARC також політично активний: він конкурує з гостьовими ОС за RAM.

Режими відмов ARC, які ви реально бачите в продакшні

  • Своп хоста: ядро починає свопити, бо ARC + page cache + qemu процеси + усе інше перевищують RAM. Коли хост свопить, латентність поводиться дивно та «випадково».
  • ARC занадто малий: постійні промахи кешу змушують справжні диски виконувати роботу; IO wait зростає; VM підстрибують.
  • ARC занадто великий: VM втрачають пам’ять, запускається ballooning, гості починають свопити, а хост «виглядає нормально», поки додаток горить.
  • Тиск метаданих: багато дрібних файлів або багато datasets можуть роздмухати метадані; ARC стає метаданозалежним і менш ефективним для блоків VM.

Суб’єктивні рекомендації щодо розміру ARC для Proxmox

Якщо ви запускаєте багато VM і хочете передбачуваної поведінки, встановіть максимум ARC. Дозвіл ARC автоматично рости може бути прийнятним на пристрої зберігання; на вузлі віртуалізації з мінливою пам’яттю гостей це шлях до дебагу «примарної повільності».

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

Примітка про SLOG/L2ARC (бо спитають)

Окремий SLOG-пристрій може допомогти із затримкою синхронних записів, якщо у вас sync‑важкі навантаження і ви розумієте ризики та знос. L2ARC підходить для читано‑важких робочих наборів, але споживає RAM для метаданих і може зворотно вплинути, якщо пам’яті й так не вистачає.

Шумні сусіди: як знайти VM, яка псує вам день

«Шумний сусід» — корпоративний евфемізм для «одне робоче навантаження егоїстичне, і всі інші за це платять». У Proxmox шумні сусіди зазвичай проявляються як:

  • Одна VM генерує екстремальні випадкові записи (часто sync‑записи).
  • Одна VM виконує повне сканування диска, індексацію, запуск антивірусу або резервне копіювання всередині гостя.
  • Одна VM насичує CPU високою частотою переривань (атакування пакетами, некоректно налаштоване polling, зайві цикли).
  • Одна VM має надто багато vCPU, створюючи тертя планування для менших VM.

Діагностичний прийом: перестаньте дивитися на середні по хосту й почніть атрибутувати споживання окремим QEMU процесам, потім зіставте з VMID. Більшість «таємничої конкуренції» стає просто ім’ям і власником протягом 15 хвилин.

Практичні завдання: команди, виводи, рішення (12+)

Завдання 1: Знімок використання CPU, iowait і steal по ядрах

cr0x@server:~$ mpstat -P ALL 1 5
Linux 6.8.12-pve (pve01)  12/28/2025  _x86_64_  (32 CPU)

12:01:11 PM  CPU   %usr  %nice   %sys %iowait  %irq %soft  %steal  %idle
12:01:12 PM  all   12.10   0.00   4.20   9.80   0.00  1.10    6.50  66.30
12:01:12 PM    0   22.00   0.00   6.00  18.00   0.00  2.00   10.00  42.00
12:01:12 PM    1    8.00   0.00   3.00   1.00   0.00  0.50    0.00  87.50

Що це означає: %steal 6.5% по всіх CPU вказує на конкуренцію планування для гостей. %iowait 9.8% також вказує, що прогрес обмежений сховищем.

Рішення: Якщо steal стабільно > 5% під час видимого інциденту, вважайте CPU contention реальною проблемою: зменште overcommit vCPU, перемістіть гарячі VM або відкоригуйте ліміти. Якщо iowait також високий — наступним кроком дослідіть сховище.

Завдання 2: Підтвердити тиск пам’яті та свопінг на хості

cr0x@server:~$ vmstat 1 10
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 5  3  262144  18432  10240 8123456  80  120   900  1400  9200 18000 12  4 66 10  8
 3  2  262144  16000  10240 8012345  60  100  1100  1600  9400 17500 10  4 67 12  7

Що це означає: Ненульові si/so вказують на активний свопінг. b (заблоковані процеси) узгоджується з IO wait. Низький free сам по собі не означає проблему; свопінг — означає.

Рішення: Якщо хост свопить, спочатку вирішіть тиск пам’яті: обмежте ARC, припиніть ризикований overcommit ballooning, додайте RAM або зменшіть виділення гостям. Налаштування сховища не врятує, якщо хост сторінкує.

Завдання 3: Виявити ознаки латентності та насичення дисків

cr0x@server:~$ iostat -x 1 5
Linux 6.8.12-pve (pve01)  12/28/2025  _x86_64_  (32 CPU)

Device            r/s   w/s  rkB/s  wkB/s  rrqm/s wrqm/s  %util  await  r_await  w_await
nvme0n1          1200  1800 48000  92000     0.0    0.0   98.5   18.2     6.1     26.4
nvme1n1           110  1600  3200  88000     0.0    0.0   91.0   22.8     4.5     24.1

Що це означає: Високий %util разом з підвищеним await вказують, що пристрої насичені і латентність зростає. Затримки запису особливо високі.

Рішення: Перейдіть до розбиття на рівні ZFS (zpool iostat -v). Якщо await підскакує під час резервного копіювання або реплікації, обмежте/поставте їх у чергу.

Завдання 4: Розбити ZFS IO по vdev, щоб знайти реальний обмежувач

cr0x@server:~$ zpool iostat -v rpool 1 5
              capacity     operations     bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
rpool       3.12T  1.48T  1.20K  1.85K  46.2M  92.8M
  mirror    3.12T  1.48T  1.20K  1.85K  46.2M  92.8M
    nvme0n1     -      -    620    980  23.1M  46.4M
    nvme1n1     -      -    580    870  23.0M  46.4M

Що це означає: Читання/записи збалансовані між mirror‑членами, отже пул поки не «один диск помирає». Якщо один vdev відстає, ви б побачили перекіс.

Рішення: Якщо пропускна здатність і операції високі, але латентність погана, дивіться на sync‑записи, фрагментацію або тиск пам’яті, який спричиняє постійні промахи кешу.

Завдання 5: Перевірити стан пулу, помилки та повільні пристрої

cr0x@server:~$ zpool status -xv
all pools are healthy

Що це означає: Немає очевидних помилок ZFS. Це добре. Але це не означає, що продуктивність добра.

Рішення: Якщо продуктивність погана, але стан хороший — зосередьтеся на формі навантаження, латентності та конкуренції, а не на «диск ламається».

Завдання 6: Спостерігати розмір ARC та сигнали хіт‑рейту

cr0x@server:~$ arcstat 1 3
    time  read  miss  miss%  dmis  dm%  pmis  pm%  mmis  mm%  arcsz     c
12:03:01  4.2K  1.1K    26   210   19   540   49   350   32   52.1G  60.0G
12:03:02  4.0K  1.4K    35   260   19   700   50   440   31   52.4G  60.0G

Що це означає: ARC великий (52G) і обмежений на 60G. Miss rate 26–35% вказує, що диски все ще виконують роботу. Це не обов’язково погано, але це підказка.

Рішення: Якщо miss% високий і IO wait високий, подумайте, чи ARC занадто малий для робочого набору. Якщо хост свопить — ARC занадто великий для реальності вашого хоста.

Завдання 7: Підтвердити swap і облік пам’яті на хості (не довіряйте лише «free»)

cr0x@server:~$ free -h
               total        used        free      shared  buff/cache   available
Mem:           128Gi       109Gi       18Gi       2.1Gi        1.6Gi       15Gi
Swap:           16Gi       256Mi        15Gi

Що це означає: Частина swap використовується. Це не миттєво фатально, але якщо вона зростає або vmstat показує активний свопінг — проблема.

Рішення: Якщо використання swap стабільне і si/so нульові, можна прийняти це. Якщо swap активний — зменште тиск пам’яті до будь‑яких інших налаштувань.

Завдання 8: Визначити топ IO процеси на хості (часто QEMU)

cr0x@server:~$ iotop -oPa
Total DISK READ: 65.20 M/s | Total DISK WRITE: 110.30 M/s
  PID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN  IO>  COMMAND
18342 be/4  root      2.10 M/s  38.70 M/s   0.00 % 92.10%  kvm -id 107 -name vm107 ...
19110 be/4  root      0.40 M/s  26.80 M/s   0.00 % 88.30%  kvm -id 112 -name vm112 ...

Що це означає: Дві VM відповідають за більшість записів. IO> вказує на час, що чекає на IO.

Рішення: Дослідіть VM 107 та 112: що вони роблять, чи це резервні копії, чи бази даних з sync‑записами, чи неправильно налаштовані?

Завдання 9: Зіставити QEMU PID з VMID і підтвердити, що Proxmox бачить ту саму «гарячу» VM

cr0x@server:~$ qm list
      VMID NAME                 STATUS     MEM(MB)    BOOTDISK(GB) PID
       107 db-prod-01           running    32768      256.00        18342
       112 files-prod-02        running    16384      1024.00       19110

Що це означає: PID’и співпадають з виводом iotop. Тепер у вас реальна атрибуція: db-prod-01 і files-prod-02 — важкі писачі.

Рішення: Якщо важкий писач — база даних, оцініть sync поведінку, налаштування кешу і доцільність SLOG. Якщо це файловий сервер — перевірте сканування, бурі rsync або снапшоти.

Завдання 10: Перевірити обмеження CPU, CPU units і ballooning, що можуть створювати конкуренцію

cr0x@server:~$ qm config 107
balloon: 16384
boot: order=scsi0;net0
cores: 16
cpu: x86-64-v2-AES
memory: 32768
name: db-prod-01
net0: virtio=DE:AD:BE:EF:10:07,bridge=vmbr0,firewall=1
scsi0: rpool:vm-107-disk-0,discard=on,iothread=1,ssd=1
sockets: 1

Що це означає: Ballooning увімкнено і може звільняти пам’ять під тиском. Cores=16 може бути занадто багато, якщо хост у конкуренції; велика кількість vCPU підвищує тертя планування.

Рішення: Якщо steal високий, подумайте про зменшення надмірних vCPU для VM, які не масштабуються. Якщо є тиск пам’яті — вимкніть ballooning для критичних низьколатентних робочих навантажень і натомість правильно розмістіть пам’ять.

Завдання 11: Перевірити тактову частоту CPU і тротлінг (класика «чому сьогодні повільно»)

cr0x@server:~$ lscpu | egrep 'Model name|Socket|Thread|CPU\(s\)'
CPU(s):                               32
Model name:                           Intel(R) Xeon(R) Silver 4216 CPU @ 2.10GHz
Socket(s):                            2
Thread(s) per core:                   2
cr0x@server:~$ cpupower frequency-info | egrep 'current CPU frequency|governor'
current CPU frequency: 1200 MHz (asserted by call to kernel)
  governor "powersave" may decide which speed to use

Що це означає: CPU працюють на 1.2GHz під політикою powersave. Це цілком може виглядати як «таємнича конкуренція».

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

Завдання 12: Перевірити тиск на interrupt/softirq (мережеві або сховищні хвилі)

cr0x@server:~$ sar -I SUM 1 3
Linux 6.8.12-pve (pve01)  12/28/2025  _x86_64_  (32 CPU)

12:05:12 PM  INTR    intr/s
12:05:13 PM  SUM     82000.00
12:05:14 PM  SUM     91000.00

Що це означає: Дуже високий рівень переривань може спалювати CPU у softirq і створювати латентність. Це часто з мережевим PPS або з деякими драйверами сховища.

Рішення: Якщо %soft в mpstat високий, дослідіть мережеві мости, налаштування virtio‑net і чи не створює VM бурю пакетів.

Завдання 13: Перевірити kernel логи на таймаути або ресети сховища (детектор брехні «все нормально»)

cr0x@server:~$ journalctl -k --since "30 min ago" | egrep -i 'nvme|blk|zfs|reset|timeout|error' | tail -n 20
Dec 28 11:41:03 pve01 kernel: nvme nvme0: I/O 123 QID 7 timeout, aborting
Dec 28 11:41:03 pve01 kernel: nvme nvme0: Abort status: 0x371
Dec 28 11:41:04 pve01 kernel: blk_update_request: I/O error, dev nvme0n1, sector 123456789 op 0x1:(WRITE) flags 0x0 phys_seg 1 prio class 0

Що це означає: У вас проблеми на рівні пристрою. Налаштування продуктивності недоречне, поки не відновити стабільність апаратури/прошивки.

Рішення: Розглядайте це як інцидент: перевірте прошивку, кабелі, помилки PCIe, стан дисків і поведінку контролера. Плануйте заміну, якщо потрібно.

Завдання 14: Виміряти властивості ZFS dataset, що впливають на IO VM

cr0x@server:~$ zfs get -o name,property,value -r compression,atime,recordsize,sync,logbias rpool | head
NAME               PROPERTY     VALUE
rpool              compression  zstd
rpool              atime        off
rpool              recordsize   128K
rpool              sync         standard
rpool              logbias      latency

Що це означає: atime=off — розумний вибір. recordsize має значення: томи VM часто краще поводяться з меншим recordsize при випадковому IO, але треба вимірювати. sync=standard поважає семантику синхронних записів гостя; змінювати це ризиковано.

Рішення: Не змінюйте sync на disabled заради «швидкості», якщо ви не приймаєте ризик втрати даних формально й отримали погодження бізнесу. Налаштовуйте recordsize і спеціальні пристрої уважно, тестуйте на представницькому IO.

Завдання 15: Підтвердити, що диск VM налаштований правильно (virtio-scsi + iothread проти legacy)

cr0x@server:~$ qm config 112 | egrep 'scsi|sata|ide|virtio|iothread'
scsi0: rpool:vm-112-disk-0,discard=on,iothread=1,ssd=1

Що це означає: Ви на virtio-scsi з IO thread. Це типовий гарний базовий варіант для продуктивності і ізоляції.

Рішення: Якщо бачите sata0 або IDE на чутливих до продуктивності VM — виправте. Емульовані контролери не витончено поводяться у 2025 році.

Три міні-історії з реальних кейсів

Інцидент через неправильне припущення: «Низьке використання CPU означає, що хост нормальний»

Середня компанія мала Proxmox кластер з веб‑аплікаціями і кількома базами даних. Одного ранку on‑call отримав скаргу: «сторінки завантажуються 10 секунд». Графіки CPU хоста виглядали спокійно. Хтось вирішив, що проблема в додатку і почав відкатати деплои.

Натомість середній load був високим. Відкат не допоміг. Люди почали голосніше сперечатися. Команда мережі була втягнута, бо так буває, коли ніхто не довіряє своїй теорії.

Зрештою хтось запустив iostat -x. Під лежачим SATA SSD масив показував високий await і %util на максимумі. Потім iotop вказав на одну VM, яка робила величезні короткі записи. Виявилось, що це «тимчасове» звітування, яке стартувало нічні експорти великих таблиць і стиснення усередині VM, що писало потік малих sync‑блоків на диск VM.

Неправильне припущення було тонким: вони прирівняли «CPU не завантажений» до «система здорова». Насправді CPU чекав на сховище, а сховище розбивав один робочий процес, якого ніхто не вважав «продукцією». Фікс був нудний і ефективний: перенести звітування в непіковий час, обмежити швидкість і перемістити VM в пул з кращою затримкою запису. Відкат — просто театр.

Оптимізація, що відпрацювала проти: «Вимкнемо sync на ZFS і воно полетить»

Інша організація мала PostgreSQL VM, яка скаржилась на латентність записів. Добра людина запропонувала виставити властивість ZFS dataset sync=disabled на том VM, щоб «вирішити» проблему. Бенчмарки виглядали чудово. Всі потиснули руки. Це впровадили в продакшн.

Через два тижні вузол втратив живлення гарячо. Не чисте завершення, не коректний shutdown — просто вимкнення. Коли він повернувся, VM бази завантажилася, але база мала симптоми корупції. Відновлювалися з бекапів, але вікно відновлення було неприємним, і команді довелось пояснювати, чому «хак продуктивності» збільшив ризик втрати даних.

Провал не в тому, що ZFS «поганий». Він зробив те, що обіцяв: змінив контракт на збереження даних. Для деяких навантажень це прийнятно, для інших — катастрофа, і цього не треба робити легковажно.

Вони врешті вирішили проблему класично: перемістили базу на швидші дзеркальні NVMe, перевірили політики write cache і додали SLOG з захистом від втрати живлення після розрахунку витривалості. Урок: оптимізації, що міняють коректність, — не оптимізації, а ризик із паперами.

Сумно, але правильно: резерви єдності і передбачувані ліміти врятували день

Третя команда обслуговувала Proxmox для внутрішніх сервісів. Не гламурно. У них були правила, що здавалися надмірними: тримати ZFS пули нижче певного рівня заповнення, обмежувати ARC на всіх вузлах і забороняти «дай їй 32 vCPU» запити без доведення, що навантаження масштабуються.

Потім стався реальний інцидент: VM вендора після оновлення почала шалено писати логи і постійно їх ротувати. Зазвичай це перетворилося б на кластерну катастрофу продуктивності.

Натомість зона ураження була обмеженою. Оскільки у них був резерв пам’яті і розумні ліміти ARC, хост не почав свопити. Через розумне CPU розмір і ліміти VM не змогла захопити весь вузол. Моніторинг по латентності диска на VM дозволив виявити винуватця за кілька хвилин.

Вони обмежили IO VM і перемістили її на менш критичний вузол, поки вендор не виправив помилку. Ніхто не святкував. Ніхто не писав пост про «героїчну евакуацію». Але продакшн залишився в строю — от і всі переваги нудних практик.

Жарт №2: Найкращий фікс продуктивності — той, що не потребує war room — здебільшого тому, що war rooms працюють на каві й запереченні.

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

1) Load average величезний, але CPU переважно простає

Симптом: load 30–80, CPU idle 60%+, користувачі скаржаться на латентність.

Причина: задачі застрягли в D‑стані, очікуючи на сховище; справжній обмежувач — IO wait.

Виправлення: перевірте з vmstat (високий b, високий wa) і iostat -x (високий await, високий %util); потім знайдіть топ‑IO VM через iotop і обмежте/перемістіть робоче навантаження.

2) VM повідомляє про високий CPU, але CPU хоста здається нормальним

Симптом: гість каже, що CPU завантажений, дашборд хоста не лякає.

Причина: CPU steal або квота/ліміт у cgroups; гість хоче CPU, але йому не дають часу.

Виправлення: перевірте %st у гості і steal в mpstat; перегляньте ліміти/units VM; зменшіть overcommit або перемістіть VM.

3) Паніка «ZFS їсть всю пам’ять»

Симптом: мало «free» пам’яті, великий ARC, люди хочуть «відключити ARC».

Причина: нерозуміння обліку пам’яті в Linux; справжня проблема — свопінг або тиск reclaim, а не низький free RAM.

Виправлення: перевірте vmstat на si/so, перевірте available пам’ять; обмежте ARC, якщо хост свопить; інакше ігноруйте «free» і зосередьтеся на латентності та hit rate.

4) Випадкові періодичні «затримки» кожні кілька секунд/хвилин

Симптом: додатки на кілька секунд заморожуються, потім відновлюються, повторюється.

Причина: сплески ZFS TXG commit, снапшоти/реплікація або поведінка контролера кеш‑флеш.

Виправлення: звірте з zpool iostat 1 і графіками розкладу бекапів; обмежте роботу; подумайте про швидші vdev або відокремлення трафіку бекапів; перевірте стабільність прошивки дисків.

5) Продуктивність погіршилася після «тонкої настройки recordsize»

Симптом: більше IOPS, гірша латентність; або краще послідовне, гірше випадкове.

Причина: невідповідність recordsize до патерну IO; для томів VM сліпе змінення може збільшити ампліфікацію записів і фрагментацію.

Виправлення: поверніться до раціональної бази; вимірюйте на реальному навантаженні; налаштовуйте по dataset і враховуйте розбіжності між zvol і dataset.

6) Резервні копії щовечора руйнують продакшн

Симптом: інциденти опівночі; вдень все добре.

Причина: читання резервних копій насичує пул і конкурує з латентністю записів; ланцюги снапшотів і стиснення підсилюють роботу.

Виправлення: розкладіть і обмежте; відокреміть сховище для бекапів; обмежте паралельні бекапи; розгляньте відвантаження важких читів на реплікаційні вузли.

7) «Додали L2ARC і тепер стало повільніше»

Симптом: латентність зросла, тиск пам’яті виріс після додавання кеш-пристрою.

Причина: накладні витрати метаданих L2ARC споживають RAM; кеш повільно «прогрівається»; пристрій додає конкуренцію.

Виправлення: видаліть L2ARC, якщо у вас немає доведеного чита‑важкого робочого набору, що не вміщується в ARC, і якщо у вас є вільна RAM.

Контрольні списки / покроковий план

Чеклист A: коли користувачі кажуть «все повільно»

  1. На хості: зафіксуйте mpstat, vmstat, iostat -x і zpool iostat протягом 2–5 хвилин.
  2. Якщо steal високий: зменшіть конкуренцію за CPU (перемістіть VM, зменшіть vCPU, перевірте ліміти, змініть governor).
  3. Якщо iowait високий: знайдіть топ IO VM (iotop), потім з’ясуйте характер навантаження (backup, DB, scan, replication).
  4. Якщо swap активний: зупиніть кровотечу (обмежте ARC, зменшіть ballooning, звільніть пам’ять, мігруйте VM), потім вирішіть ємність.
  5. Перевірте логи ядра на помилки/таймаути сховища. Якщо вони є — припиніть налаштування і зробіть апаратну/драйверну стабілізацію пріоритетом №1.

Чеклист B: коли одна VM повільна, а інші в порядку

  1. Всередині VM: перевірте top на %st і %wa.
  2. На хості: зіставте VMID з PID (qm list) і спостерігайте CPU/IO цього PID (ps, iotop).
  3. Підтвердіть тип диска/контролера: virtio-scsi з iothread для IO‑важких VM.
  4. Перевірте ліміти CPU/ballooning, що можуть непомітно обмежувати VM.
  5. Якщо це БД: перевірте, чи навантаження синхронно‑записне; розгляньте сховище, призначене для низької латентності записів, а не лише «швидкої послідовності».

Чеклист C: перед зміною налаштувань ZFS на продакшн вузлі

  1. Запишіть поточні властивості dataset/zvol, які плануєте змінити.
  2. Визначте метрики успіху: p99 latency, час запиту, fsync time, вікно бекапу, host iowait, ARC hit%.
  3. Змінюйте по одному параметру, бажано на одній VM або dataset.
  4. Майте план відкату, що займає хвилини, а не години.
  5. Ніколи не міняйте durability заради швидкості без явного погодження бізнесу (sync=disabled — це не «опція налаштування», а перепис контракту).

Поширені запитання

1) Який відсоток CPU steal вважається «поганим»?

Універсального порогу немає, але стійкий steal вище ≈5% під час видимої затримки користувача — сильний сигнал конкуренції. Переривчастий steal — звичне явище; стійкий — проблема ємності або планування.

2) Чому load average високий, коли використання CPU низьке?

Бо load рахує задачі, готові до виконання, і задачі, що в незмінному стані (зазвичай чекають на IO). Висока латентність IO піднімає load без високого CPU.

3) Чи варто вимикати atime у ZFS?

Для томів VM і більшості серверних навантажень atime=off зазвичай правильне рішення, щоб уникнути зайвих записів. Якщо у вас є робоче навантаження, що залежить від atime, залиште його ввімкненим лише для того dataset.

4) Чи «краде» ZFS ARC пам’ять у VM?

ARC агресивно використовує доступну пам’ять за замовчуванням, але вона може бути звільнена. Справжня проблема — коли хост свопить або ballooning штовхає гості в swap. Обмежте ARC, якщо хост під тиском пам’яті.

5) Чи корисно додавати L2ARC SSD на Proxmox?

Іноді так, але не за замовчуванням. L2ARC споживає RAM для метаданих і допомагає переважно читано‑важким робочим наборам, що не вміщаються в ARC. Якщо у вас мало RAM, L2ARC часто погіршить продуктивність.

6) У мене високий IO wait. Чи означає це, що потрібні швидші диски?

Можливо, але спочатку з’ясуйте характер IO. Одна VM з синхронними випадковими записами може наситити відмінне обладнання. Знайдіть винуватця, патерн доступу і чи відповідає ваш план зберігання цим патернам.

7) Чи давати кожній VM багато vCPU «про всяк випадок»?

Ні. Надмірні vCPU збільшують тертя планування і можуть погіршити хвостову латентність для всіх. Починайте з меншого, вимірюйте і масштабируйте vCPU лише коли навантаження це підтверджує.

8) Чи повинні резервні копії Proxmox завжди шкодити продуктивності?

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

9) Як швидко знайти noisy‑neighbor VM на вузлі?

Використайте iotop -oPa щоб знайти IO‑важкі QEMU процеси і зіставте їхні PID з VMID через qm list. Для CPU‑конкуренції використайте mpstat і ps сортування за CPU, потім зіставте.

10) Чи варто вимикати ballooning?

Для критичних низьколатентних VM часто так — ballooning може створити непередбачуваний тиск пам’яті. Для менш критичних навантажень ballooning підвищує щільність. Головне — уникати свопінгу хоста будь‑якою ціною.

Висновок: наступні кроки, що справді допомагають

Якщо ваш Proxmox вузол повільний — припиніть суперечки і почніть атрибутувати: зафіксуйте mpstat, vmstat, iostat -x і zpool iostat. Визначте, чи обмежувач — планування CPU (steal), латентність сховища (iowait + await) або тиск пам’яті (swap/reclaim). Потім назвіть головного винуватця VM за допомогою iotop і qm list.

Далі зробіть непривабливі, але правильні кроки: обмежте ARC, щоб захистити хост, зупиніть свопінг хоста, правильно розмістіть vCPU і обмежте бекапи. Лише після діагностики переходьте до архітектурних змін: швидші vdev, окремі пули для чутливих робочих навантажень або додавання правильно інженерного SLOG. Налаштування продуктивності без діагностики — це імпровізовані витрати.

← Попередня
Debian 13: зміна порту SSH — виправити порядок sshd і фаєрволу без блокування доступу (випадок №87)
Наступна →
Виправити pvestatd.service у Proxmox: швидко відновити графіки та статистику

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