Windows VM на Proxmox повільна: 8 налаштувань (диск/кеш/IO‑потік/драйвери), що мають значення

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

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

Proxmox може запускати Windows швидко — нудно швидко. Але потрібно підкрутити правильні ручки. Не всі. Вісім. І перевіряти варто не «на око», а вимірюваннями, бо Windows може ховати проблеми з диском під «System» у процесах, а Proxmox — під «io=…».

Швидка діагностика (знайдіть вузьке місце за 10 хвилин)

Коли Windows VM повільна, мозок хоче звинуватити Windows. Ваше завдання — визначити, на якому шарі саме відбувається очікування: планування CPU гостьової ОС, накопичення черги в гостьовій ОС, емуляція пристрою QEMU, хостовий IO або бекенд сховища. Найшвидший шлях — триангуляція за затримкою, а не за пропускною здатністю.

По‑перше: вирішіть, чи це планування CPU чи затримка сховища

  • Перевірте поведінку host CPU steal/ready: якщо vCPU не отримують час процесора, усе відчувається як сироп.
  • Перевірте затримку IO на хості: якщо IO повільний, Windows «зависатиме» так, ніби це проблема CPU.

По‑друге: підтвердіть, що VM використовує правильні пристрої та драйвери

  • Windows на SATA/IDE або з загальним драйвером Microsoft — це постійна «данина».
  • Неправильний контролер + відсутність VirtIO = висока CPU‑вартість на операцію IO і неглибокі черги.

По‑третє: ізолюйте, де наростає черга

  • Черга в гості (велика disk queue length), але диск хоста в прості: часто помилка драйвера/контролера або невідповідність режиму кешу.
  • Черга на хості (великий await у iostat) і гостя також повільний: обмеження бекенду сховища.
  • Черга в потоці QEMU (високе навантаження на один ядро хоста): відсутній IO‑потік або неправильний контролер.

Мінімальний порядок дій (робіть у цьому порядку)

  1. На хості: перевірте затримку IO та конкуренцію за CPU (iostat, pvesh/qm status, top).
  2. У конфігурації VM: перевірте контролер (VirtIO SCSI), режим кешу, iothread, discard і тип CPU.
  3. У Windows: підтвердіть, що встановлені драйвери VirtIO і справді використовуються; перевірте disk queue length та використання storport.
  4. На бекенді сховища: перевірте підбір recordsize/volblocksize для ZFS, поведінку sync, налаштування Ceph RBD або параметри LVM та планувальника.

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

Факти та контекст, які пояснюють, чому це відбувається

  • VirtIO існує, бо емуляція «реального» обладнання повільна. KVM швидкий у віртуалізації CPU; емітація пристроїв — це те, за що доводиться платити.
  • IDE історично простий, але не історично швидкий. Емуляція IDE — це підстраховка сумісності; вона «з’їдає» CPU на кожну IO і має неглибокі черги.
  • Стек збереження Windows змінився між версіями. Драйвери на базі Storport і покращення чергування роблять сучасні Windows більш чутливими до правильних віртуальних контролерів.
  • Режими запису в кеш — це контракт на надійність. «Writeback» може бути ракетою або рогаткою залежно від того, чи може хост гарантувати семантику flush.
  • ZFS транзакційний і чесно повідомляє про синхронні записи. Якщо ваші робочі навантаження виконують sync‑запити (багато Windows‑патернів саме такі), ZFS змусить вас платити, якщо ви не спроектували систему під це.
  • Ceph жертвує затримкою заради розподіленої надійності. Він може бути швидким, але дрібні випадкові записи можуть жорстко реагувати на мережевий джиттер і налаштування бекенду.
  • NVMe не призначався для одного потоку. Сучасні SSD хочуть багато черг і паралелізму; однонитковий шлях IO стає новим вузьким місцем.
  • Балонування пам’яті розробляли для щільності, а не для щастя. Воно може «вписати» VM, але Windows погано реагує на раптовий дефіцит пам’яті.
  • Планувальники IO та кеш‑шари можуть ворогувати між собою. Два шари, що «оптимізують» один потік IO, часто означають, що жоден з них цього не робить.

Одна перефразована ідея, приписувана Werner Vogels (CTO Amazon): Все ламається, тому проектуйте системи так, щоб вони працювали, коли частини неминуче виходять з ладу. Налаштування продуктивності подібне: припустіть, що щось застопориться, і зменшіть площу ураження.

Вісім налаштувань, що реально змінюють ситуацію

1) Шина диска та контролер: VirtIO SCSI (і коли не варто)

Якщо диск Windows VM на Proxmox підключений як IDE або SATA, ви вже знайшли одну проблему. Це вибір для сумісності, але не для продуктивності. За замовчуванням «SCSI» може бути хорошим, але тип контролера має значення.

Найкращий дефолт для Windows на Proxmox: VirtIO SCSI контролер (зазвичай virtio-scsi-single для простоти) плюс драйвер VirtIO у Windows.

Чому це важливо: VirtIO — паравіртуалізований пристрій. Він зменшує VM exits, знижує CPU на IO і підтримує глибші черги. Робочі навантаження Windows — особливо багато дрібних читань під час завантаження та оновлень — дуже виграють.

Коли можна вибрати інше:

  • Віртуальний NVMe може бути відмінним для високих IOPS, бо добре відображає сучасну чергувальну архітектуру. В деяких випадках він простіший за SCSI.
  • SATA може підходити, якщо ви застрягли з старим інсталятором Windows і не хочете вбудовувати драйвери — лише як тимчасовий міст.

Моя думка: не відправляйте «тимчасовий міст SATA» у продакшн. Саме так тимчасове стає постійним, як картонний напис на поламаних дверях, що висить два роки.

2) Режим кешу: оберіть один і розумійте наслідки

Режим кешу вирішує, хто може «брехати» про надійність записів. Windows хвилює це. Бази даних хвилюють ще більше. А ваше майбутнє «я» хвилює найбільше.

Типові режими кешу у Proxmox для дисків:

  • cache=none: Загалом найбезпечніший дефолт. Використовує прямий IO, уникає подвійного кешування, коректно обробляє flush‑семантику. Часто кращий для ZFS і Ceph.
  • cache=writeback: Швидше сприймає запис, бо кеш сторінок хоста поглинає їх. Набагато ризикованіше при втраті живлення або краху хоста, якщо немає захисту й правильного оброблення flush.
  • cache=writethrough: Безпечніший за writeback, але часто повільніший.

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

Рекомендація: починайте з cache=none, вимірюйте, і лише потім розглядайте writeback, якщо ви можете захистити історію даних (UPS, enterprise SSD з PLP і ви розумієте стек сховища).

3) IO‑потік: відокремте «повільний шлях» від усього іншого

QEMU має потоки. Емуляція пристрою та обробка virtqueue може перетворитися на один «гарячий» потік, якщо не виділити для цього окрему лінію. Саме для цього потрібні IO‑потоки: вони ізолюють обробку дискового IO від основних vCPU‑потоків.

Симптоми, коли потрібен iothread:

  • VM відчувається «заторможеною» під навантаженням диска, хоча завантаження CPU здається помірним.
  • Одне ядро хоста завалене під час інтенсивного IO, інші — простіють.
  • Піки затримки корелюють з фоновими завданнями (Windows Defender, оновлення, індексація).

Увімкніть iothread для диска (або використайте контролер, що його чисто підтримує). Це одне з тих змін, що не приваблює увагу, але часто очевидне у графіку «до/після».

4) Discard/TRIM та емуляція SSD: припиніть обманювати гостьову ОС

Windows очікує, що він може повідомити сховищу про вільні блоки (TRIM). Якщо гість не може виконувати discard, бекенд може повільно деградувати, особливо на thin‑provisioned томах або SSD‑пулаx, які залежать від інформації про вільні блоки.

Увімкніть discard на віртуальному диску, якщо ваш бекенд це підтримує (ZFS zvols можуть, Ceph RBD може, LVM‑thin може). Потім увімкніть оптимізацію Windows (зазвичай вона робить це автоматично на «SSD»).

Розгляньте емуляцію SSD: повідомлення гостю, що диск — SSD, може змінити поведінку Windows (розклад дефрагментації vs optimize/trim). Це не чарівництво, але дозволяє уникнути зайвої роботи.

Обережно: discard не безкоштовний. На деяких бекендах він створює навантаження. Головне — правильність, потім вимірювання.

5) Драйвери VirtIO та гостьові інструменти: нервова система VM

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

У Windows вам потрібні:

  • Драйвер збереження VirtIO (viostor або vioscsi залежно від контролера)
  • Драйвер мережі VirtIO (NetKVM)
  • Драйвер балона лише якщо ви навмисно використовуєте ballooning (у багатьох середовищах його краще не використовувати)
  • QEMU guest agent для кращих життєвих операцій і іноді для покращення таймінгу

Не «встановіть і забудьте» ISO з драйверами. Підтвердіть, що драйвер активний у Device Manager і що диск використовує очікуваний контролер.

Жарт №1: Windows без драйверів VirtIO — це як спорткар, якому привезли з квадратними колесами: формально рухається, але ніхто не задоволений.

6) Тип CPU та NUMA: припиніть голодувати Windows

Якщо Windows VM повільніє під навантаженням, ви можете платити за консервативні CPU‑флаги або за погану топологію. Proxmox пропонує кілька моделей CPU. Пастка «безпечний‑але‑повільний» — використовувати generic модель, коли «host» був би кращим.

Рекомендація: використовуйте CPU type: host для продуктивних VM у стабільному кластері (або якщо обмеження live migration прийнятні). Це відкриває гостю більше можливостей CPU, покращуючи продуктивність криптооперацій, стиснення та деяких планувальників.

NUMA: Якщо ви даєте VM багато vCPU і RAM, але вона розміщується через NUMA‑вузли без урахування топології, затримки зростають. Windows розподіляє потоки між вузлами; якщо топологія VM невідповідна, з’являються випадкові паузи, що виглядають як проблеми зі сховищем, хоча ними не є.

Правило: не виділяйте VM більшу за розмір NUMA‑вузла, якщо тільки у вас немає причин і розуміння розташування хосту.

7) Балонування пам’яті та своп: смерть від «допомоги»

Балонування заманює: «Ми можемо overcommit, і все буде добре.» Windows не погоджується. Коли пам’ять відбирається, Windows починає власну підкачку, кеші руйнуються, і VM робить IO, щоб компенсувати брак RAM. Ось як проблема пам’яті стає проблемою диска.

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

На хості переконайтеся, що немає свопінгу під навантаженням. Свопінг хоста робить затримки в гості хаотичними, і саме хаотична затримка сприймається користувачами як «повільно».

8) Налаштування беку для сховища (ZFS/Ceph/LVM): узгодьте розмір блоків і черги

Саме сюди зазвичай і прямують пости «моя VM повільна»: бекенд робить рівно те, що ви йому наказали, а не те, що ви мали на увазі. Proxmox абстрагує сховище, але диски все одно підкоряються фізиці, write amplification і семантиці flush.

ZFS (zvols та datasets)

  • volblocksize важливий для zvol. Якщо він невідповідний до навантаження, ви платите в write amplification і затримках.
  • синхронні записи (sync) дорогі без правильного SLOG. Windows може генерувати sync‑подібні шаблони (метадані, журнали, flush додатків).
  • компресія може допомагати або шкодити залежно від CPU і навантаження; на сучасних CPU зазвичай виграш.

Ceph RBD

  • Ceph може забезпечити чудову пропускну здатність, але може мати вищу базову затримку, ніж локальний NVMe.
  • Дрібні випадкові записи чутливі до мережі та продуктивності OSD; «це лише 4k» не заспокоює.
  • Параметри кешу RBD і клієнта можуть змінювати поведінку, але починайте з вимірювання розподілу затримок.

LVM‑thin / локальний SSD

  • Thin provisioning потребує discard, щоб уникнути прихованого тиску в просторі.
  • Перевірте планувальник пристрою і глибину черги; значення за замовчуванням не завжди оптимальні.
  • Слідкуйте за write cliff на споживчих SSD (вичерпання SLC‑кешу). Це виглядає як раптові сплески затримки.

Жарт №2: Якщо ваш бекенд — звичайний споживчий SSD без захисту від втрати живлення, «writeback cache» — це просто пришвидшення вашого оновлення резюме.

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

Це ті завдання, які я справді запускаю, коли Windows VM на Proxmox здається повільною. Кожне містить команду, приклад виводу і яке рішення вона обґрунтовує. Виконуйте їх на хості Proxmox, якщо не зазначено інше.

Завдання 1: Ідентифікувати конфігурацію VM (шина диска, кеш, iothread, discard)

cr0x@server:~$ qm config 104
boot: order=scsi0;ide2;net0
cores: 8
cpu: x86-64-v2-AES
memory: 16384
name: win-app-01
net0: virtio=DE:AD:BE:EF:10:04,bridge=vmbr0,firewall=1
ostype: win11
scsi0: local-zfs:vm-104-disk-0,cache=none,discard=on,iothread=1,ssd=1,size=200G
scsihw: virtio-scsi-single

Що це означає: Диск на VirtIO SCSI single, cache=none, discard=on, iothread увімкнено, SSD‑емуляція увімкнена. Це «правильні» дефолти.

Рішення: Якщо ви бачите ide0, sata0, cache=writeback без історії забезпечення надійності, або відсутнє iothread=1, спочатку виправте конфігурацію VM, а не ганяйтеся за фантомами.

Завдання 2: Підтвердити, що VM справді працює і не «балонить» пам’ять

cr0x@server:~$ qm status 104 --verbose
status: running
cpus: 8
memory: 16384
balloon: 0
uptime: 91234

Що це означає: balloon: 0 означає, що ballooning відключено (фіксована пам’ять). Добре для передбачуваної продуктивності.

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

Завдання 3: Знайти процес/потік, що спалює CPU на хості під час «повільного диска»

cr0x@server:~$ top -H -p $(pgrep -f "kvm.*104" | head -n1)
top - 10:03:11 up 12 days,  5:44,  2 users,  load average: 6.10, 5.92, 5.80
Threads:  52 total,   1 running,  51 sleeping
%Cpu(s): 22.0 us,  3.0 sy,  0.0 ni, 75.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
31241 root      20   0 6143200 902144  21760 S  98.0   1.4  10:22.11 iothread
31200 root      20   0 6143200 902144  21760 S  12.0   1.4   2:13.45 CPU 0/KVM
31201 root      20   0 6143200 902144  21760 S  11.5   1.4   2:11.88 CPU 1/KVM

Що це означає: Присутній iothread і він навантажений. Це нормально, якщо це відповідає реальному дисковому навантаженню. Якщо основний KVM‑потік при IO завжди на 100%, ймовірно, потрібен IO‑потік або кращий контролер.

Рішення: Якщо один QEMU‑потік під час IO прив’язаний до 100%, увімкніть iothread і переконайтеся, що використовується VirtIO SCSI/NVMe.

Завдання 4: Виміряти затримку та черги диска на хості

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

avg-cpu:  %user %nice %system %iowait  %steal  %idle
          10.12  0.00    2.31    8.44    0.00  79.13

Device            r/s     w/s   rkB/s   wkB/s  rrqm/s  wrqm/s  %util  await  r_await  w_await
nvme0n1         220.0   180.0  8800.0  7200.0     0.0     5.0   92.0  18.2    9.1     29.0

Що це означає: await у двозначних числах під навантаженням вказує на реальні затримки. Якщо це бекенд вашої VM і Windows «повільний», швидше за все, межа — бекенд.

Рішення: Якщо %util високий та await високий, лагодьте сховище (швидший носій, кращий макет пулу, SLOG для sync, зменшення write amplification). Якщо диски хоста в порядку, а VM повільна — дивіться конфігурацію VM/драйвери.

Завдання 5: Визначити, який пристрій забезпечує диск VM

cr0x@server:~$ pvesm path local-zfs:vm-104-disk-0
/dev/zvol/rpool/data/vm-104-disk-0

Що це означає: Диск VM — ZFS zvol. Потрібні правила налаштування ZFS.

Рішення: Якщо це ZFS, перевірте volblocksize, поведінку sync і наявність швидкого лог‑пристрою для sync‑важких робочих навантажень.

Завдання 6: Перевірка стану пулу ZFS та сигналів затримки

cr0x@server:~$ zpool status -v rpool
  pool: rpool
 state: ONLINE
  scan: scrub repaired 0B in 00:18:44 with 0 errors on Sun Dec 22 03:12:18 2025
config:

        NAME        STATE     READ WRITE CKSUM
        rpool       ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            nvme0n1 ONLINE       0     0     0
            nvme1n1 ONLINE       0     0     0

errors: No known data errors

Що це означає: Пул здоровий. Здоров’я не означає швидкість, але виключає «резилверинг у дегрейді» як причину проблем.

Рішення: Якщо пул деградований або йде resilvering, очікуйте затримок. Вирішіть проблеми з дисками/пулом перш ніж тонко налаштовувати.

Завдання 7: Перевірити властивості dataset ZFS, що впливають на диски VM

cr0x@server:~$ zfs get -o name,property,value -s local recordsize,compression,atime,sync rpool/data
NAME        PROPERTY     VALUE
rpool/data  recordsize   128K
rpool/data  compression  lz4
rpool/data  atime        off
rpool/data  sync         standard

Що це означає: Recordsize застосовується до datasets, не до zvol, але це підказка щодо загальних налаштувань. Compression увімкнено, atime вимкнено — це зазвичай хороші дефолти.

Рішення: Не «оптимізуйте», встановлюючи sync=disabled для сховища VM, якщо ви не готові погодитися на втрату даних при краху. Краще використайте відповідне обладнання.

Завдання 8: Перевірити volblocksize зvol (критично для IO‑патернів Windows)

cr0x@server:~$ zfs get -o name,property,value volblocksize rpool/data/vm-104-disk-0
NAME                      PROPERTY      VALUE
rpool/data/vm-104-disk-0   volblocksize  8K

Що це означає: 8K volblocksize — часто розумний компроміс для загальних VM‑навантажень. Занадто великий — погіршення дрібних випадкових записів; занадто малий — додаткові метадані.

Рішення: Якщо ви бачите 128K volblocksize на системному диску Windows з великою кількістю дрібних випадкових IO, розгляньте варіант перегенерації диска з меншим volblocksize і міграції.

Завдання 9: Спостерігати IO та тиск затримок ZFS у реальному часі

cr0x@server:~$ zpool iostat -v rpool 1 5
              capacity     operations     bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
rpool       1.20T  600G    800    650   60.0M  48.0M
  mirror-0  1.20T  600G    800    650   60.0M  48.0M
    nvme0n1     -      -   420    330   31.0M  24.0M
    nvme1n1     -      -   380    320   29.0M  24.0M

Що це означає: Ви бачите реальні read/write rate і ops. Якщо Windows «зависає», коли ці числа стрибають, у вас кореляція з дисковою активністю.

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

Завдання 10: Перевірити тиск пам’яті хоста і своп (тихий вбивця затримок)

cr0x@server:~$ free -h
               total        used        free      shared  buff/cache   available
Mem:           256Gi       210Gi        12Gi       2.0Gi        34Gi        38Gi
Swap:           16Gi       3.2Gi        13Gi

Що це означає: Своп використовується. Це може бути історичне використання або активний біль.

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

Завдання 11: Подивитися, чи ядро активно свопить під навантаженням

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
 2  0 3355443 1200000  8000 32000000    0    0   120   220  800 1200 12  3 77  8  0
 3  1 3355443 1150000  8000 31500000    0  256  1024  4096 1200 1800 10  4 65 21  0
 2  0 3355700 1100000  8000 31000000  128  512   900  3800 1100 1600 11  4 62 23  0

Що це означає: Ненульові si/so вказують на активний свопінг. Це інцидент продуктивності у сповільненому режимі.

Рішення: Усуньте тиск пам’яті. Не налаштовуйте режими кешу, щоб компенсувати свопінг; це як міняти тиск в шинах, щоб виправити стукіт в двигуні.

Завдання 12: Перевірити планувальник блочного пристрою і налаштування черги (локальні диски)

cr0x@server:~$ cat /sys/block/nvme0n1/queue/scheduler
[mq-deadline] none

Що це означає: Планувальник — mq‑deadline. Для NVMe це зазвичай нормально. Для деяких масивів «none» кращий; для деяких змішаних навантажень deadline‑тип поведінки допомагає хвостовій затримці.

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

Завдання 13: Перевірити опції диска VM на рівні командного рядка QEMU (перевірка)

cr0x@server:~$ ps -ef | grep -E "kvm.*104" | head -n1
root     31200     1 18 09:40 ?        00:42:10 /usr/bin/kvm -id 104 -name win-app-01 -m 16384 -smp 8 -cpu x86-64-v2-AES ... -device virtio-scsi-pci,id=scsihw0 ... -drive file=/dev/zvol/rpool/data/vm-104-disk-0,if=none,id=drive-scsi0,cache=none,aio=io_uring,discard=unmap ...

Що це означає: Підтверджує ефективні налаштування (cache, discard, aio). Це виявляє розбіжності між тим, що ви думали, що Proxmox встановив, і тим, що QEMU реально запустив.

Рішення: Якщо очікували discard=unmap, а його немає — перевірте налаштування апаратної частини VM і підтримку сховища.

Завдання 14: Швидко перевірити затримки Ceph (якщо використовується RBD)

cr0x@server:~$ ceph -s
  cluster:
    id:     9c1f3a1a-aaaa-bbbb-cccc-1234567890ab
    health: HEALTH_OK

  services:
    mon: 3 daemons, quorum mon1,mon2,mon3
    mgr: mgr1(active), standbys: mgr2
    osd: 12 osds: 12 up, 12 in

  data:
    pools:   4 pools, 256 pgs
    objects: 1.20M objects, 4.6 TiB
    usage:   13 TiB used, 22 TiB / 35 TiB avail
    pgs:     256 active+clean

Що це означає: HEALTH_OK не гарантує низьких затримок, але виключає «кластер у вогні» зі списку.

Рішення: Якщо health не OK (backfill, degraded, повільні операції), припиніть налаштовувати VM і спочатку виправте Ceph. Windows не обганяє повільні операції.

Завдання 15: Підтвердити, що Windows використовує VirtIO драйвер з боку хоста (перевірка через агент)

cr0x@server:~$ qm agent 104 get-osinfo
{
  "id": "mswindows",
  "kernel-release": "10.0.22631",
  "name": "Microsoft Windows 11 Pro",
  "pretty-name": "Microsoft Windows 11 Pro",
  "version": "11"
}

Що це означає: Guest agent працює. Це не чарівний виграш у продуктивності, але дає кращу видимість та надійнішу операційну інтеграцію.

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

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

1) «Windows повільна тільки під час оновлень і перезавантажень»

Симптом: Перезавантаження тривають вічність, оновлення повзуть, «Працюємо над оновленнями» виглядає як життєвий вибір.

Корінь: Оновлення Windows — метадані‑ та flush‑інтенсивні; неправильний контролер, відсутність VirtIO драйвера або затримка sync у ZFS виявляються тут.

Виправлення: Перенесіть системний диск на VirtIO SCSI (або віртуальний NVMe), встановіть драйвер VirtIO storage, використайте cache=none і переконайтеся, що бекенд може справлятися із sync‑запитами (SLOG або краще обладнання).

2) «Бенчмарки чудові, реальні додатки — жах»

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

Корінь: Ви оптимізували під пропускну здатність, а робоче навантаження чутливе до хвостової затримки. Часто: writeback кеш приховує flush‑и або однонитковий шлях IO без iothread.

Виправлення: Увімкніть iothread, віддавайте перевагу cache=none і вимірюйте розподіл затримок (await, не лише MB/s).

3) «Випадкові зависання 2–10 секунд, потім все відновлюється»

Симптом: VM раптово «зависає» ненадовго, особливо під навантаженням; затримка миші/клавіші у консолі.

Корінь: Своп хоста, блокування транзакцій ZFS або піки затримки бекенду сховища (write cliff на споживчому SSD, повільні операції Ceph).

Виправлення: Припиніть свопінг хоста (додайте RAM, зменшіть overcommit), переконайтеся, що сховище не насичене, перевірте повільні операції/резилверинг і уникайте ballooning.

4) «CPU високе, але здається, що вузьке місце — IO»

Симптом: Windows показує високе завантаження CPU; хост показує одне зайняте ядро; метрики диска виглядають помірними.

Корінь: Накладні витрати від емульованих пристроїв (IDE/SATA) або відсутність паравіртуалізованих драйверів, що підвищує CPU на операцію IO.

Виправлення: Перейдіть на VirtIO SCSI/NVMe і встановіть правильні драйвери; увімкніть iothread.

5) «Мережа повільна, але тільки для цієї Windows VM»

Симптом: SMB‑копіювання повільні; інші VM в порядку.

Корінь: Використовується e1000 емуляція або відсутній VirtIO net драйвер; налаштування offload не відповідають.

Виправлення: Використовуйте VirtIO net; встановіть NetKVM драйвер; перевірте MTU і конфігурацію bridge; вимірюйте з iperf‑подібними інструментами (і не плутайте диск з мережею).

6) «Все було нормально, поки ми не увімкнули discard»

Симптом: Періодичні сплески IO після увімкнення discard/trim.

Корінь: Бекенд обробляє discard як реальну роботу (metadata‑оновлення thin provisioning, discards у Ceph або free space maps у ZFS) і ви це проявили.

Виправлення: Залишайте discard (коректність важлива), але плануйте Windows optimize завдання, розгляньте обмеження або переконайтеся, що бекенд масштабований. Якщо discards патологічні, перегляньте конфігурацію бекенду, а не просто вимикайте discard.

Три корпоративні міні‑історії з фронту продуктивності

Міні‑історія 1: Інцидент через хибне припущення

Тікет починався як «Citrix повільний». Завжди так буває. Користувачі скаржилися, що відкриття Outlook у Windows VM займало хвилини. Декілька адміністраторів наполягали, що винна нова політика антивірусу, бо «диск SSD і мережа в порядку». Це припущення — «SSD означає низьку затримку» — стало зерном інциденту.

На хості Proxmox iostat показував помірну пропускну здатність, але неприємні await‑сплески. Windows VM були на ZFS, пул був здоровий. Убитий деталлю: навантаження було sync‑важким через поведінку додатка щодо flush‑ів і те, як Windows оновлює метадані. У пулі не було виділеного log‑пристрою, а пул збудований на mirror vdev із споживчих NVMe без захисту від втрати живлення.

Команда також увімкнула cache=writeback «для швидкості», вважаючи, що «на SSD це безпечно». Під навантаженням система коливалася між швидкими сплесками і затримками, коли flush‑операції «змусили» систему сказати правду. Користувачі бачили випадкові зависання. Хост відчував, що іноді треба відповісти достовірно.

Виправлення було болісно просте і політично неприємне: повернути cache=none, розгорнути enterprise NVMe з PLP і додати швидкий лог‑пристрій для ZFS пулу, де жили sync‑важкі VM. Раптом ті самі VM почали поводитися так, ніби вони в дата‑центрі, а не на шкільному стенді.

Висновок постмортему не був «ZFS повільний» чи «Windows дивний». Він полягав у тому, що стек має контракти. Якщо ви припускаєте, що SSD автоматично забезпечує надійність і низьку латентність, ви будете дебажити людські очікування, а не машини.

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

Інша організація мала змішаний кластер Proxmox: деякі вузли з локальними NVMe, деякі — на Ceph. Вони хотіли «однорідну продуктивність VM», тож стандартизували шаблон VM: VirtIO SCSI, iothread увімкнено, discard увімкнено і один великий віртуальний диск для простоти.

Потім вони ввели агресивне балонування пам’яті по флоту, щоб підвищити щільність. Графіки виглядали чудово. CFO був задоволений. Windows VM — ні.

У пікові години хости забирали пам’ять. Windows реагував підкачкою і падінням кешів. Це створило більше дискових операцій. На вузлах з Ceph це означало більше дрібних випадкових записів і більше метаданих. Зростання IO підняло затримки. Збільшення затримок уповільнило додатки, що збільшило кількість повторних спроб і підвищило навантаження. Це петля продуктивності під виглядом «ефективності ємності».

Вони намагалися «вирішити» це додаванням vCPU. Це лише загострило конкуренцію: більше runnable thread, що конкурують за той самий IO і пам’ять. VM виглядали зайнятими, але зробили менше роботи — класичний момент «ми масштабували проблему».

Зрештою вирішили банально, але ефективно: вимкнули ballooning для Windows servers, зарезервували пам’ять на хості і розділили чутливі навантаження від «галасливих». Щільність трохи впала. Кількість інцидентів упала суттєво. Це називається «він дорослий вибір».

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

Одна команда, з якою мені подобалося працювати, мала ритуал: кожного разу, коли вони розгортали новий вузол Proxmox або змінювали сховище, вони запускали ту ж саму перевірку. Не якийсь великий бенчмарк‑цирк — просто кілька повторюваних чеків: поведінка свопу хоста, iostat await під синтетичним навантаженням і sanity‑перевірка Windows VM, що підтверджує драйвери VirtIO і тип контролера.

Вони також держали шаблони VM строго: ніхто не міг створити Windows на SATA «щоб просто встановити». Шаблон мав VirtIO SCSI і ISO з драйверами; кроки build включали перевірку прив’язки драйвера. Було нудно. Працювало.

Одного кварталу оновлення прошивки сховища внесло тонку регресію латентності. Нічого не падало. Але рутинні тести команди показали вищу хвостову затримку для випадкових записів. Вони призупинили rollout, відкотили прошивку на оновлених вузлах і уникли місяця «користувачі кажуть, що повільно» тикетів, які ніколи не відтворюються, якщо за цим не спостерігаєш.

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

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

Чеклист A: Зробити існуючу повільну Windows VM прийнятною (мінімальний простій)

  1. Зберіть базові метрики: хост iostat -x, хост vmstat, конфіг VM через qm config.
  2. Підтвердіть контролер та опції диска: забезпечте VirtIO SCSI (або NVMe), cache=none, iothread=1, discard=on там, де підтримується.
  3. Встановіть драйвери VirtIO у Windows, якщо їх немає (storage + net). Підтвердіть, що вони активні.
  4. Вимкніть ballooning для чутливих до затримки навантажень; встановіть фіксований обсяг пам’яті.
  5. Переключіть тип CPU на host, якщо дозволяють обмеження міграції; переконайтеся, що кількість vCPU розумна.
  6. Повторно протестуйте під реальним навантаженням і підтвердіть, що затримка на хості покращилась або принаймні стала стабільнішою.

Чеклист B: Новий шаблон Windows VM, що не зганьбить вас потім

  1. Machine type: modern (q35), якщо не потрібна сумісність зі старим обладнанням.
  2. Disk: VirtIO SCSI single (або NVMe), cache=none, iothread=1, discard=on, ssd=1.
  3. Network: VirtIO net.
  4. CPU: host (або узгоджена модель по всьому кластеру, якщо потрібна прозора міграція).
  5. Memory: фіксована; ballooning за замовчуванням вимкнено для Windows app server.
  6. Install: ISO з драйверами VirtIO прикріплений; підтвердження правильних драйверів до завершення складання.
  7. Post‑install: QEMU guest agent встановлений; план живлення Windows налаштований для серверів (уникати агресивного енергозбереження).

Чеклист C: Саніті‑перевірка беку сховища для Windows VM

  1. Підтвердіть здоров’я сховища (немає rebuild/backfill).
  2. Виміряйте затримку (iostat -x) під репрезентативним IO‑навантаженням.
  3. ZFS: перевірте вибір volblocksize перед provisioning; розгляньте SLOG для sync‑важких робочих наборів.
  4. Ceph: слідкуйте за повільними операціями та мережевим джиттером; уникайте змішування критичних за латентністю та масових навантажень без планування.
  5. Thin provisioning: переконайтеся, що discard працює і моніторьте вільне місце.

FAQ

1) Чи використовувати VirtIO SCSI або віртуальний NVMe для Windows на Proxmox?

Якщо хочете безпечний дефолт: VirtIO SCSI (часто virtio-scsi-single) з увімкненим iothread. Якщо ви женетеся за високими IOPS на сучасних Windows і віддаєте перевагу семантиці NVMe, віртуальний NVMe може бути відмінним. Вимірюйте обидва варіанти; не припускайте за замовчуванням.

2) Чи cache=writeback завжди швидший?

Виглядає швидшим, поки не настануть flush‑операції — тоді реальність підпирає з документацією. Використовуйте його лише якщо можете захистити стійкість даних (UPS, правильні flush‑семантики та довірений бекенд).

3) Чому Windows «зависає», коли диск завантажений?

Бо багато UI‑операцій та сервісів Windows залежать від затримки сховища, а не від середнього MB/s. Висока хвостова затримка робить систему завислою, навіть якщо середній потік даних виглядає нормально.

4) Чи допомагає увімкнення discard/TRIM продуктивності?

Воно допомагає коректності і довгостроковій стабільності на thin‑ та SSD‑системах, інформуючи бекенд про вільні блоки. Короткостроково це може додати роботи. Якщо увімкнення discard викликає сплески, це інформація про поведінку вашого бекенду.

5) Скільки vCPU давати Windows VM?

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

6) Чи вмикати ballooning для Windows VM?

Для тест/дев чи низькоприоритетних десктопів — можливо. Для production Windows app server, де люди помічають затримки — зазвичай ні. Фіксована пам’ять дає передбачуваність.

7) Хост IO в порядку, але Windows має велику disk queue length. Чому?

Часто це проблема драйвера/контролера (неправильна шина, відсутність VirtIO) або шлях IO в VM однонитковий і насичує QEMU‑потік. Перевірте тип контролера, iothread і прив’язку драйвера у Windows.

8) Чи може ZFS бути швидким для Windows VM?

Може. Але потрібно поважати синхронні записи і поведінку розмірів блоків. ZFS не прикидається, що sync‑запити дешеві. Якщо навантаження вимагає низької sync‑латентності, проектуйте пул відповідно.

9) Яка зміна має найбільший вплив для повільної Windows VM?

Перехід з емуляції IDE/SATA на VirtIO SCSI (або NVMe) з правильним драйвером VirtIO. Це не тонко.

10) Якщо не можу перевстановити Windows, чи можна змінити контролер?

Зазвичай так, але робіть це обережно: спочатку встановіть драйвери VirtIO, поки старий контролер ще дозволяє завантажуватись, потім додайте новий контролер/мапінг дисків і переключіться на нього. Тестуйте зі снапшотами/бекапами.

Висновок: наступні кроки, що не зіпсують ваші вихідні

Зробіть Windows VM швидкою, виправивши нудні, але важливі речі: контролер диска, контракт кешу, IO‑потоки та драйвери. Потім перевірте, що хост не свопить і що затримки бекенду сховища відповідають людським очікуванням.

Конкретні наступні кроки:

  1. Запустіть qm config <vmid> і підтвердіть VirtIO SCSI/NVMe, cache=none, iothread=1, discard=on там, де підтримується.
  2. Виміряйте затримку хоста з iostat -x 1 під час уповільнення. Якщо await поганий — припиніть підганяти гостя і лагодьте сховище.
  3. Вимкніть ballooning для VM (і усуньте тиск пам’яті на хості), якщо бачите свопінг або поведінку під час вилучення пам’яті.
  4. Стандартизуйте шаблон Windows VM, що випікає правильні контролери/драйвери, щоб наступного кварталу не витрачати час на те саме.

Робота з продуктивністю рідко про геніальне тюнінг. Це про усунення випадкових вузьких місць і відмову від дефолтів, створених для сумісності, а не для швидкості.

← Попередня
ZFS Scrub проти SMART Long Test: що який інструмент виявляє
Наступна →
Proxmox «QEMU завершився з кодом 1»: прочитайте помилку, знайдіть справжню причину

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