Більшість «таємниць» продуктивності Proxmox+ZFS насправді не таємниці. Це — стандартні налаштування. Налаштування, обрані, щоб бути безпечними, універсальними та сумісними — але потім тихо застосовані у вашій дуже конкретній реальності зберігання: споживчі SSD з ненадійним захистом від втрати живлення, RAIDZ-пули з випадковим I/O, гостьові ОС, що виконують sync-записи, і гіпервізор, який любить кешувати поверх уже кешованого.
Якщо ваші ВМ здаються швидкими до того моменту, коли перестають бути такими — коли відбувається контрольна точка бази даних, оновлення Windows або вікно резервного копіювання і все перетворюється на «гіперцукор» — це для вас. Ми змінимо ті значення за замовчуванням, які дійсно важливі, пояснимо чому та покажемо, як довести результати командами, що не брешуть.
Мислення: припиніть задовольнятися зберіганням «в моїй лабораторії працює»
ZFS має свою думку щодо дизайну. Proxmox теж має свою. Ваш робочий навантаження також має свою думку — особливо якщо воно включає бази даних, поштові сервери, CI-ранери або будь-що, що виконує багато маленьких sync-записів. Коли ці три думки не збігаються, ви отримуєте стрибки затримки, які виглядають як «випадкова повільність», і тратите дні, звинувачуючи невірний шар.
Ключова пастка — припущення, що віртуалізація «випрямляє» речі. Насправді вона робить протилежне. Віртуалізація множить різні патерни I/O — послідовні, випадкові, вибухоподібні, sync-важкі, метадані-важкі — і мультиплексує їх у спільний пул. Цей пул повинен давати обіцянки: обіцянки надійності (семантика sync), обіцянки розподілу (copy-on-write), обіцянки кешування (ARC/L2ARC) і обіцянки справедливості (планувальник). Параметри за замовчуванням — це точка старту, а не стратегія.
Ось рамка, яку я використовую в продакшені:
- Знайте, які записи мають бути безпечними. Якщо гість попросив sync, вважайте, що це важливо, доки ви свідомо не обмінюєте надійність на швидкість.
- Підібрати розмір блоків до реальності. ZFS не може прочитати те, що не було записано. Якщо ви обираєте volblocksize, який конфліктує з навантаженням, ви платитимете вічно.
- Мінімізуйте «подвійну роботу». Подвійне кешування, подвійні контрольні суми, подвійні CoW-шари: кожен окремо може бути виправданий; разом вони — податок.
- Вимірюйте на правильному шарі. iostat всередині гостя може виглядати нормально, поки хост палає. І навпаки: ZFS може виглядати нормально, поки гість робить патологічні fsync-цикли.
Цікаві факти та історичний контекст (коротко, корисно)
- ZFS зробив звичним end-to-end checksumming у масових розгортаннях, перетворивши мовчазну корупцію з «міфічної» на «вимірювану». Це змінило підхід операційних команд до довіри до зберігання.
- Copy-on-write (CoW) — причина дешевих знімків (snapshots), а також причина того, чому випадкові записи можуть бути дорогими — особливо на RAIDZ під віртуалізацією.
- Compression на ZFS часто є функцією продуктивності, а не лише економії місця, бо менше байтів для переміщення може перекрити вартість CPU (особливо з lz4).
- «Sync-записи повільні» раніше залишалися проблемою баз даних; ZFS зробив це системним питанням, строго дотримуючись семантики sync.
- SLOG-пристрої стали окремою нішею, бо люди боляче вивчали, що «просто SSD» ≠ «безпечний, низьколатентний лог-пристрій».
- Proxmox перевів багатьох користувачів з LVM-thin на ZFS через зручність знімків і реплікації — поки не виявили, як значення за замовчуванням впливають на затримки.
- Індустрія роками переосмислювала write amplification: маленькі випадкові записи на CoW-файлових системах можуть розростися в значно більшу фізичну роботу, особливо з паритетними RAID.
- Помилки ashift — назавжди (фактично): якщо ви створили пул з неправильною припущеною фізичною розмірністю секторів, продуктивність може бути назавжди обмежена.
Стандартні налаштування Proxmox+ZFS, яким варто одразу не довіряти
1) Поведінка sync: її більше не можна ігнорувати
Стандартні налаштування Proxmox не врятують вас від затримок sync-записів. Ваші гості можуть виконувати sync-запити (fsync, O_DSYNC, barriers/flushes), і ZFS трактуватиме ці записи як «мають бути стійкими при відключенні живлення». Якщо у вас немає SLOG і ваш пул на HDD або насичених SSD, sync-важкі навантаження почуватимуться як будинок з привидами.
Але найгірше — це неоднозначність: деякі навантаження стають sync-важкими тільки в певні фази — коміти бази даних, скидання журналів, резервне копіювання ВМ, що тригерить поведінку файлової системи. Тож ви отримаєте періодичні страждання та хибне відчуття «переважно все нормально».
Рішення: якщо вам важлива надійність, залишайте sync=standard і будуйте пул, щоб витримувати це. Якщо не важлива (лабораторія, епhemeral CI), ви можете свідомо обрати sync=disabled — ніколи випадково.
2) volblocksize: налаштування, яке тихо визначає економіку I/O
ZVOL мають volblocksize. Datasets мають recordsize. Люди їх плутають, а потім дивуються, чому їхні тюнінги не дали результату.
volblocksize встановлюється при створенні zvol і фактично постійний (ви можете змінити його, але вже записані блоки не переписуються; зазвичай потрібна міграція, щоб повністю скористатися змінами). Proxmox часто створює zvol з дефолтним значенням, яке може не відповідати вашому навантаженню.
Типові рекомендації (не догма):
- 16K: часто підходить для загальних дисків VM, змішаних навантажень і баз даних з великою кількістю маленьких випадкових I/O.
- 8K: може допомогти для особливо sync-важких або лог-орієнтованих патернів, але може збільшити накладні витрати на метадані.
- 64K/128K: чудово для великих послідовних навантажень (медіа, резервні копії), часто помилково для системних дисків ОС.
На RAIDZ менші блоки можуть бути особливо болісними через паритет і поведінку read-modify-write. Саме тут народжуються чутки «ZFS повільний».
3) Compression: не витягайте продуктивність зі столу
Якщо ви не використовуєте compression=lz4 на сховищі ВМ, ви фактично обираєте переміщати більше байтів, ніж потрібно. Для багатьох навантажень ВМ (файли ОС, логи, текст, пакети) стиснення зменшує фізичний I/O і покращує затримку під навантаженням.
Стиснення може нашкодити на CPU-обмежених хостах або при нескомпресованих даних (зашифровані томи, стиснені медіа). Але для більшості гіпервізорів Proxmox lz4 — це дефолт, який варто бажати.
4) atime: смерть від тисячі читань
atime=on означає, що читання стають записами, бо оновлюється час доступу. На сховищі ВМ це зазвичай марна активність. Якщо ви цінуєте ресурс SSD і затримку, встановіть atime=off для dataset ВМ.
5) Primary cache: подвійне кешування — це не характеристика
ZFS ARC агресивно кешує. Гості також кешують. Якщо дозволите ZFS кешувати дані ВМ, які гість знову закешує, ви витрачатимете пам’ять з обох боків і отримаєте менш ефективне кешування загалом.
Типовий підхід: для дисків VM на базі zvol розгляньте primarycache=metadata (кешувати метадані, а не дані), щоб зменшити подвійне кешування. Це ситуативно: якщо ваші гості малі, а хост має величезну RAM, кеш даних може і допомогти. Але вирішувати потрібно свідомо.
6) Thin provisioning: «вільне місце» — соціальна конструкція
Thin zvols виглядають як ефективність доти, доки пул не опиниться на краю прірви. Коли ZFS-пул сильно заповнюється, продуктивність може впасти через тиск на алокацію і фрагментацію. «Але в нас ще 15% вільно!» — так люди говорять незадовго до поганого дня.
Операційне правило: зберігайте значущий обсяг вільного місця. Для багатьох пулів з великою кількістю ВМ вважайте нормою 20–30% вільного. Якщо це здається марнотратним, ви незабаром відчуєте, як виглядає екстрене придбання сховища.
Жарт #1: RAIDZ з майже повним пулом — як зустріч, яка «могла бути листом». Вона триває, повільніє, і ніхто не може піти.
ZVOL проти файлів у dataset (raw/qcow2): оберіть найменш погане для вашого використання
ZVOL (блокові пристрої): простий шлях, чіткі семантики
ZVOL — це блокові пристрої, підкріплені ZFS. Proxmox їх любить, бо знімки й реплікація інтегруються чисто, і ви уникаєте частини дивної поведінки «файлова система на файловій системі».
Торгівлі:
- volblocksize має велике значення, і у вас не безкінечні повторні спроби.
- Поводження з Discard/TRIM може бути складним залежно від версій та налаштувань. Потрібно перевірити, що звільнення місця дійсно працює.
- Семантика кешування (primarycache) стає важливою, щоб не конкурувати з гостем.
Файли dataset (raw/qcow2): гнучкість з додатковим шаром
Зберігання дисків ВМ як файлів у dataset може бути цілком пристойним. Головний ризик — насладання CoW-шарів (qcow2 — CoW; ZFS — CoW). Це може посилити фрагментацію і накладні витрати на метадані, особливо при випадкових записах.
Рекомендації за позицією:
- Віддавайте перевагу raw перед qcow2 на ZFS, якщо вам не потрібна конкретна функція qcow2.
- Використовуйте qcow2 обережно для нішевих випадків (с sparse + внутрішні знімки), але розумійте, що платите за цю гнучкість.
Як швидко вирішити
- Якщо у вас бази даних або чутливі до затримки сервіси: zvol з адекватним volblocksize та планом для sync-записів.
- Якщо у вас переважно послідовні великі дані: файли в dataset можуть бути прийнятними, налаштуйте recordsize і тримайте все просто.
- Якщо у вас багато маленьких ВМ і ви цінуєте простоту управління: з більшим шансом zvols легше розуміти в інструментах Proxmox.
Зміни, які я роблю в перший день (і чому)
Зміна 1: Увімкніть compression=lz4 на сховищі ВМ
Робіть це, якщо немає доказів протилежного. lz4 має низьку латентність, а диски ВМ зазвичай стискувані. Перевага найкраще помітна під навантаженням, коли пул зайнятий.
Зміна 2: Вимкніть atime для dataset ВМ
Це класичне «дрібне» налаштування, що запобігає марним операціям. Сховище ВМ не потребує записів часу доступу.
Зміна 3: Явно вирішіть політику sync
Більшість людей випадково працюють з sync=standard на обладнанні, яке не може це витримати, а потім «виправляють» вимкненням sync глобально й забувають про це. Не будьте тим, хто так робить.
Оберіть одне:
- Дорога надійність:
sync=standard, додайте належний SLOG за потреби й перевірте затримки. - Швидкість за будь-яку ціну:
sync=disabledна конкретних dataset/zvol, де втрата даних допустима.
Зміна 4: Встановіть primarycache обдумано для сховища з великою кількістю zvol
Якщо хост обмежений за пам’яттю, ARC, що конкурує з гостями, — як бій ножами. Для багатьох дисків VM на zvol, primarycache=metadata є розумним дефолтом. Якщо у вас велика RAM і переважно read-орієнтовані гості, кеш даних може допомогти. Вимірюйте, а не орієнтуйтеся на відчуття.
Зміна 5: Припиніть переповнювати пулив
Запишіть це: пул ZFS на 85–90% заповнення — це не «нормально». Це інцидент з латентністю, про який ви вже попереджені.
Зміна 6: Використовуйте правильні опції диска в віртуалізації (і перевіряйте)
Налаштування диска Proxmox як-от cache, discard, iothread та модель контролера мають значення. Але «мають значення» означає «виявляються у вимірах», а не «звучать круто в форумі». Ваш базовий стан має бути стабільна затримка й передбачувана поведінка при відмовах.
Жарт #2: Увімкнути всі перемикачі продуктивності одночасно — це як випити п’ять енергетиків, щоб «краще спати». Ви дізнаєтеся щось, але не те, чого хотіли.
Практичні завдання: команди, виводи та рішення
Ось реальні перевірки, які я виконую на хості Proxmox, коли сховище ВМ повільне, непослідовне або підозріло «добре до моменту, коли ні». Кожне завдання включає команду, приклад виводу, що означає вивід, і наступне рішення.
Завдання 1: Визначте пули, їхній стан і очевидні червоні прапори
cr0x@server:~$ zpool status
pool: rpool
state: ONLINE
status: Some supported features are not enabled on the pool.
action: Upgrade the pool to enable all features.
scan: scrub repaired 0B in 00:12:44 with 0 errors on Sun Dec 22 03:12:26 2025
config:
NAME STATE READ WRITE CKSUM
rpool ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ata-SAMSUNG_SSD_1TB_A ONLINE 0 0 0
ata-SAMSUNG_SSD_1TB_B ONLINE 0 0 0
errors: No known data errors
Що це означає: Пул онлайн, помилок немає, scrub чистий. Попередження про фічі не є само по собі проблемою продуктивності.
Рішення: Якщо ви бачите degraded vdevs, checksum errors або постійні resilver, припиніть тюнінг і спочатку виправте апарат. Налаштування продуктивності на несправному пулі — це креативний шлях отримати незвичні звіти про простої.
Завдання 2: Перевірте заповненість пулу (тихий вбивця продуктивності)
cr0x@server:~$ zfs list -o name,used,avail,refer,mountpoint -r rpool
NAME USED AVAIL REFER MOUNTPOINT
rpool 720G 180G 104K /rpool
rpool/data 680G 180G 104K /rpool/data
rpool/data/vmdata 640G 180G 96K /rpool/data/vmdata
Що це означає: ~80% використано. Ви входите в зону, де фрагментація й накладні витрати на алокацію починають проявлятися.
Рішення: Якщо ви вище ~80–85% на пулі з великим навантаженням ВМ, плануйте роботу з ємністю зараз: додайте vdevs, перемістіть холодні ВМ або розділіть навантаження. Не намагайтеся «оптимізувати» фізичні обмеження.
Завдання 3: Перевірте критичні властивості dataset (compression, atime, sync)
cr0x@server:~$ zfs get -o name,property,value -s local,default compression,atime,sync,primarycache rpool/data/vmdata
NAME PROPERTY VALUE
rpool/data/vmdata compression off
rpool/data/vmdata atime on
rpool/data/vmdata sync standard
rpool/data/vmdata primarycache all
Що це означає: Compression вимкнено і atime увімкнено: ви платите зайвий I/O. sync standard: діє семантика надійності. primarycache all: ARC може подвійно кешувати дані гостя.
Рішення: Увімкніть compression=lz4 і atime=off на dataset ВМ, якщо немає причин інакше. Оцініть primarycache залежно від навантаження пам’яті і кешування в гостях.
Завдання 4: Застосуйте безпечні, відкотні зміни dataset (lz4 + atime off)
cr0x@server:~$ sudo zfs set compression=lz4 atime=off rpool/data/vmdata
cr0x@server:~$ zfs get -o name,property,value compression,atime rpool/data/vmdata
NAME PROPERTY VALUE
rpool/data/vmdata compression lz4
rpool/data/vmdata atime off
Що це означає: Майбутні записи будуть стиснені; оновлення часу доступу припинять генерувати зайві операції.
Рішення: Зазвичай це загальна вигода. Якщо CPU стане вузьким місцем (рідко з lz4), ви побачите це в метриках CPU хоста під I/O навантаженням.
Завдання 5: Перелічіть zvol і перевірте volblocksize
cr0x@server:~$ zfs list -t volume -o name,volblocksize,used,refer,logicalused -r rpool/data/vmdata
NAME VOLBLOCKSIZE USED REFER LOGICALUSED
rpool/data/vmdata/vm-101-disk-0 128K 64G 64G 120G
rpool/data/vmdata/vm-102-disk-0 8K 20G 20G 22G
Що це означає: У вас різні volblocksize. 128K-диск ОС часто погано поводиться для випадкового I/O. LOGICALUSED > REFER вказує на компресію/знімки або ефекти thin provisioning.
Рішення: Для загальних VM-дисків стандартизуйте (часто 16K), якщо немає виміреної причини інакше. Для існуючих дисків плануйте міграцію, щоб повністю отримати користь.
Завдання 6: Перевірте, чи ви зловживаєте sync семантикою (стрибки затримки)
cr0x@server:~$ sudo zpool iostat -v rpool 1 5
capacity operations bandwidth
pool alloc free read write read write
---------- ----- ----- ----- ----- ----- -----
rpool 720G 180G 150 980 12.4M 5.1M
mirror-0 720G 180G 150 980 12.4M 5.1M
ata-SAMSUNG_SSD_1TB_A - - 75 490 6.2M 2.6M
ata-SAMSUNG_SSD_1TB_B - - 75 490 6.2M 2.6M
Що це означає: Помірний bandwidth, але багато write operations: класичне навантаження малих записів. Якщо під час цього спостерігається погана затримка, sync-записи можуть змушувати чекати.
Рішення: Далі проінспектуйте затримку ZFS і поведінку sync (завдання нижче). Якщо це хост бази даних, вважайте, що sync важливий, поки не доведено протилежне.
Завдання 7: Перевірте затримку ZFS безпосередньо
cr0x@server:~$ sudo zpool iostat -rlv rpool 1 3
read write
pool r/s w/s rMB/s wMB/s rlat wlat cholat dlat
---------- ---- ---- ----- ----- ---- ---- ------ ----
rpool 120 950 10.1 4.9 2ms 38ms 42ms 1ms
Що це означає: Затримка запису ~38ms, вища під навантаженням. Це «ВМ почуваються пригальмовано» — особливо для метаданих і журналів.
Рішення: Якщо wlat регулярно підскакує в десятки/сотні мілісекунд, потрібно вирішувати питання sync-шляху, насичення пулу або поведінки пристрою (прошивка/PLP). Налаштування гостей цього не виправить.
Завдання 8: Перевірте, чи взагалі у вас є окремий лог (SLOG)
cr0x@server:~$ zpool status -v rpool
pool: rpool
state: ONLINE
config:
NAME STATE READ WRITE CKSUM
rpool ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ata-SAMSUNG_SSD_1TB_A ONLINE 0 0 0
ata-SAMSUNG_SSD_1TB_B ONLINE 0 0 0
errors: No known data errors
Що це означає: Немає секції logs. Sync-записи потрапляють на основні vdev.
Рішення: Якщо у вас sync-важкі навантаження і болить затримка, оцініть придбання належного SLOG (з дзеркалом, захистом від втрати живлення). Якщо у вас немає PLP, ви просто купуєте нові способи швидко втратити дані.
Завдання 9: Перевірте тиск ARC і реальний стан пам’яті
cr0x@server:~$ grep -E 'MemTotal|MemFree|MemAvailable' /proc/meminfo
MemTotal: 131900192 kB
MemFree: 4021184 kB
MemAvailable: 18944128 kB
cr0x@server:~$ cat /proc/spl/kstat/zfs/arcstats | egrep '^(size|c |c_min|c_max|hits|misses) '
size 4 82463313920
c 4 85899345920
c_min 4 4294967296
c_max 4 85899345920
hits 4 2840093011
misses 4 390129220
Що це означає: ARC ≈82G, може зрости до ≈85G. MemAvailable ≈18G свідчить, що хост не голодує, але гості можуть.
Рішення: Якщо хост свопить або MemAvailable постійно мізерний, зменшіть ARC (або додайте RAM). Якщо гості позбавлені пам’яті, розгляньте primarycache=metadata для zvol дисків ВМ, щоб хост припинив «занадто допомагати».
Завдання 10: Перевірте, чи увімкнено discard/TRIM наскрізно
cr0x@server:~$ lsblk -D
NAME DISC-ALN DISC-GRAN DISC-MAX DISC-ZERO
sda 0 512B 2G 0
sdb 0 512B 2G 0
cr0x@server:~$ sudo zpool get autotrim rpool
NAME PROPERTY VALUE SOURCE
rpool autotrim off default
Що це означає: Диски підтримують discard, але autotrim пулу вимкнено.
Рішення: Розгляньте увімкнення autotrim на SSD пулах, де звільнення місця важливе і ваше навантаження не постраждає від додаткової активності trim. Потім перевірте, чи увімкнено discard у Proxmox для дисків ВМ.
Завдання 11: Увімкніть autotrim (якщо доречно) і спостерігайте
cr0x@server:~$ sudo zpool set autotrim=on rpool
cr0x@server:~$ sudo zpool get autotrim rpool
NAME PROPERTY VALUE SOURCE
rpool autotrim on local
Що це означає: Пул передаватиме trims далі. Це може допомогти довгостроковій продуктивності SSD і поведінці місця.
Рішення: Якщо увімкнення trim корелює зі стрибками затримки на деяких SSD, вимкніть його й натомість виконуйте планові trims у тихі вікна.
Завдання 12: Перевірте фрагментацію (особливо на довгоживучих VM пулах)
cr0x@server:~$ zpool list -o name,size,alloc,free,frag,cap,dedupratio
NAME SIZE ALLOC FREE FRAG CAP DEDUP
rpool 900G 720G 180G 42% 80% 1.00x
Що це означає: 42% фрагментації не катастрофа, але може додавати до випадкової I/O-затримки на навантажених пулах, особливо в поєднанні з високим заповненням.
Рішення: Якщо frag висока і пул також повний, припиніть експерименти. Плануйте міграцію або розширення. «Тюнінг» фрагментації — це здебільшого управління ємністю в іншому вбранні.
Завдання 13: Перевірте, чи випадково увімкнено dedup
cr0x@server:~$ zfs get -o name,property,value dedup -r rpool/data/vmdata
NAME PROPERTY VALUE
rpool/data/vmdata dedup off
Що це означає: Dedup вимкнено. Добре.
Рішення: Якщо dedup включений для сховища ВМ і ви не планували цього, вимкніть для нових записів і сплануйте ремедіацію. Dedup без правильного обсягу пам’яті та тестування перетворює RAM на вузьке місце продуктивності.
Завдання 14: Спостерігайте затримку по vdev за допомогою iostat
cr0x@server:~$ iostat -x 1 3
Linux 6.8.12-pve (server) 12/25/2025 _x86_64_ (32 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
8.12 0.00 2.91 11.44 0.00 77.53
Device r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
sda 85.0 490.0 6200.0 2600.0 27.4 3.10 38.2 3.1 44.1 0.8 46.2
sdb 85.0 490.0 6200.0 2600.0 27.4 3.06 37.9 3.0 43.7 0.8 46.0
Що це означає: iowait хосту немалий (11%). Очікування записів ≈44ms: це збігається з wlat ZFS. Пристрої не завантажені на 100%, але затримка все одно висока — типова ситуація, коли пристрій виконує внутрішній GC або обробляє flush-и.
Рішення: Якщо await високий, а %util не зашитий, підозрюйте поведінку flush, прошивку або тиск від sync, а не просто пропускну здатність.
Завдання 15: Перевірте конфіг диска VM у Proxmox щодо ризикованих режимів кешу
cr0x@server:~$ qm config 101 | egrep 'scsi|virtio|ide|sata|boot'
boot: order=scsi0;net0
scsi0: rpool/data/vmdata/vm-101-disk-0,discard=on,iothread=1,cache=writeback,ssd=1
Що це означає: cache=writeback може бути швидким, але змінює семантику відмовостійкості. З writeback хост може підтввердити запис, перш ніж він буде безпечним на диску.
Рішення: Для баз даних і чого-небудь, що залежить від правильності, віддавайте перевагу безпечнішим режимам кешу (і покладайтеся на ZFS + належне обладнання). Якщо ви свідомо обираєте writeback, документуйте це, ніби це заряджена зброя.
Завдання 16: Підтвердіть ashift пулу (бо потім не виправиш)
cr0x@server:~$ sudo zdb -C rpool | egrep 'ashift|vdev_tree' -n | head
54: vdev_tree:
86: ashift: 12
Що це означає: ashift=12 (4K сектора). Зазвичай це правильно для сучасних дисків.
Рішення: Якщо ви коли-небудь побачите ashift=9 на дисках, що насправді 4K, очікуйте проблем з продуктивністю. Виправлення зазвичай означає перебудову пулу. Плануйте це відповідно.
Завдання 17: Перевірте «роздуття» snapshot-ів (бо «вільне місце» може бути заповнено)
cr0x@server:~$ zfs list -o name,used,usedbysnapshots,usedbydataset,logicalused -r rpool/data/vmdata | head
NAME USED USEDSNAP USEDDS LOGICALUSED
rpool/data/vmdata 640G 210G 96K 1.1T
Що це означає: 210G зайнято snapshot-ами. Це не «погано» саме по собі; це політичне рішення. Але це впливає на заповненість пулу і продуктивність.
Рішення: Якщо знімки їдять простір і штовхають вас у зону високого заповнення, скоротіть політику зберігання або перенесіть резервні копії в інше місце. «Ми зберігаємо все назавжди» — не стратегія зберігання.
Завдання 18: Перевірте, чи стиснення справді працює (перевірка коефіцієнта)
cr0x@server:~$ zfs get -o name,property,value compressratio -r rpool/data/vmdata | head
NAME PROPERTY VALUE
rpool/data/vmdata compressratio 1.38x
Що це означає: 1.38x — відчутна вигода. Ви зменшуєте фізичний I/O для багатьох навантажень.
Рішення: Якщо compressratio ≈1.00x для зашифрованих/нестиснюваних даних — це очікувано. Проте накладні витрати lz4 зазвичай низькі, тому його варто залишати ввімкненим.
Парафразована ідея — John Allspaw: Надійність походить від проектування систем, що безпечно відпрацьовують відмови, а не від припущення, що відмов не буде.
Швидкий план діагностики (перші/другі/треті перевірки)
Це короткий потік триажу, коли в тикеті написано «сховище ВМ повільне» і у вас є 15 хвилин до наступної наради, яку ви все одно ігноруватимете.
Перше: чи хворий шар зберігання хоста або він просто зайнятий?
- Запустіть
zpool status: подивіться на degraded devices, checksum errors, resilvering або scrubs, що працюють у пікові години. - Запустіть
zpool iostat -rlv 1 3: перевірте write latency (wlat). Якщо wlat високий, проблеми на шарі зберігання. - Запустіть
iostat -x 1 3: підтвердіть await пристроїв і iowait. Високий await підтверджує проблему на рівні пристрою.
Друге: чи тонете ви в sync-записах?
- Перевірте властивість
syncdataset/zvol (не припускайте автоматично). Якщоsync=standard, sync-записи чекатимуть на стабільне зберігання. - Підтвердіть наявність SLOG. Якщо немає — sync-затримка сплачується на основних vdev.
- Шукайте навантаження, що тригерить sync-шторм: бази даних, пошта, NFS всередині гостей, файлові системи з журналом під тиском.
Третє: чи ви обмежені ємністю та фрагментацією?
- Перевірте
capтаfragпулу. Висока ємність у поєднанні з високою фрагментацією множить затримки. - Перевірте використання snapshot-ів. Знімки можуть «закривати» простір і пришвидшувати поведінку «пул занадто повний».
- Перевірте несподіваності thin provisioning: гості думають, що мають простір, а пул — ні.
Якщо ці три перевірки чисті
Тоді дивіться на конфігурацію ВМ: режим кешу, шину диска, iothread, глибину черги та поведінку файлової системи гостя. Але не починайте з цього. Інакше ви закінчите тюнінгом приладової панелі, поки двигун працює з одним циліндром.
Поширені помилки: симптом → корінна причина → виправлення
1) Симптом: «Усе зависає на 1–5 секунд рандомно»
Корінна причина: Стрибки затримки sync-записів (flush-и, fsync-шторм) на пулі без належного SLOG, часто в поєднанні зі споживчими SSD, що зависають під тиском flush.
Виправлення: Залишайте sync=standard для важливих даних, додайте дзеркальний SLOG з PLP за потреби і валідуйте zpool iostat -rlv. Якщо дані витратні, встановіть sync=disabled для конкретного dataset/zvol і задокументуйте ризик.
2) Симптом: «ВМ синтетично швидкі, але реальні додатки повільні»
Корінна причина: Бенчмарки тестують послідовні шляхи; додатки — випадкові sync-важкі патерни та метадані. Також поширено: невідповідний volblocksize для zvol.
Виправлення: Підберіть volblocksize під навантаження (часто 16K для загальних VM-дисків), уникайте qcow2-на-ZFS без потреби і вимірюйте затримку, а не лише пропускну здатність.
3) Симптом: «Пул має місце, але продуктивність жахлива»
Корінна причина: Пул занадто заповнений (80–95%), знімки ловлять простір, аллокатор під тиском; фрагментація зростає.
Виправлення: Скоротіть збереження знімків, мігруйте дані, розширюйте пул. Розглядайте вільний простір як резерв продуктивності, а не пораду.
4) Симптом: «Після увімкнення autotrim затримка погіршилась»
Корінна причина: Деякі SSD погано працюють при безперервних trim-операціях; trim конкурує з foreground-записами.
Виправлення: Вимкніть autotrim і виконуйте планові trims у тихі вікна. Розгляньте enterprise SSD з передбачуваною поведінкою trim.
5) Симптом: «Хост має багато RAM, але гості все одно своплять під навантаженням»
Корінна причина: ARC агресивно росте і відбирає пам’ять у гостей, або ви подвійно кешуєте дані хостом і гостем.
Виправлення: Розгляньте primarycache=metadata для zvol ВМ; обмежте ARC, якщо потрібно; валідуйте з arcstats і метриками пам’яті гостей.
6) Симптом: «Резервні копії роблять продакшн непридатним»
Корінна причина: I/O від знімків/бекапів конфліктує з продуктивним випадковим записом; бекапи підвищують read amplification і метадані-активність.
Виправлення: Плануйте бекапи, обмежуйте їх, ізолюйте сховище для бекапів і уникайте розміщення цілей резервного копіювання на тому самому навантаженому пулі.
7) Симптом: «Ми додали швидкий SSD-кеш і нічого не покращилось»
Корінна причина: L2ARC не допомагає з затримкою запису; він допомагає з читанням, і лише якщо робочий набір і патерни доступу підходять. Кеш-пристрої також можуть «красти» RAM і додавати накладні витрати.
Виправлення: Вирішуйте проблему затримки записів на рівні vdev/sync. Додавайте L2ARC лише після підтвердження, що читання — вузьке місце і ARC-хітрейт недостатній.
Три корпоративні міні-історії з практики зберігання
Міні-історія №1: Інцидент через невірне припущення
Вони мігрували невеликий парк прикладних ВМ на Proxmox з ZFS-міррорами на «хороших SSD». Це був сенсовний, бюджетно-затверджений дизайн: два диски, дзеркало, на папері — багато IOPS. Додатки були переважно безстанніми веб-сервісами з невеликою базою даних і брокером повідомлень.
Неправильне припущення було тонким: «Якщо це дзеркальний SSD, sync-записи практично безкоштовні». Ніхто цього не проговорив вголос, і такі припущення виживають. Вони запустили платформу, вона виглядала чудово, а потім почала давати короткі жорсткі стрибки затримки під піком трафіку.
Команда на виклику ганялася за привидами: мережеві перебої, «шумні сусіди», CPU steal, навіть «можливо, в Linux регрес планувальника». Тим часом база даних робила цілком адекватні коміти з fsync, а ZFS робив цілком адекватно — чекав стабільного зберігання.
Коли вони порівняли графіки затримки запису хоста з таймаутами додатків, історія написала себе сама. SSD були споживчими моделями з нестабільною латентністю flush. Коли база даних потрапляла у сплеск sync-записів, пристрої зависали. Дзеркало не врятувало; воно просто надало два пристрої, які могли зависати одночасно.
Виправлення не було екзотичним. Вони розгорнули дзеркальний SLOG на пристроях з захистом від втрати живлення і перестали робити вигляд, що латентність flush не має значення. Стрибки зникли. Команда також задокументувала, які dataset можуть терпіти sync=disabled (декілька) і які ні (база даних і брокер). Головний урок — операційний: ніколи не припускайте, що ваше сховище швидко виконує гарантії довговічності лише тому, що це «SSD».
Міні-історія №2: Оптимізація, що відкотилася
Інша організація хотіла «максимальної продуктивності» і агресивно налаштувала все. Вони вимкнули sync глобально. Встановили VM-диски в writeback cache. Увімкнули всі перемикачі продуктивності, які лише знайшли. Також обрали qcow2, бо переміщати диски було «зручніше».
Деякий час це працювало. Бенчмарки виглядали героїчними. Деплої були швидкі. Усі давали «п’ять» і поверталися до фіч. Потім відбувся ребут хоста — рутинне оновлення ядра — і кілька ВМ повернулися з пошкодженими файловими системами. База даних відновилася. Поштовий VM — ні. Постмортем був… пізнавальний.
Відкат не стався через те, що будь-яке окреме налаштування «погане» само по собі. Проблема була у комбінації: writeback cache + sync disabled + характеристика записів qcow2 створили систему, що оптимістично підтверджувала записи. Система була швидкою, бо фактично брехала щодо того, що є стійким.
Вони повернулися до безпечніших дефолтів, але не сліпо. Вони винесли політику тюнінгу: для витратних навантажень важливіше швидкість; для станкових — надійність; для останніх вони оптимізували апаратний шлях зберігання, а не вимикали коректність. Також перейшли з qcow2 на raw, де це було можливо, щоб зменшити насладання CoW і накладні витрати на метадані.
Справжня вартість була не в корупції як такій — а в тижні втраченої довіри. Користувачам байдуже, що ви можете пояснити семантику кешу. Їм важливо, що їхні дані повернулися.
Міні-історія №3: Нудна, але правильна практика, що врятувала день
Середня компанія експлуатувала кластери Proxmox для внутрішніх сервісів. Нічого яскравого: контролери домену, Git, моніторинг, кілька малих баз даних і дивовижна кількість синхронізації файлів. Їхнє зберігання — ZFS-міррори і трохи RAIDZ для бекапів. Вони мали одну практику, що здавалася болюче нудною: щотижневі scrubs, моніторинг SMART і суворі пороги заповнення пулів.
Вони також стандартизували dataset для ВМ з однаковими властивостями: lz4 увімкнено, atime вимкнено і явні рішення щодо sync. Найважливіше — правило: жоден пул ВМ понад 80% без затвердженого плану розширення. Люди скаржилися. Фінанси скаржилися. Усі скаржаться, коли їм кажуть «ні».
Одного кварталу набір SSD почав показувати зростаючі помилки середовища. Нічого не вибухнуло. Просто тренд в SMART і кілька повільних читань, що проявилися як невеликі підвищення затримки під час scrubs. Завдяки регулярним scrubs і алертам, прив’язаним до змін, вони виявили це рано.
Вони замінили диски в робочий час, по одному, з контрольованими resilver-ами. Жодного інцидент-бріджу. Жодного видимого для клієнтів простою. Нудна практика — дисципліна scrubs і ємності — зробила так, що пул ніколи не потрапив у «занадто повний для безпечного resilver» стан. Вони не отримали нагороду. Вони просто не мали поганого тижня.
Чеклісти / покроковий план
Чекліст A: Дефолти зберігання на перший день для нового Proxmox ZFS VM пулу
- Створіть пул з коректним ashift (зазвичай 12). Перевірте з
zdb -Cперед тим, як класти туди дані. - Створіть окремий dataset для сховища ВМ (не кидайте все в кореневі datasets).
- Встановіть
compression=lz4на dataset ВМ. - Встановіть
atime=offна dataset ВМ. - Вирішіть політику sync по кожному dataset: за замовчуванням — надійність; вимикайте лише для втратних навантажень.
- Якщо використовуєте zvol, стандартизуйте volblocksize (часто 16K для загальних VM-дисків). Вирішіть до створення дисків.
- Вирішіть поведінку primarycache для дисків VM (розгляньте metadata-only для пам’ятевого тиску).
- Встановіть і дотримуйтеся порогів заповненості (сповіщення при 70–75%, дія при 80%).
Чекліст B: Коли ВМ відчувається повільною (триаж за 15 хвилин)
- Перевірте
zpool status(помилки? resilver? scrub?). Якщо так — зупиніться і стабілізуйте. - Перевірте
zpool iostat -rlv 1 3(затримка запису?). Якщо висока — вузьке місце шлях зберігання. - Перевірте
iostat -x 1 3(await пристрою, iowait). Підтвердіть, що це не лише сприйняття гостя. - Перевірте заповненість пулу і frag (
zpool list,zfs list, використання snapshot-ів). Якщо занадто повний — потрібна ємність, а не «відчуття». - Перевірте режим кешу диска ВМ (
qm config) і властивості dataset (zfs get).
Чекліст C: Контрольована міграція для виправлення поганого volblocksize
- Створіть новий zvol з бажаним
volblocksize. - Використайте Proxmox storage migration або контрольоване блочне копіювання під час вимкнення ВМ (бажано для коректності).
- Перевірте продуктивність і затримку з
zpool iostat -rlvі перевірками застосунку. - Видаліть старий zvol і спостерігайте за фрагментацією та простором.
Поширені питання
1) Чи варто використовувати ZFS або LVM-thin для зберігання ВМ у Proxmox?
Якщо вам потрібні прості знімки та реплікація і цілісність «від краю до краю», ZFS — сильний вибір. Якщо ви хочете простішу модель блокового сховища і менше взаємодії CoW, LVM-thin може бути легшим для розуміння. Для багатьох команд ZFS виграє операційно — за умови, що ви ставите sync, ємність і розміри блоків у першу чергу.
2) Чи безпечно використовувати compression=lz4 для дисків ВМ?
Так. Це прозоро і широко розгорнуто. «Ризик» переважно в додатковому навантаженні на CPU, що зазвичай менше, ніж I/O, який ви заощаджуєте. Справжній ризик — не використовувати стиснення і потім дивуватися, чому пул завжди зайнятий переміщенням зайвих байтів.
3) Який volblocksize слід використовувати для zvol ВМ?
Звичні значення для загальних VM-дисків — 16K (часто хороший баланс). Для спеціалізованих навантажень вимірюйте: бази даних іноді полюбляють 8K або 16K; великі послідовні навантаження — 64K+. Ключ — послідовність і намір: вибирайте за навантаженням, а не за суєтою.
4) Чи можу я змінити volblocksize після створення zvol?
Ви можете змінити властивість, але вже записані блоки залишаться старого розміру. Щоб справді отримати користь, зазвичай мігрують дані на новий zvol з правильним volblocksize.
5) Чи варто вимкнути sync, щоб прискорити Proxmox?
Лише якщо ви готові втратити нещодавні записи при відключенні живлення або падінні — і лише для датасетів, де це прийнятно. Для реальних систем зі справжніми даними краще побудувати шлях зберігання, який витримає sync=standard, а не вимикати коректність глобально.
6) Чи потрібен мені SLOG для ZFS на SSD-дзеркалах?
Не обов’язково. Якщо ваше навантаження переважно асинхронне — ви можете бути в порядку. Якщо у вас значні sync-записи і вам важлива затримка, належний SLOG може сильно допомогти. «Належний» означає низьколатентний та захищений від втрати живлення, бажано в дзеркалі.
7) Чи погана ідея qcow2 на ZFS?
Зазвичай так — бо ви складаєте CoW на CoW, що збільшує фрагментацію і накладні витрати на метадані. Якщо вам потрібні фічі qcow2 — використовуйте усвідомлено. Інакше raw на ZFS зазвичай спокійніший і передбачуваніший вибір.
8) Чому продуктивність руйнується, коли пул наповнюється?
ZFS потребує вільного простору для ефективної алокації. Коли вільного місця стає мало, алокації ускладнюються, фрагментація зростає, і write amplification збільшується — особливо при випадковому I/O ВМ. Тримати 20–30% вільним — це не марнотратство; це купівля стабільної затримки.
9) Чи варто ставити primarycache=metadata для всього сховища ВМ?
Це хороший дефолт при великіх гостях і пам’ятевому тиску, бо зменшує подвійне кешування. Якщо хост має багато RAM і гості малі/читають інтенсивно, кеш даних може допомогти. Не вгадуйте: перевіряйте ARC і стан пам’яті гостей.
10) Чи autotrim завжди допомагає на SSD пулах?
Воно часто допомагає у довгостроковій поведінці місця і може підтримувати продуктивність SSD, але деякі пристрої погано переносять безперервні trims. Увімкніть, спостерігайте латентність і будьте готові перейти на планові trims.
Висновок: практичні подальші кроки
Якщо ви експлуатуєте Proxmox на ZFS і ще не торкалися дефолтів зберігання, швидше за все у вас система, що чудова у вівторок і зрадницька в четвер. Виправлення — це не магія. Це політика.
- Увімкніть compression=lz4 і atime=off на dataset ВМ сьогодні. Це низький ризик, зазвичай велика віддача.
- Аудитуйте поведінку sync. Вирішіть, що має бути надійним, і спроектуйте під це. Не вимикайте sync випадково по всьому пулу.
- Стандартизуйте volblocksize для нових VM-дисків (часто 16K) і плануйте міграції для найгірших випадків.
- Перестаньте переповнювати пулив. Ємність — це функція продуктивності. Зробіть її моніторинговим SLO, а не нічною несподіванкою.
- Вимірюйте затримку, а не лише пропускну здатність. Використовуйте
zpool iostat -rlvіiostat -x, щоб тримати себе чесним.
Зробіть ці п’ять речей, і більшість скарг «ZFS повільний» зникне. Ті, що залишаться, будуть чесними проблемами — апаратні обмеження, реалії навантаження і поодинокі свідомі рішення.