Ви можете роками використовувати ZFS, не задумуючись про різницю між dataset і zvol.
Потім ви віртуалізуєте щось важливе, додаєте снапшоти «на всякий випадок», реплікація стає вимогою ради директорів,
і раптом ваша платформа зберігання починає мати власну думку. Голосну.
Вибір між zvol і dataset — не академічне питання. Він змінює, як формується IO, що може кеш, як поводяться снапшоти,
як ламається реплікація і які налаштування взагалі існують. Помилковий вибір призведе не просто до уповільнення — ви отримаєте
операційний борг, що накопичується з кварталу в квартал.
Datasets і zvol: що вони насправді означають (не те, що пишуть у Slack)
Dataset: файловa система з надздібностями ZFS
ZFS dataset — це ZFS filesystem. Вона має файлову семантику: директорії, дозволи, власність, розширені атрибути.
Її можна експортувати через NFS/SMB, монтувати локально та оперувати звичними інструментами. ZFS додає власний набір можливостей:
снапшоти, клони, стиснення, контрольні суми, квоти/резервації, налаштування recordsize і всю транзакційну безпеку, що
дає вам трохи більше спокою.
Коли ви зберігаєте дані в dataset, ZFS керує тим, як розміщує змінного розміру «записи» (блоки, але не фіксованого розміру як у традиційних ФС).
Це важливо, бо впливає на ампліфікацію, ефективність кешування і шаблони IO. Ключовий регулятор — recordsize.
Zvol: блочний пристрій, вирізаний із ZFS
Zvol — це ZFS volume: віртуальний блочний пристрій, що експонується як /dev/zvol/pool/volume. Він не розуміє файлів.
Ваш гостьовий файловий менеджер (ext4, XFS, NTFS) або база даних бачить диск і записує блоки. ZFS зберігає ці блоки як об’єкти
з фіксованим розміром, яким керує volblocksize.
Zvol існують для випадків, коли споживач потребує блочного пристрою: iSCSI LUN, диски VM, деякі рантайми контейнерів, деякі гіпервізори
і інколи стекі застосунків, що наполягають на «сирих» пристроях.
Реальний світ простою мовою
- Dataset = «ZFS — це файловa система; клієнти говорять через файлові протоколи; ZFS бачить файли і може оптимізувати під них.»
- Zvol = «ZFS надає імітацію диска; хтось інший будує файлову систему; ZFS бачить блоки і робить припущення.»
ZFS чудово працює в обох моделях, але вони поводяться по-різному. Біль виникає, коли вважають, що це однакові речі.
Короткий жарт про те, що зберігання потребує смиренності: якщо ви хочете розпалити пристрасну дискусію в датацентрі, заговоріть про RAID.
Якщо хочете її завершити — згадайте zvol volblocksize і спостерігайте, як усі тихенько переглядають нотатки.
Правила вибору: коли використовувати dataset, коли — zvol
За замовчуванням: datasets — нудний вибір, і нудний виграє
Якщо ваше навантаження може використовувати сховище як файлову систему (локальне монтування, NFS, SMB), використовуйте dataset. Ви отримуєте простішу експлуатацію:
легше інспектувати, простіше копіювати/відновлювати, пряміші права доступу і менше крайових випадків навколо розмірів блоків та TRIM/UNMAP.
Також ви отримуєте поведінку ZFS, налаштовану за замовчуванням під файли.
Datasets також простіше відлагоджувати, бо ваші інструменти все ще «говорять файловою мовою». Ви можете вимірювати фрагментацію на рівні файлів,
дивитися директорії, розбиратися з метаданими і зберігати чисту ментальну модель.
Коли zvol — правильний інструмент
Використовуйте zvol, коли споживач вимагає блочний пристрій:
- диски VM (особливо для гіпервізорів, які хочуть raw volumes, або коли потрібні ZFS-снапшоти віртуального диска)
- iSCSI-таргети (LUN за визначенням блочні)
- деякі кластерні налаштування, які реплікують блочні пристрої або потребують SCSI-семантики
- успадковані застосунки, що підтримують тільки «базу даних на сирому пристрої» (рідко, але буває)
Модель zvol потужна: снапшоти диска VM швидкі, клони — миттєві, реплікація працює, і ви можете стискати та контролювати контрольні суми.
Але: блочні пристрої множать відповідальність
Коли ви використовуєте zvol, ви тепер відповідаєте за шар між гостьовою ФС і ZFS. Вирівнювання важливе. Розмір блоку важливий.
Бар’єри запису важливі. Trim/UNMAP важливі. Налаштування sync стають політикою, а не дрібною опцією.
Проста матриця рішень, яку можна захищати
- Потрібні NFS/SMB або локальні файли? Dataset.
- Потрібен iSCSI LUN або сирий блок для гіпервізора? Zvol.
- Потрібна видимість по файлах, просте відновлення одного файлу? Dataset.
- Потрібні миттєві клони VM від golden image? Zvol (або dataset зі sparse-файлами, але знайте свій інструментальний стек).
- Потрібен консистентний снапшот застосунку, який керує власною ФС? Zvol (і координуйте flush/quiesce).
- Хочете «оптимізувати продуктивність», не знаючи шаблонів IO? Dataset, потім вимірюйте. Геройське тонке налаштування прийде пізніше.
Recordsize vs volblocksize: тут вирішується продуктивність
Datasets: recordsize — це максимальний розмір блока даних, який ZFS використовуватиме для файлів. Великі послідовні файли (резервні копії,
медіа, логи) люблять більші recordsize, наприклад 1M. Бази даних і випадкові IO віддають перевагу меншим значенням (16K, 8K), бо перезапис невеликого
регіону не провокує велику перезаписну ампліфікацію.
Zvols: volblocksize фіксується при створенні. Вибравши неправильно, ви не зможете змінити його пізніше без перебудови zvol.
Це не «неприємно». Це «ми заплануємо міграцію в Q4, бо графіки затримок нагадують пилкоподібний малюнок».
Снапшоти: оманливо схожі, але операційно різні
Снапшот dataset захоплює стан файлової системи. Снапшот zvol захоплює сирі блоки. У обох випадках ZFS використовує copy-on-write,
тому снапшот дешевий на створенні і дорожчий пізніше, якщо ви постійно перезаписуєте блоки, що посилаються снапшотами.
З zvol цю витрату легше спровокувати, бо диски VM постійно перезаписують блоки: оновлення метаданих, журналювання, обслуговування ФС,
іноді «нічого не відбувається», але всередині щось перезаписується. Снапшоти, що тримаються занадто довго, стають податком.
Квоти, резервації і пастка thin-provisioning
Datasets дають вам quota і refquota. Zvols дають фіксований розмір, але ви можете створювати sparse-томи
і прикидатися, що у вас більше місця, ніж є. Це бізнес-рішення під виглядом інженерної функції.
Thin-provisioning прийнятне, якщо у вас є моніторинг, алерти і відповідальна експлуатація. Це катастрофа, коли його використовують,
щоб уникнути слова «ні» у черзі запитів.
Другий короткий жарт (і останній): thin provisioning — це як замовити штани на розмір менші як «мотивацію».
Іноді працює, але переважно просто не вистачає повітря.
Режими відмов, що зустрічаються лише в продукції
Ампліфікація записів через невідповідний розмір блоків
Dataset з recordsize=1M, що підтримує базу даних з 8K випадковими записами, може викликати болісну ампліфікацію:
кожне невелике оновлення зачіпає великий запис. ZFS має логіку для обробки менших записів (і в деяких випадках зберігатиме менші блоки),
але не покладайтеся на неї, щоб врятувати вас від поганого вибору. Натомість zvol з volblocksize=128K, що обслуговує VM ФС,
яка пише 4K блоки, буде так само невідповідний.
Симптом: добрий пропуск у бенчмарках, жахливі хвостові затримки в реальних навантаженнях.
Синхронні семантики: де ховається латентність
ZFS поважає синхронні записи. Якщо застосунок (або гіпервізор) робить sync-записи, ZFS має зафіксувати їх безпечно — тобто на стабільне сховище, а не лише в RAM.
Без виділеного SLOG-пристрою (швидкого, із захистом від втрати живлення) навантаження з великою кількістю sync-записів може застрягти на латентності основного пулу.
Споживачі zvol часто більш агресивно використовують sync-запити, ніж файлові протоколи. VM і бази даних зазвичай дбають про довговічність.
NFS-клієнти можуть робити sync-записи залежно від опцій монтовання і поведінки застосунку. У будь-якому випадку, якщо сплески затримок корелюють
з навантаженням sync, дискусія «zvol vs dataset» перетворюється на «чи розуміємо ми шлях sync-записів».
TRIM/UNMAP і міф про «автоматичне повернення вільного місця»
Datasets звільняють блоки при видаленні файлів. Zvols залежать від того, чи гість надсилає TRIM/UNMAP (і чи ваш стек передає його далі).
Без цього ваш zvol виглядає повним назавжди, снапшоти здуті, і ви починаєте звинувачувати «фрагментацію ZFS» замість відсутності сигналу збору сміття.
Вибухове зростання утримання снапшотів
Утримувати hourly снапшоти протягом 90 днів для VM zvol здається відповідальним, поки ви не усвідомите, що зберігаєте кожен перезаписаний блок під час
кожного Windows-оновлення, запуску пакетного менеджера і ротації логів. Математика швидко стає некрасивою. Datasets теж страждають, але VM churn — це особливий вид ентузіазму.
Сюрприз реплікації: datasets дружніші до інкрементальної логіки
Реплікація ZFS працює і для datasets, і для zvol, але реплікація zvol може бути більша та більш чутлива до перезаписів блоків.
Невелика зміна в гостьовій ФС може перезаписати блоки по всьому простору. Ваш incremental send може виглядати підозріло як повний send, і WAN-канал підкаже вам, що він проти.
Фрикція інструментів: люди — частина системи
Більшість команд мають кращі операційні навички щодо файлових систем, ніж блочних пристроїв. Вони знають, як перевіряти дозволи, як копіювати файли,
як монтувати й інспектувати. Робочі процеси з zvol тягнуть вас у інші інструменти: таблиці розділів, гостьові ФС, блок-рівневі перевірки.
Фрикція проявляється о 3:00 ранку, а не на зустрічі з дизайну.
Цікаві факти та історія, які можна використати на дизайн-рев’ю
- ZFS ввів наскрізну перевірку контрольних сум як базову функцію, а не доповнення; це змінило підхід до «тихої корупції».
- Copy-on-write не був новим коли з’явився ZFS, але ZFS зробив його експлуатаційно звичним для загальних стеків зберігання.
- Zvol були спроектовані для інтеграції з блочними екосистемами як iSCSI і VM-платформи, задовго до того, як «гіперконвергентність» стала маркетинговим терміном.
- За замовчуванням recordsize вибрано для загальних файлових навантажень, а не для баз даних; значення за замовчуванням — це політика, вбудована в код.
- Volblocksize незмінний після створення zvol у більшості реалізацій; ця деталь викликає багато міграцій.
- ARC (Adaptive Replacement Cache) зробив поведінку кешу ZFS відмінною від багатьох традиційних ФС; це не просто page cache.
- L2ARC з’явився як кеш другого рівня, але він не замінює потребу правильно розмірити RAM; він змінює лише показники влучань, а не творить дива.
- SLOG-пристрої стали стандартним паттерном тому, що латентність синхронних записів домінує в деяких навантаженнях; «швидкий SSD» без захисту від втрати живлення — це не SLOG.
- Send/receive реплікація дала ZFS вбудований примітив для бекапу; це не «rsync», це потік транзакцій блоків.
Практичні завдання: команди, виводи та що вирішувати
Це не «демо-команди». Це ті команди, що ви запускаєте, коли намагаєтеся вибрати між dataset і zvol, або коли доводите собі, що зробили правильний вибір.
Завдання 1: інвентаризація того, що у вас насправді є
cr0x@server:~$ zfs list -o name,type,used,avail,refer,mountpoint -r tank
NAME TYPE USED AVAIL REFER MOUNTPOINT
tank filesystem 1.12T 8.44T 192K /tank
tank/vm filesystem 420G 8.44T 128K /tank/vm
tank/vm/web01 volume 80.0G 8.44T 10.2G -
tank/vm/db01 volume 250G 8.44T 96.4G -
tank/nfs filesystem 320G 8.44T 320G /tank/nfs
Значення: У вас є і datasets (filesystem), і zvols (volume). Zvols не мають mountpoint.
Рішення: Визначте, які навантаження знаходяться на volumes, і запитайте: чи справді їм потрібен блок, або це інерція?
Завдання 2: перевірте recordsize dataset (і чи відповідає він навантаженню)
cr0x@server:~$ zfs get -o name,property,value recordsize tank/nfs
NAME PROPERTY VALUE
tank/nfs recordsize 128K
Значення: Цей dataset використовує 128K records, пристойний загальний дефолт.
Рішення: Якщо dataset хостить бази даних або образи VM як файли, розгляньте 16K або 32K; якщо це бекапи — 1M.
Завдання 3: перевірте volblocksize zvol ( «не змінюється пізніше»)
cr0x@server:~$ zfs get -o name,property,value volblocksize tank/vm/db01
NAME PROPERTY VALUE
tank/vm/db01 volblocksize 8K
Значення: Цей zvol використовує 8K блоки — зазвичай доречно для баз даних з випадковими IO і багатьох VM ФС.
Рішення: Якщо ви бачите 64K/128K тут для загальних VM-дисків, очікуйте ампліфікацію записів і розгляньте перебудову правильно.
Завдання 4: перевірте політику sync, бо вона контролює довговічність vs латентність
cr0x@server:~$ zfs get -o name,property,value sync tank/vm
NAME PROPERTY VALUE
tank/vm sync standard
Значення: ZFS буде поважати sync-запити, але не змушуватиме всі записи бути sync.
Рішення: Якщо хтось поставив sync=disabled «для продуктивності», заплануйте розмову про ризики і план відкату.
Завдання 5: подивіться статус стиснення і коефіцієнт (часто вирішує вартість)
cr0x@server:~$ zfs get -o name,property,value,source compression,compressratio tank/vm/db01
NAME PROPERTY VALUE SOURCE
tank/vm/db01 compression lz4 local
tank/vm/db01 compressratio 1.62x -
Значення: LZ4 увімкнено і допомагає.
Рішення: Залиште його. Якщо стиснення вимкнене на VM-дисках, увімкніть, якщо немає доведеного CPU-ші\
кання.
Завдання 6: перевірте, скільки снапшотів ви тягнете з собою
cr0x@server:~$ zfs list -t snapshot -o name,used,refer -S used | head
NAME USED REFER
tank/vm/db01@hourly-2025-12-24-23 8.4G 96.4G
tank/vm/db01@hourly-2025-12-24-22 7.9G 96.4G
tank/vm/web01@hourly-2025-12-24-23 2.1G 10.2G
tank/nfs@daily-2025-12-24 1.4G 320G
Значення: Стовпець USED — це простір снапшота, унікальний для цього снапшота.
Рішення: Якщо годинні снапшоти VM займають по кілька гігабайт, скоротіть зберігання або частоту; снапшоти не безкоштовні.
Завдання 7: визначте «простір, утримуваний снапшотами» на zvol
cr0x@server:~$ zfs get -o name,property,value usedbysnapshots,usedbydataset,logicalused tank/vm/db01
NAME PROPERTY VALUE
tank/vm/db01 usedbysnapshots 112G
tank/vm/db01 usedbydataset 96.4G
tank/vm/db01 logicalused 250G
Значення: Снапшоти утримують більше місця, ніж поточні «живі» дані.
Рішення: Ваша «політика бекапу» тепер — політика планування ємності. Виправте зберігання і розгляньте поведінку guest TRIM/UNMAP.
Завдання 8: перевірте здоров’я пулу та помилки перш ніж налаштовувати продуктивність
cr0x@server:~$ zpool status -v tank
pool: tank
state: ONLINE
scan: scrub repaired 0B in 02:14:33 with 0 errors on Sun Dec 22 03:10:11 2025
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ata-SSD1 ONLINE 0 0 0
ata-SSD2 ONLINE 0 0 0
errors: No known data errors
Значення: Пул здоровий, scrub пройшов чисто.
Рішення: Якщо ви бачите checksum errors або degraded vdevs, зупиніться. Виправте апарат/шлях до накопичувача перед дискусією zvol vs dataset.
Завдання 9: дивіться IO в реальному часі по dataset/zvol
cr0x@server:~$ zpool iostat -v tank 2 3
capacity operations bandwidth
pool alloc free read write read write
-------------------------- ----- ----- ----- ----- ----- -----
tank 1.12T 8.44T 210 980 12.4M 88.1M
mirror-0 1.12T 8.44T 210 980 12.4M 88.1M
ata-SSD1 - - 105 490 6.2M 44.0M
ata-SSD2 - - 105 490 6.2M 44.1M
-------------------------- ----- ----- ----- ----- ----- -----
Значення: Ви бачите read/write IOPS і пропускну здатність; це показує, чи ви обмежені IOPS або throughput.
Рішення: Велика кількість write IOPS з низьким bandwidth вказує на дрібні випадкові записи — тут мають значення volblocksize і шлях sync.
Завдання 10: перевірте навантаження на ARC (бо RAM — ваш перший рівень зберігання)
cr0x@server:~$ arcstat 1 3
time read miss miss% dmis dm% pmis pm% mmis mm% size c
12:20:01 532 41 7 12 2 29 5 0 0 48.1G 52.0G
12:20:02 611 58 9 16 2 42 7 0 0 48.1G 52.0G
12:20:03 590 55 9 15 2 40 7 0 0 48.1G 52.0G
Значення: Показники пропуску ARC низькі; кешування здорове.
Рішення: Якщо miss% постійно високий під навантаженням, додавання RAM часто кращий варіант, ніж хитрі зміни макету зберігання.
Завдання 11: чи є zvol sparse (тонкий) і чи це безпечно
cr0x@server:~$ zfs get -o name,property,value refreservation,volsize,used tank/vm/web01
NAME PROPERTY VALUE
tank/vm/web01 refreservation none
tank/vm/web01 volsize 80G
tank/vm/web01 used 10.2G
Значення: Немає refreservation: фактично це thin з точки зору гарантованого простору.
Рішення: Якщо запускаєте критичні VM, встановіть refreservation, щоб гарантувати місце, або прийміть ризик pool-full відмов.
Завдання 12: підтвердьте ashift (ваш базовий вирівнювач фізичного сектора)
cr0x@server:~$ zdb -C tank | grep -E 'ashift|vdev_tree' -n | head
45: vdev_tree:
67: ashift: 12
Значення: ashift=12 означає 4K сектори. Зазвичай правильно для сучасних SSD і HDD.
Рішення: Якщо ashift неправильний (занадто малий), продуктивність може бути назавжди знижена; потрібно перебудувати пул, а не «налаштовувати».
Завдання 13: оцініть розмір send перед реплікацією по вузькому каналу
cr0x@server:~$ zfs send -nvP tank/vm/db01@hourly-2025-12-24-23 | head
send from @hourly-2025-12-24-22 to tank/vm/db01@hourly-2025-12-24-23 estimated size is 18.7G
total estimated size is 18.7G
Значення: Інкрементальна реплікація все ще 18.7G — перезапис блоків високий.
Рішення: Зменште частоту/утримання снапшотів, покращте guest TRIM або змініть архітектуру (зберігання даних у dataset) якщо можливо.
Завдання 14: перевірте, чи TRIM увімкнено на пулі
cr0x@server:~$ zpool get -o name,property,value autotrim tank
NAME PROPERTY VALUE
tank autotrim on
Значення: Пул відправляє TRIM у SSD.
Рішення: Якщо autotrim вимкнено на SSD-пулах, розгляньте ввімкнення — особливо якщо ви покладаєтеся на звільнення простору від zvol гостей.
Завдання 15: перевірте властивості по dataset, що змінюють поведінку непомітно
cr0x@server:~$ zfs get -o name,property,value atime,xattr,primarycache,logbias tank/vm
NAME PROPERTY VALUE
tank/vm atime off
tank/vm xattr sa
tank/vm primarycache all
tank/vm logbias latency
Значення: atime off зменшує записи метаданих; xattr=sa зберігає xattr ефективніше; logbias=latency віддає перевагу латентності sync.
Рішення: Для VM zvols logbias=latency зазвичай доречно. Якщо logbias=throughput — перевірте, чи це не копіювання налаштування без розуміння причин.
Швидка діагностика (знайти вузьке місце за хвилини)
Коли продуктивність погана, дискусія про zvol vs dataset часто відволікає. Використайте цю послідовність, щоб швидко знайти реальне обмеження.
Перше: доведіть, що пул не хворий
-
Запустіть:
zpool status -v
Шукайте: degraded vdevs, checksum errors, resilver in progress, повільний scrub.
Інтерпретація: Якщо пул нездоровий — все інше шум. -
Запустіть:
dmesg | tail(і логи вашої ОС)
Шукайте: link resets, timeouts, NVMe errors, HBA issues.
Інтерпретація: Флапаючий шлях диска виглядає як «випадкові сплески латентності».
Друге: класифікуйте IO (малі випадкові vs великі послідовні, sync vs async)
-
Запустіть:
zpool iostat -v 2
Шукайте: високу кількість IOPS з низьким MB/s (випадкові) vs високий MB/s (послідовні).
Інтерпретація: Випадковий IO навантажує латентність, послідовний — пропускну здатність. -
Запустіть:
zfs get sync tank/...і перевірте налаштування застосунків
Шукайте: sync-важкі навантаження без SLOG або на повільних носіях.
Інтерпретація: Sync-записи виявлять найповільніший шлях до надійного зберігання.
Третє: перевірте пам’ять і кешування перед тим як купувати обладнання
-
Запустіть:
arcstat 1
Шукайте: високий miss%, ARC не росте, тиск пам’яті.
Інтерпретація: Якщо ви постійно промахуєтесь у кеші, змушуєте диск читати те, що можна уникнути. -
Запустіть:
zfs get primarycache secondarycache tank/...
Шукайте: чи хтось встановив кешування тільки метаданих «щоб зекономити RAM».
Інтерпретація: Це може бути виправданим, але часто — випадкова самопоразка.
Четверте: перевірте розміри блоків і податок снапшотів
-
Запустіть:
zfs get recordsize tank/datasetабоzfs get volblocksize tank/volume
Інтерпретація: Невідповідність = ампліфікація = хвостова латентність. -
Запустіть:
zfs get usedbysnapshots tank/...
Інтерпретація: Якщо снапшоти утримують масивний простір, вони також збільшують метадані та роботу алокації.
Три корпоративні міні-історії (анонімізовані, але болісно реальні)
Міні-історія 1: інцидент через хибні припущення («zvol — це по суті dataset»)
Середня SaaS-компанія мігрувала з legacy SAN на ZFS. Інженер зберігання — розумний, швидкий, трохи надто впевнений — стандартизувався на zvol для всього
«бо диски VM — це volumes, і саме так робив SAN». NFS-подібне сховище застосунку також перемістили в ext4 на zvol. У тестах працювало. У продукції теж поки що.
Перші ознаки були тонкі: вікна бекапів почали розтягуватися. Реплікація почала пропускати RPO, але тільки на певних томах.
Потім пул, що був стабільним місяцями, раптом впав у край по ємності. «У нас 30% вільного», — хтось сказав, вказуючи на дашборд пулу. «То чому не можна створити новий VM-диск?»
Відповідь була в снапшотах. Zvols снапшотили щогодини, а гостьові файлові системи постійно перезаписували блоки. Видалені файли всередині гостей не звільняли блоки,
якщо TRIM не пройшов через весь стек. Він не пройшов, бо гості не були налаштовані і шлях гіпервізора не пробачав його.
Паралельно навантаження, схоже на NFS, всередині гостя ext4 не мало причин перебувати на zvol взагалі. Вони хотіли файлову семантику, але побудували торт
file-on-block-on-ZFS. Реакція on-call була видалити «старі снапшоти», поки пул не заспівав, що працювало тимчасово і потім стало ритуалом надзвичайної ситуації.
Виправлення не було гламурним: міграція NFS-подібних даних у datasets, експортування напряму, введення адекватного зберігання снапшотів для VM zvols і
валідація TRIM end-to-end. Розв’язати дизайн, побудований на хибному припущенні «volume vs filesystem — це просто пакування», зайняло місяць ретельної міграції.
Міні-історія 2: оптимізація, що обернулася проти («set sync=disabled, все нормально»)
Інша організація, пов’язана з фінансами і вкрай алергічна до простоїв, вела віртуалізований кластер баз даних. Латентність під час піку росла.
Хтось знайшов в форумах чарівні слова sync=disabled і запропонував це як швидке рішення. Зміна була зроблена на ієрархії zvol, що підсилювала VM-диски.
Латентність одразу покращилася. Графіки виглядали чудово. Команда оголосила перемогу і перейшла до інших пожеж. Протягом кількох тижнів усе було спокійно,
що якраз і навчає ризик ігнорувати його.
Потім стався подій з живленням: не акуратне завершення, не граційний failover — просто момент, коли UPS не впорався. Гіпервізор піднявся.
Деякі VMs завантажились. Кілька — ні. База даних завелася, але відкотила більше транзакцій, ніж комусь подобалося, і хоча б одна ФС вимагала відновлення.
Рев’ю інциденту було незручним, бо ніхто не міг прямо сказати, що вони не обміняли довговічність на продуктивність. Вони обміняли. Це те, що робить налаштування.
Відкатом було відновлення sync=standard і додавання належного SLOG-пристрою з захистом від втрати живлення. Довгострокове виправлення — культурне:
жодне «виправлення продуктивності», що змінює семантику довговічності, без письмового прийняття ризику і тесту симуляції втрати живлення.
Міні-історія 3: нудна, але правильна практика, що врятувала день (перевірка розміру send і дисципліна снапшотів)
Велика внутрішня платформа вела два датацентри з реплікацією ZFS між ними. У них була тиха, нудна практика: перед підключенням нового навантаження вони
робили тижневу «реплікаційну репетицію» зі снапшотами і zfs send -nvP, щоб оцінити інкрементальні розміри. Також вони дотримувались політик утримання
снапшотів явно: коротке зберігання для churn-томів, довше — для dataset з стабільними даними.
Команда продукту попросила «годинні снапшоти на шість місяців» для флоту VM. Платформна команда не сперечалась філософськи. Вони провели репетицію.
Інкрементали були величезними і непередбачуваними, і WAN-лінк регулярно б був насичений. Замість «ні» вони запропонували нудну альтернативу:
щоденне довготривале зберігання, годинне коротке зберігання, плюс бекапи на рівні застосунку для критичних даних. Частину даних вони також винесли з VM-дисків
у datasets через NFS, бо це були файлові дані, що прикидалися блочними.
Через місяці збій в одному сайті змусив зробити фейловер. Реплікація була актуальна, відновлення передбачуване, і постмортем був приємно неінформативним.
Похвала дісталась практиці, якій ніхто не хотів займатись, бо це не було «інженерією», а було «процесом». Вона врятувала їх.
Типові помилки: симптом → корінь → виправлення
1) Зберігання VM повільне і стрибкоподібне, особливо під час оновлень
- Симптоми: хвостові сплески латентності, зависання UI, повільні завантаження, періодичні IO-стали.
- Корінь: zvol
volblocksizeне відповідає розміру IO гостя; снапшоти утримуються занадто довго; sync-записи блокуються повільним носієм. - Виправлення: перебудувати zvol з розумним
volblocksize(часто 8K або 16K для загальних VM), зменшити утримання снапшотів, перевірити SLOG для sync-важких навантажень.
2) Пул показує багато вільного місця, але ви стикаєтесь з поведінкою “out of space”
- Симптоми: невдачі алокації, блокування записів, неможливість створити нові zvol, дивний ENOSPC в гостях.
- Корінь: thin provisioning без
refreservation; снапшоти утримують простір; пул надто заповнений (ZFS потребує запасу). - Виправлення: вимагати резервації для критичних zvols, видаляти/вичерпувати снапшоти, тримати пул нижче розумного порогу використання, реалізувати алерти ємності з урахуванням росту снапшотів.
3) Інкрементали реплікації великі для VM на zvol
- Симптоми: send/receive триває вічно, насичення мережі, пропускання RPO.
- Корінь: перезапис блоків гостьовою ФС; відсутність TRIM/UNMAP; невідповідна частота снапшотів.
- Виправлення: увімкнути та перевірити TRIM від гостя до zvol, відрегулювати каденцію снапшотів, перемістити файлові дані у datasets, протестувати estimated send sizes перед політикою.
4) «Ми вимкнули sync і нічого поганого не сталося» (поки що)
- Симптоми: дивовижна латентність; підозріло спокійні дашборди; відсутність негайних збоїв.
- Корінь: змінена семантика довговічності; ви підтверджуєте записи раніше, ніж вони безпечні.
- Виправлення: повернути
sync=standardабоsync=alwaysяк потрібно; додати належний SLOG; тестувати сценарії втрати живлення і документувати прийняття ризику, якщо наполягаєте на «обмані фізики».
5) NFS-навантаження працює погано, якщо зберігається всередині VM на zvol
- Симптоми: навантаження, що багато працює з метаданими, повільне; бекапи і відновлення незручні; відлагодження болісне.
- Корінь: зайве нашарування: файлове навантаження поміщене всередину гостя ФС на zvol, втрачені оптимізації ZFS на рівні файлів і видимість.
- Виправлення: зберігайте і експортуйте як dataset напряму; налаштуйте
recordsizeіatime; спростіть стек.
6) Відкат снапшоту «працює», але застосунок запускається пошкодженим
- Симптоми: після відкату ФС монтується, але дані застосунку неконсистентні.
- Корінь: невідповідність crash-consistency; снапшоти zvol захоплюють блоки, а не координовану паузу застосунку; снапшоти dataset теж можуть бути некоординованими без координації.
- Виправлення: зупиняти застосунки (fsfreeze, flush бази даних, hooks гостьового агента гіпервізора) перед снапшотом; періодично перевіряти процедури відновлення.
Чеклісти / покроковий план
Покроково: вибір dataset vs zvol для нового навантаження
- Визначте інтерфейс, який потрібен: файловий протокол (NFS/SMB/локальне монтування) → dataset; блочний протокол (iSCSI/VM диск) → zvol.
- Запишіть припущення про IO-шаблон: здебільшого послідовне? здебільшого випадкове? sync-важке? Це вирішує recordsize/volblocksize і потребу в SLOG.
- Виберіть найпростішу робочу схему: уникайте file-on-block-on-ZFS, якщо це не необхідно.
- Увімкніть compression=lz4 за замовчуванням, якщо немає доказів зворотного.
- Визначте політику снапшотів наперед: частота і утримання; не дозволяйте їй рости як «замінник бекапу».
- Визначте очікування реплікації: проведіть репетицію з estimated send sizes, якщо вам важливі RPO/RTO.
- Оберіть обмежувачі ємності: резервації для критичних zvols; квоти для datasets; тримайте запас у пулі.
- Документуйте відновлення: як відновити файл, VM або базу даних; включіть кроки з координації quiesce.
Чекліст: конфігурація zvol для дисків VM (продуктивний базовий набір)
- Створіть з розумним
volblocksize(часто 8K або 16K; узгодьте з гостем і гіпервізором). - Увімкніть
compression=lz4. - Тримайте
sync=standard; додайте SLOG, якщо sync-латентність важлива. - Плануйте утримання снапшотів відповідно до churn; тестуйте
zfs send -nvPдля оцінки реплікації. - Перевірте TRIM/UNMAP end-to-end, якщо очікуєте повернення простору.
- Розгляньте
refreservationдля критичних гостьових ОС, щоб запобігти pool-full катастрофам.
Чекліст: конфігурація dataset для застосунків і файлового зберігання
- Виберіть
recordsizeзгідно з IO: 1M для бекапів/медіа; менше — для навантажень, подібних до БД. - Увімкніть
compression=lz4. - Вимкніть
atime, якщо він справді не потрібен. - Використовуйте
quota/refquota, щоб запобігти ситуації «один орендар з’їв пул». - Робіть снапшоти з чіткою політикою утримання, а не накопиченням.
- Експортуйте через NFS/SMB з розумними клієнтськими налаштуваннями; вимірюйте реальними навантаженнями.
FAQ
1) Чи завжди zvol швидший за dataset для дисків VM?
Ні. Zvol може бути відмінним для дисків VM, але «швидше» залежить від поведінки sync, розмірів блоків, churn снапшотів і шляху IO гіпервізора.
Dataset, що містить QCOW2/raw файли, також може працювати дуже добре з правильним recordsize і налаштуванням кешування. Вимірюйте, не вірте інтуїції.
2) Чи можна змінити volblocksize пізніше?
Практично: ні. Розглядайте volblocksize як незмінний. Якщо ви помилилися, чисте вирішення — міграція на новий zvol з правильним розміром і контрольоване переключення.
3) Чи ставити recordsize=16K для баз даних на datasets?
Часто доречно, але не універсально. Багато баз даних використовують 8K сторінки; 16K може бути компромісом. Якщо ваше навантаження переважно послідовні сканування або великі блоби,
більший recordsize може допомогти. Профілюйте IO.
4) Чи є ZFS снапшоти бекапом?
Вони — потужний будівельний блок, але не стратегія бекапу. Снапшоти не захищають від втрати пулу, помилок оператора на пулі або реплікованої корупції, якщо ви реплікуєте занадто швидко.
Використовуйте снапшоти разом з реплікацією і/або окремим сховищем бекапів та політикою утримання.
5) Чому видалення файлів всередині VM не звільняє місце в пулі ZFS?
Тому що ZFS бачить блочний пристрій. Якщо гість не надсилає TRIM/UNMAP або стек не передає його далі, ZFS не знає, які блоки всередині гостя вільні.
6) Чи варто використовувати dedup на zvols, щоб заощадити місце?
Зазвичай ні. Dedup вимагає багато RAM і важкий в експлуатації. Стиснення зазвичай дає безпечний прибуток з меншим ризиком. Якщо ви хочете dedup — доведіть ефективність на реальних даних і закладіть RAM відповідно.
7) Чи допомагає SLOG всім записам?
Ні. SLOG допомагає синхронним записам. Якщо ваше навантаження в основному асинхронне, SLOG мало що змінить. Якщо навантаження sync-важке, коректний SLOG може стати різницею між «все добре» і «все горить».
8) Коли слід віддавати перевагу datasets для контейнерів?
Якщо ваша контейнерна платформа може використовувати ZFS datasets напряму (поширено для багатьох Linux-настроювань), datasets зазвичай дають кращу видимість і простіші операції,
ніж розміщення контейнерного сховища в VM-дисках на zvol. Мінімізуйте шари.
9) Чи можна безпечно використовувати sync=disabled для дисків VM, якщо є UPS?
UPS знижує ризик; він не усуває його. Kernel panics, controller resets, firmware bugs і людські помилки все ще існують. Якщо вам потрібна довговічність, тримайте семантику sync правильно і проектуйте апаратний шлях (SLOG з захистом від втрати живлення).
10) Який найкращий дефолт: zvol чи dataset?
За замовчуванням обирайте dataset, якщо споживач не вимагає блоку. Коли потрібен блок — використовуйте zvol навмисно: виберіть volblocksize, сплануйте снапшоти і підтвердіть TRIM та поведінку sync.
Наступні кроки, які можна виконати цього тижня
Ось практичний шлях, що зменшить майбутній біль без перетворення вашого сховища на науковий експеримент.
- Інвентаризуйте середовище: перелічіть datasets проти volumes і зіставте їх із навантаженнями. Будь-що «файлоподібне», що живе всередині zvol — червоний прапор для розслідування.
-
Аудит незворотних налаштувань: перевірте
volblocksizeна zvols іrecordsizeна ключових datasets. Запишіть невідповідності з шаблонами навантажень. -
Виміряйте податок снапшотів: визначте, які zvols/datasets мають великий
usedbysnapshots. Узгодьте утримання з бізнес-потребою, а не з тривогою. -
Перевірте поведінку sync: знайдіть будь-який
sync=disabledі обробляйте як запит на зміну, що потребує явного прийняття ризику. Якщо sync-латентність проблема — інженеруйте вирішення з SLOG, а не сподівайтеся. -
Запустіть реплікаційну репетицію: використайте
zfs send -nvP, щоб оцінити інкременти протягом тижня. Якщо числа дики, виправте драйвери churn перед обіцянкою жорстких RPO.
Одна перефразована ідея від John Allspaw (операції/надійність): Інциденти виникають через нормальну роботу в складних системах, а не через одну погану людину в поганий день.
Вибір між zvol і dataset — саме такого роду «звичайна робота» рішення. Прийміть його свідомо. Майбутнє-ви все одно матиме відмови,
але вони будуть цікавими — ті, які ви зможете виправити, а не повільними, що витікають через один неправильний примітив зберігання,
вибраний роками тому і захищений з гордістю.