Перший раз, коли ZFS підводить вас, зазвичай це не через «нестабільність». Це тому, що ви поводилися з ним як із звичайною файловою системою,
підмішали кілька «порад для продуктивності» з форуму й перевели в продакшн з усією урочистістю перенесення кімнатної рослини.
Ця дорожня карта призначена для побудови ZFS так, ніби вас будуть викликати о 03:12, сховище заповнене,
генеральний директор підключений до демо‑Wi‑Fi, і вам потрібно діагностувати вузьке місце, поки ваша кава не охолоне.
Ментальна модель ZFS: що ви насправді будуєте
ZFS — це не просто «файлова система». Це система зберігання з власними поглядами. Пул (zpool) — це ваша зона відмови та рамка продуктивності.
Датасети — це межі політики. Zvol — це блочний пристрій з гострими краями. ARC — ваш найкращий друг, поки не стане вашою
найдорожчою відмовкою «в стаджингу було швидко».
Найважливіше для усвідомлення: ZFS використовує копіювання при записі (copy-on-write). Він ніколи не перезаписує блоки на місці.
Саме так забезпечуються контрольні суми, снапшоти та консистентний стан на диску без звичайного журналювання. Це також причина,
чому фрагментація, ріст метаданих і записове підсилення можуть з’явитися в несподіваних місцях, якщо ви не сформуєте навантаження.
Думайте у шарах:
- vdev: одна група надлишковості (mirror, raidz). Якщо vdev помирає, пул зникає.
- pool: набір vdev, зшитих у смугу. Ємність і IOPS — це агрегати, поки раптом не перестають бути такими.
- dataset: адміністративна межа для властивостей (compression, recordsize, atime, квоти, резервації).
- snapshot: посилання на точку в часі; це не «бекап», це машина часу, застрягла в тому самому шасі.
- send/receive: як ви отримуєте справжні бекапи, реплікацію, міграції та жалощі в іншу систему.
Ваша дорожня карта здебільшого про вибір правильної геометрії vdev, встановлення властивостей датасету відповідно до реального I/O
та побудову операційного ритму: scrub, моніторинг, тест відновлення, повторити.
Факти та контекст, що змінюють рішення
Інженерія зберігання покращується, коли ви пам’ятаєте, що сьогоднішня «найкраща практика» здебільшого — вчорашній звіт про інцидент.
Ось кілька контекстних пунктів, які варто тримати в голові:
- ZFS походить з Sun Microsystems у середині 2000‑х як комплексна система зберігання, а не просто надбудова над файловою системою.
- Copy-on-write був вибором для консистентності: втрата живлення під час оновлення метаданих не має вимагати театру fsck.
- Енд‑ту‑енд контрольні суми дозволяють ZFS виявляти тиху корупцію, навіть коли диск «щасливо» повертає неправильні дані.
- RAIDZ — це не просто «RAID5/6» у реалізації: він уникає write hole за рахунок дизайну, але розплачується парною арифметикою та
змінною поведінкою смуг. - Раніше ZFS мав репутацію пам’яттєво ненажерливої; сучасні впровадження більш конфігуровані, але ARC усе ще масштабується разом з амбіціями.
- lz4‑сжаття стало за замовчуванням не випадково: зазвичай це «безкоштовна швидкість», бо менше байтів потрапляє на диск.
- Вирішення про вирівнювання секторів 4K (ashift) — постійне: коли ви створюєте vdev з надто маленьким ashift, це неможливо
виправити на місці. - SLOG та L2ARC історично продавалися як чарівні кнопки; у багатьох системах вони не допомагають або погіршують ситуацію.
- OpenZFS став точкою конвергенції між платформами після оригінального ліцензійного розколу; функції приходять з різною частотою на різні ОС.
Одна перефразована ідея від John Allspaw (операції/надійність): надійність приходить завдяки можливості вчитися на помилках, а не претензії, що відмов не буде.
Налаштуйте ZFS так, щоб ви могли швидко вчитися, коли він поводиться не так.
Етап 0: вирішіть, який тип відмови ви купуєте
Перш ніж виконувати команди, вирішіть три речі, які насправді визначають ваш результат:
терпимість до відмов, IO‑профіль та ризик відновлення.
Люди люблять говорити про сирі пропускні здатності. Продакшн‑системи гинуть від хвостової латентності та операційної паніки.
Mirror vs RAIDZ: обирайте, виходячи з вашого найгіршого дня
- Mirrors: найкращі для невеликих випадкових I/O, найшвидше відновлення (особливо на великих дисках), легше розширювати в майбутньому. Коштує більше ємності.
- RAIDZ1: привабливо на папері, але часто викликає жалощі на великих дисках. Один збій диска — і вас чекає дуже цікавий тиждень.
- RAIDZ2: поширений вибір для ємнісних систем; пристойний захист, повільніші дрібні випадкові записи, ніж у mirror.
- RAIDZ3: для дуже великих vdev і середовищ, де «вікна відновлення лякають».
Якщо пул підтримує чутливі до латентності навантаження (VM, БД, CI‑раннери), mirrors зазвичай — найменш поганий вибір.
Якщо це переважно послідовний об’єкт/архів, RAIDZ2 може бути хорошим громадянином.
Правило «один vdev — одна зона ураження»
Якщо будь‑який топ‑рівневий vdev виходить з ладу, пул виходить з ладу. Ось чому змішування класів пристроїв всередині vdev — погане хобі.
Також тому «я додам ще один диск пізніше» — це не план: геометрія vdev має значення.
Жарт #1: ZFS не втрачає ваших даних. Він просто призначає зустріч між вашими припущеннями та фізикою.
Етап 1: створіть перший пул (правильно)
Цей етап здебільшого про те, щоб не закласти невідкатні помилки в пул: неправильні пристрої, невірний ashift, неправильний макет.
Ставтесь до створення пулу як до проєктування схеми. Ви не «просто зміните це пізніше».
Завдання 1: ідентифікуйте диски за стабільними ідентифікаторами (не /dev/sdX‑рулетка)
cr0x@server:~$ ls -l /dev/disk/by-id/ | head
total 0
lrwxrwxrwx 1 root root 9 Dec 26 10:11 ata-SAMSUNG_MZ7L31T9HBLT-00A07_S4XXXXXXXXX -> ../../sda
lrwxrwxrwx 1 root root 9 Dec 26 10:11 ata-SAMSUNG_MZ7L31T9HBLT-00A07_S4YYYYYYYYY -> ../../sdb
lrwxrwxrwx 1 root root 10 Dec 26 10:11 wwn-0x5000c500abcdef01 -> ../../nvme0n1
lrwxrwxrwx 1 root root 10 Dec 26 10:11 wwn-0x5000c500abcdef02 -> ../../nvme1n1
Що це означає: у вас є стабільні імена (ata-*, wwn-*). ZFS зберігатиме шляхи; ви хочете шляхи, що переживуть перезавантаження та перестановки HBA.
Рішення: створюйте vdev за допомогою /dev/disk/by-id (або by-partuuid, якщо ви розбиваєте на розділи).
Завдання 2: перевірте розміри секторів, перш ніж фіксувати ashift
cr0x@server:~$ sudo lsblk -d -o NAME,MODEL,SIZE,PHY-SeC,LOG-SeC
NAME MODEL SIZE PHY-SEC LOG-SEC
sda SAMSUNG MZ7L31T9HBLT-00A 1.8T 4096 512
sdb SAMSUNG MZ7L31T9HBLT-00A 1.8T 4096 512
nvme0n1 INTEL SSDPE2KX040T8 3.7T 4096 4096
nvme1n1 INTEL SSDPE2KX040T8 3.7T 4096 4096
Що це означає: деякі диски — 512e (логічно 512, фізично 4K). ZFS має використовувати вирівнювання під 4K.
Рішення: встановіть ashift=12 для 4K. Якщо у вас обладнання з 8K/16K секторами, розгляньте вищий ashift. Не ворожіть.
Завдання 3: створіть mirror‑пул з явним ashift та розумними значеннями за замовчуванням
cr0x@server:~$ sudo zpool create -o ashift=12 -O compression=lz4 -O atime=off -O xattr=sa -O acltype=posixacl tank mirror \
/dev/disk/by-id/ata-SAMSUNG_MZ7L31T9HBLT-00A07_S4XXXXXXXXX \
/dev/disk/by-id/ata-SAMSUNG_MZ7L31T9HBLT-00A07_S4YYYYYYYYY
Що це означає: ви створили tank з mirror vdev. Властивості застосовано до кореневого датасету.
Рішення: якщо цей пул служитиме для загальних файлів і VM, mirrors — захищений початок. Якщо потрібна ємність, спроєктуйте RAIDZ2 одразу — не «мігруйте пізніше».
Завдання 4: перевірте стан пулу та макет
cr0x@server:~$ sudo zpool status -v tank
pool: tank
state: ONLINE
scan: none requested
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ata-SAMSUNG_MZ7L31T9HBLT-00A07_S4XXXXXXXXX ONLINE 0 0 0
ata-SAMSUNG_MZ7L31T9HBLT-00A07_S4YYYYYYYYY ONLINE 0 0 0
errors: No known data errors
Що це означає: помилок немає; топологія відповідає вашим намірам.
Рішення: якщо топологія виглядає неправильно, знищіть і створіть заново зараз (zpool destroy tank) до появи даних і політики.
Завдання 5: підтвердіть, що властивості справді застосовані
cr0x@server:~$ sudo zfs get -o name,property,value -s local compression,atime,xattr,acltype tank
NAME PROPERTY VALUE
tank compression lz4
tank atime off
tank xattr sa
tank acltype posixacl
Що це означає: властивості локально встановлені на кореневому датасеті.
Рішення: тримайте «політичні» властивості локальними на рівні датасету; уникайте глобальних правок, які ви не зможете пояснити пізніше.
Завдання 6: встановіть mountpoint і підтвердіть монтування
cr0x@server:~$ sudo zfs set mountpoint=/tank tank
cr0x@server:~$ mount | grep tank
tank on /tank type zfs (rw,xattr,posixacl)
Що це означає: датасет змонтовано в передбачуваному місці.
Рішення: тримайте mountpoints простими і явними. Ніхто не хоче питати «де ZFS змонтував це?» під час відновлення.
Етап 2: датасети, властивості та розумні значення за замовчуванням
Пули — для апаратури. Датасети — для людей. Ви створюєте датасети, щоб розділити політики:
вибір стиснення, recordsize, розклад снапшотів, квоти та «тут дозволено шуміти».
Структура датасетів, що переживе зростання
Практична структура (підлаштуйте назви під свій світ):
tank/sysдля ОС‑подібних файлів і конфігураційtank/homeдля користувачів (корисні квоти)tank/appsдля даних додатківtank/vmдля дисків VM (питання recordsize)tank/backupдля вхідної реплікації (інша політика снапшотів)
Завдання 7: створіть датасети і застосуйте властивості під навантаження
cr0x@server:~$ sudo zfs create tank/apps
cr0x@server:~$ sudo zfs create tank/home
cr0x@server:~$ sudo zfs create tank/vm
cr0x@server:~$ sudo zfs set compression=lz4 tank/apps tank/home tank/vm
cr0x@server:~$ sudo zfs set atime=off tank/apps tank/vm
cr0x@server:~$ sudo zfs set recordsize=16K tank/vm
Що це означає: ви створили окремі датасети і налаштували recordsize для VM‑подібного випадкового I/O.
Рішення: не ставте recordsize=16K скрізь «для продуктивності». Використовуйте там, де це відповідає I/O (VM‑диски, деякі БД).
Завдання 8: перевірте успадкування властивостей і локальні переозначення
cr0x@server:~$ sudo zfs get -r -o name,property,value,source compression,recordsize,atime tank | head -n 20
NAME PROPERTY VALUE SOURCE
tank compression lz4 local
tank recordsize 128K default
tank atime off local
tank/apps compression lz4 local
tank/apps recordsize 128K inherited from tank
tank/apps atime off local
tank/home compression lz4 local
tank/home recordsize 128K inherited from tank
tank/home atime off inherited from tank
tank/vm compression lz4 local
tank/vm recordsize 16K local
tank/vm atime off local
Що це означає: ви бачите успадкування і те, що ви свідомо переозначили.
Рішення: тримайте переозначення рідкими. Якщо все переозначено, нічого не можна пояснити.
Завдання 9: використовуйте квоти та резервації, щоб запобігти «галасливим сусідам»
cr0x@server:~$ sudo zfs set quota=500G tank/home
cr0x@server:~$ sudo zfs set reservation=200G tank/apps
cr0x@server:~$ sudo zfs get -o name,property,value tank/home quota
NAME PROPERTY VALUE
tank/home quota 500G
Що це означає: tank/home не може вирости понад 500G; tank/apps тримає 200G у резерві.
Рішення: квоти зупиняють неконтрольований ріст; резервації зберігають критичні навантаження від «тимчасових» логів.
Етап 3: налаштування продуктивності, які можна захистити
Налаштування продуктивності ZFS — це 30% параметрів і 70% чесності щодо вашого навантаження.
Почніть з вимірювання. Потім зробіть найпростіше, що усуває вузьке місце.
«Налаштувати все» — це рецепт системи, якою зможе керувати лише одна людина — і та людина у відпустці.
ARC, пам’ять і чому «більше RAM» одночасно правдиво й ліниво
ARC кешує читання й метадані. Він може приховувати повільні диски і може також конкурувати з додатками за пам’ять.
Якщо ви працюєте з базами даних або гіпервізорами, потрібно свідомо вирішити, де має жити кеш:
в додатку, в сторінковому кеші ОС, в ARC або в виділеному шарі.
Завдання 10: подивіться ARC і тиск пам’яті (приклад для Linux)
cr0x@server:~$ grep -E 'c_max|c |size|hits|misses' /proc/spl/kstat/zfs/arcstats | head
c_max 4 34359738368
c 4 26843545600
size 4 25769803776
hits 4 182736451
misses 4 24372611
Що це означає: ARC ≈ 24–25GiB, ціль ≈ 25GiB, макс 32GiB; співвідношення hits/misses показує, чи кеш допомагає.
Рішення: якщо ARC величезний і додатки своплять, обмежте ARC. Якщо misses високі і диски завантажені, більше ARC може допомогти.
Recordsize: тихий визначник успіху
recordsize — для файлових датасетів. Це максимальний розмір блоку, який ZFS використовуватиме для даних файлу.
Великий recordsize підходить для послідовного читання і кращого стискання. Малий recordsize зменшує overhead read‑modify‑write для дрібного випадкового I/O.
Але занадто малий recordsize може збільшити метадані й фрагментацію.
Zvols: коли ви хочете блочний пристрій і трохи страждання
Zvols підходять для iSCSI або бекендів VM, але вимагають дисципліни: встановіть volblocksize під час створення,
вирівняйте розділи гостя та контролюйте записове підсилення. Не змінюйте розміри блоків після факту — це неможливо.
Завдання 11: створіть zvol з навмисним volblocksize
cr0x@server:~$ sudo zfs create -V 200G -o volblocksize=16K -o compression=lz4 tank/vm/vm-001
cr0x@server:~$ sudo zfs get -o name,property,value tank/vm/vm-001 volblocksize
NAME PROPERTY VALUE
tank/vm/vm-001 volblocksize 16K
Що це означає: 200G zvol на ZFS з 16K блоками.
Рішення: підігруйте volblocksize під очікуваний I/O (зазвичай 8K–16K для багатьох VM‑патернів). Не ставте за замовчуванням.
SLOG і синхронні записи: місце, де люди витрачають гроші і все одно програють
SLOG допомагає лише для синхронних записів. Якщо навантаження переважно асинхронне, він не зрушить показників.
Якщо навантаження синхронно‑важке (БД з fsync, NFS з sync, журнали VM), SLOG може знизити латентність і захистити логи на швидкому носії.
Але поганий SLOG (без захисту від втрати живлення) може перетворити «апгрейд продуктивності» на «історію таємничої корупції».
Завдання 12: перевірте, чи ваше навантаження дійсно робить синхронні записи
cr0x@server:~$ sudo zpool iostat -v tank 1 5
capacity operations bandwidth
pool alloc free read write read write
---------- ----- ----- ----- ----- ----- -----
tank 1.02T 650G 210 1800 42.1M 155M
mirror-0 1.02T 650G 210 1800 42.1M 155M
ata-SAMSUNG_MZ7L31T9HBLT-00A07_S4XXXXXXXXX - - 105 900 21.0M 77.5M
ata-SAMSUNG_MZ7L31T9HBLT-00A07_S4YYYYYYYYY - - 105 900 21.1M 77.5M
Що це означає: ви бачите інтенсивну записувальну активність. Саме по собі це не доводить синхронність, але показує, де сидить навантаження.
Рішення: якщо клієнти, чутливі до латентності, скаржаться під час синхронно‑важких операцій, перевірте властивість sync і додавайте SLOG лише при виправданні.
Завдання 13: перевірте налаштування sync і уникайте пастки «sync=disabled»
cr0x@server:~$ sudo zfs get -o name,property,value,source sync tank tank/apps tank/vm
NAME PROPERTY VALUE SOURCE
tank sync standard default
tank/apps sync standard inherited from tank
tank/vm sync standard inherited from tank
Що це означає: ви використовуєте нормальні POSIX‑семантики.
Рішення: залишайте sync=standard, якщо не хочете пояснювати аудиторам, чому «надійність» означала «більше‑менше».
Завдання 14: перевірте фрагментацію і запас ємності перед тим, як звинувачувати ZFS
cr0x@server:~$ sudo zpool list -o name,size,alloc,free,capacity,frag,health
NAME SIZE ALLOC FREE CAPACITY FRAG HEALTH
tank 1.81T 1.02T 650G 61% 18% ONLINE
Що це означає: 61% заповнення, фрагментація 18%. Не тривожно.
Рішення: якщо заповнення >80–85% і фрагментація висока, очікуйте стрибків продуктивності. Виправте наповненість перш ніж налаштовувати.
Стиснення: зазвичай увімкнено, інколи вимкнено
lz4 — «дорослий» вибір за замовчуванням. Він зменшує фізичні записи і часто покращує пропускну здатність.
Вимикайте стиснення лише коли дані вже стиснуті (деякі мультимедіа, зашифровані бінарні файли) і ви перевірили, що CPU‑навантаження має значення.
Завдання 15: оцініть ефективність стиснення на реальних даних
cr0x@server:~$ sudo zfs get -o name,property,value -r compressratio tank/apps | head
NAME PROPERTY VALUE
tank/apps compressratio 1.62x
Що це означає: ви економите ≈38% простору у середньому, часто з меншими записами на диск.
Рішення: якщо compressratio ≈ 1.00x і CPU обмежує, розгляньте вимкнення стиснення для цього датасету.
Етап 4: захист: scrubs, снапшоти, реплікація
ZFS дає вам контрольні суми. Він не дає невразливості. Scrub знаходить латентні помилки диска. Снапшоти дають відкат.
Реплікація дає вам другу копію, яка не ділить ту саму зону відмови.
Scrubs: не опціонально і не панічна кнопка
Scrub читає всі дані і перевіряє контрольні суми, виправляючи з надлишковості, коли можливо. Це спосіб знайти поступово вмираючий диск
до того, як він перейде в стан «незчитувано під час resilver».
Завдання 16: запустіть scrub і перевірте прогрес
cr0x@server:~$ sudo zpool scrub tank
cr0x@server:~$ sudo zpool status tank
pool: tank
state: ONLINE
scan: scrub in progress since Fri Dec 26 10:42:01 2025
312G scanned at 3.20G/s, 120G issued at 1.23G/s, 1.02T total
0B repaired, 11.71% done, 0:11:23 to go
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ata-SAMSUNG_MZ7L31T9HBLT-00A07_S4XXXXXXXXX ONLINE 0 0 0
ata-SAMSUNG_MZ7L31T9HBLT-00A07_S4YYYYYYYYY ONLINE 0 0 0
errors: No known data errors
Що це означає: scrub запущено; показує швидкість сканування, issued‑швидкість і ETA.
Рішення: заплануйте scrubs (щомісяця — звичайно). Якщо scrubs йдуть «вічно», перевірте продуктивність дисків, кабелі та макет пулу.
Снапшоти: скальпель, а не звалище
Снапшоти спочатку дешеві. Потім ви зберігаєте їх назавжди, тричі перейменовуєте датасети і дивуєтеся, чому видалення не звільняє простір.
Стратегія снапшотів — це політика утримання плюс тестування відновлення. Без обох це просто директорія ілюзій.
Завдання 17: створіть і перелічіть снапшоти; інтерпретуйте використання простору
cr0x@server:~$ sudo zfs snapshot tank/apps@pre-upgrade-001
cr0x@server:~$ sudo zfs list -t snapshot -o name,used,refer,creation -s creation | tail -n 3
NAME USED REFER CREATION
tank/apps@pre-upgrade-001 12M 220G Fri Dec 26 10:55 2025
Що це означає: USED — простір, утримуваний виключно цим снапшотом; REFER — розмір, на який посилаються.
Рішення: якщо снапшоти накопичуються і простір не звільняється, перевірте USED для снапшотів і обрізайте за політикою, а не за емоціями.
Реплікація: доросла версія снапшотів
Якщо контролер пулу згорає, снапшоти на тому самому пулі настільки ж корисні, як і запасний ключ, зачинений в тому самому автомобілі.
Справжній захист означає send/receive на іншу машину, інший стій або принаймні іншу зону відмови.
Завдання 18: запустіть інкрементальне send/receive на резервний пул
cr0x@server:~$ sudo zfs snapshot tank/apps@replica-001
cr0x@server:~$ sudo zfs send -c tank/apps@replica-001 | ssh backup01 sudo zfs receive -uF backup/tank/apps
Що це означає: ви надіслали стиснений потік (-c) на backup01 і прийняли в backup/tank/apps, не змонтованим (-u), з примусовим відкатом за потреби (-F).
Рішення: потім автоматизуйте, але спочатку робіть це вручну, щоб знати, як виглядає «успіх» і як це ламається.
Завдання 19: перевірте отриманий датасет та останній снапшот на приймачі
cr0x@server:~$ ssh backup01 sudo zfs list -o name,used,avail,refer,mountpoint backup/tank/apps
NAME USED AVAIL REFER MOUNTPOINT
backup/tank/apps 220G 4.10T 220G none
Що це означає: резервний датасет існує і не змонтований (добре для безпеки).
Рішення: тримайте резервні прийоми незмонтованими за замовчуванням. Монтуйте тільки для тестів відновлення, а потім відмонтуйте знову.
Етап 5: спостережуваність та оперативні запобіжники
ZFS голосно повідомляє про помилки, коли це очевидно. Набагато підступніші відмови — тихі: поганий кабель, диск, що таймаутить раз на день,
пул, який повільно заповнюється, поки фрагментація не стане властивістю характеру.
Ваше завдання — дізнатися про це раніше за користувачів.
Завдання 20: зафіксуйте базовий рівень лічильників помилок і спостерігайте за їх зміною
cr0x@server:~$ sudo zpool status -v
pool: tank
state: ONLINE
scan: scrub repaired 0B in 0:26:41 with 0 errors on Fri Dec 26 11:08:49 2025
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ata-SAMSUNG_MZ7L31T9HBLT-00A07_S4XXXXXXXXX ONLINE 0 0 0
ata-SAMSUNG_MZ7L31T9HBLT-00A07_S4YYYYYYYYY ONLINE 0 0 0
errors: No known data errors
Що це означає: READ/WRITE/CKSUM — нулі. Чудовий базовий рівень.
Рішення: ставте алерти на зміни. Одна checksum‑помилка — «розслідувати». Тренд — «планувати обслуговування».
Завдання 21: перевірте SMART‑здоров’я дисків у vdev
cr0x@server:~$ sudo smartctl -a /dev/sda | egrep -i 'Model|Serial|Reallocated|Pending|CRC|Power_On_Hours'
Model Family: Samsung based SSDs
Serial Number: S4XXXXXXXXX
Power_On_Hours: 18422
Reallocated_Sector_Ct: 0
Current_Pending_Sector: 0
UDMA_CRC_Error_Count: 2
Що це означає: CRC‑помилки часто вказують на кабелі/бекплейн/HBA, а не на сам NAND.
Рішення: якщо CRC збільшується, переукладіть/замініть кабель або змініть відсік перед тим, як замінювати потенційно робочий диск.
Завдання 22: перевірте autotrim (SSD) і вирішіть, чи хочете його
cr0x@server:~$ sudo zpool get -o name,property,value autotrim tank
NAME PROPERTY VALUE
tank autotrim off
Що це означає: autotrim вимкнено. На SSD‑пулі TRIM може допомогти стійкій продуктивності запису.
Рішення: розгляньте zpool set autotrim=on tank для SSD‑пулів після перевірки поведінки прошивки дисків.
Завдання 23: проаналізуйте сигнали про записове підсилення на рівні датасету (логічне проти фізичного)
cr0x@server:~$ sudo zfs get -o name,property,value logicalused,used tank/vm
NAME PROPERTY VALUE
tank/vm logicalused 380G
tank/vm used 295G
Що це означає: стиснення допомагає (фізично використано менше, ніж логічно). Якби було навпаки, підозрювали б копії, паддінг або невідповідність volblocksize.
Рішення: коли logical і used розходяться у несприятливому напрямку, перевірте властивості датасету й припущення про навантаження.
Завдання 24: репетиція відновлення (єдиний тест, що має значення)
cr0x@server:~$ ssh backup01 sudo zfs clone backup/tank/apps@replica-001 backup/tank/apps-restore-test
cr0x@server:~$ ssh backup01 sudo zfs set mountpoint=/mnt/restore-test backup/tank/apps-restore-test
cr0x@server:~$ ssh backup01 mount | grep restore-test
backup/tank/apps-restore-test on /mnt/restore-test type zfs (rw,xattr,posixacl)
Що це означає: ви створили записуваний клон зі снапшоту і змонтували його.
Рішення: заплануйте тести відновлення. Якщо ви цього не робите, перше відновлення відбудеться під час інциденту — сміливий вибір.
План швидкої діагностики
Коли продуктивність падає, потрібен шлях, що швидко сходиться. Не тижневе інтерпретативне танцювання з графіками.
Цей план припускає інструменти Linux/OpenZFS, але логіка загальна.
Перше: чи пул здоровий і чи щось відновлюється?
- Перевірка:
zpool status -v - Що шукати: scrub/resilver у процесі, DEGRADED vdev, checksum‑помилки, повільні пристрої
- Рішення: якщо йде resilver, очікуйте зниження продуктивності; віддавайте пріоритет безпечному завершенню відновлення над «налаштуваннями».
Друге: чи в нас закінчується місце або сильна фрагментація?
- Перевірка:
zpool list -o size,alloc,free,capacity,frag - Що шукати: заповнення > 80–85%, frag > ~50% (залежно від контексту)
- Рішення: якщо повно/фрагментовано, звільніть місце і видаліть снапшоти (обережно). Не ганяйтеся спочатку за arcane sysctls.
Третє: де вузьке місце: диск, CPU, пам’ять чи sync‑латентність?
- Диск:
zpool iostat -v 1показує один пристрій «прикований» або значно повільніший за сусідів. - CPU: стиснення/checksum може бути обмеженням на малих ядрах; перевіряйте за допомогою системних інструментів CPU.
- Пам’ять: thrashing ARC або свопінг системи: перевірте розмір ARC і активність свопу.
- Sync‑записи: сплески латентності під час fsync‑важких навантажень; SLOG може допомогти, якщо правильно спроєктований.
Четверте: визначте датасет і шаблон навантаження
- Перевірка: який датасет «гарячий» (логи додатків, диски VM, імпорт бекапів)
- Що шукати: невірний
recordsizeдля навантаження, забагато снапшотів, що утримують простір, несподівана поведінкаsync - Рішення: налаштуйте на межі датасету. Уникайте змін для всього пулу, якщо ви не вирішуєте проблему пул‑рівня.
Три корпоративні міні‑історії (такі, що запам’ятовуються)
Інцидент: хибне припущення (мислення 512‑байт у 4K‑світі)
Середня SaaS‑компанія побудувала новий аналітичний кластер на блискучих великих HDD за поважним HBA. Архітектор вибрав ZFS через контрольні суми
й снапшоти, бо стара система зберігання була як волога картонка. Скрипт для створення пулу «працював».
Через шість місяців латентність записів почала повзти вгору. Не катастрофічно — достатньо, щоб батч‑джоби пропустили вікно. Потім час resilver після заміни одного диска
перетворився на багатоденну подію. Під час resilver продуктивність упала в прірву і так залишилась. Команда вважала, що «великі диски довго відновлюються»
і прийняла біль як ціну за ємність.
Хтось нарешті зробив повний базовий огляд: розміри секторів, ashift і реальне фізичне вирівнювання. Пул був побудований з ashift=9, бо диски
повідомляли логічні 512 сектори і ніхто не перевірив фізичний розмір. Кожен запис перетворювався на read‑modify‑write цикл на диску.
ZFS робив те, що йому наказали; диски робили те, що вимагала фізика.
Вони мігрували дані в новий пул з ashift=12. Продуктивність нормалізувалась. Resilver‑процеси стали значно швидшими.
Звіт по інциденту був болісно простий: «Ми припустили, що диск говорить правду.» Коригувальна дія також проста:
«Ми перевірятимемо PHY‑SeC і явно ставитимемо ashift.» Урок: ZFS вірно збереже ваші помилки.
Оптимізація, що дала назад: ера «sync=disabled»
Інша компанія тримала ферму VM на ZFS mirror. Розробники скаржилися на періодичні сплески латентності в пікові години деплоїв.
Хтось загуглив. Хтось знайшов налаштування. Хтось сказав: «Нам не потрібні синхронні записи; у нас є UPS.»
sync=disabled застосували на рівні датасету для зберігання VM.
Сплески зникли. Тікети закрилися. У Slack лунали п’ятихвилинки оптимізму.
Через два місяці хост перезавантажився несподівано після kernel panic. UPS був у порядку. Диски були в порядку. VM — ні.
Декілька повернулися з пошкодженими файловими системами. Не всі. Достатньо, щоб інцидент переслідував.
Розбір був суворий, але простий: синхронні семантики були вимкнені, тож підтверджені записи не були обов’язково стійкими.
Креш стався в вікні, де кілька гістьових ОС вірили, що їхні дані збережені. Насправді — ні. ZFS зробив саме те, що було налаштовано.
Вони повернули sync=standard, поміряли ще раз і вирішили реальну проблему: насичений шлях запису плюс погане чергування під час хвиль деплоїв.
Додали ємності й згладили сплески I/O. Мораль не «ніколи не оптимізуйте». Мораль — «оптимізуйте з планом rollback і чітким визначенням коректності».
Жарт #2: Вимкнути синхронні записи — як зняти датчик диму, бо він гучний. Тихіше, так. Розумніше — ні.
Сумна, але правильна практика, що врятувала день: щомісячні scrubs і культура алертів
Фінансова команда підтримувала простий файловий сервіс на ZFS. Нічого особливого: mirror vdev, стиснення lz4, консервативні політики датасетів.
У них була звичка, про яку ніхто не хвалився: щомісячні scrubs і алерти на нові checksum‑помилки або DEGRADED vdev.
Ротація on‑call це ненавиділа, але не ігнорувала.
Одного четверга спрацював алерт: кілька checksum‑помилок на одному диску, потім ще. Пул лишався ONLINE. Користувачі нічого не помітили.
Інженер не «почекали і подивимося». Він перевірив SMART, побачив зростання CRC‑помилок і запідозрив кабель або відсік.
Запланували вікно обслуговування і переставили диск в інший слот. CRC‑помилки зупинилися.
Через два тижні інший диск почав кидати реальні помилки носія, і ZFS виправив їх під час scrub. Команда замінила диск у робочий час.
Ніякої аварії. Ніяких тривалих зупинок. Система залишилася нудно робочою.
Секрет не у геніальності. Він у циклі: регулярно робити scrub, сигналізувати рано, трактувати малі лічильники помилок як дим і валідувати шлях (кабелі, HBA, прошивка),
а не лише диск. У зберіганні нудне — це функція, яку варто доставляти.
Поширені помилки: симптоми → корінна причина → виправлення
1) «Видалення не звільняє простір»
- Симптоми: додаток видаляє дані, але використання пулу залишається стабільним;
dfне змінюється. - Корінна причина: снапшоти утримують посилання на блоки; іноді й клони також.
- Виправлення: перелічіть снапшоти за використанням простору і обрізайте за політикою.
cr0x@server:~$ sudo zfs list -t snapshot -o name,used -s used | tail
tank/apps@daily-2025-12-20 18.2G
tank/apps@daily-2025-12-21 21.4G
tank/apps@daily-2025-12-22 25.7G
2) «Random I/O жахливий на RAIDZ»
- Симптоми: латентність VM, IOPS нижче очікувань; записи «липучі».
- Корінна причина: накладні витрати парності RAIDZ плюс дрібні випадкові записи; невідповідний recordsize; пул занадто повний.
- Виправлення: використовувати mirrors для навантажень, чутливих до латентності, або окремі RAIDZ для ємності; налаштувати recordsize для «гарячого» датасету; тримати запас ємності.
3) «Scrub триває вічно і система повзає»
- Симптоми: scrubs тягнуться днями; сервіси повільні; iostat показує низьку пропускну здатність.
- Корінна причина: повільний або збійний диск, поганий HBA/кабель, SMR‑диски в маскуванні, або важке конкурентне навантаження.
- Виправлення: ідентифікуйте повільний пристрій за допомогою
zpool iostat -v; перевірте SMART; замініть проблемне обладнання; плануйте scrubs поза піком.
4) «Ми додали L2ARC і нічого не стало швидше»
- Симптоми: купили SSD‑кеш; латентність незмінна; ARC‑статистика схожа.
- Корінна причина: навантаження не підходить для кешування читань, або L2ARC замалий/повільний, або система CPU/пам’ять‑обмежена.
- Виправлення: виміряйте коефіцієнти попадань у кеш; пріоритезуйте RAM/ARC і кращу геометрію vdev перед додаванням L2ARC.
5) «Resilver надто повільний»
- Симптоми: заміна диска займає багато часу; продуктивність під час resilver жахлива.
- Корінна причина: великі HDD, геометрія RAIDZ, високе заповнення пулу, поведінка SMR, або проблемний диск, що тягне vdev.
- Виправлення: віддавайте перевагу mirror для швидкого відновлення; тримайте пул менше ≈80%; замінюйте підозрілі диски превентивно; не змішуйте повільні та швидкі пристрої в одному vdev.
6) «З’являються checksum‑помилки, але диски “в порядку”»
- Симптоми:
zpool statusпоказує CKSUM‑помилки; SMART виглядає нормально. - Корінна причина: проблеми з кабелями/бекплейном/HBA/прошивкою; транзитні помилки транспорту.
- Виправлення: перевірте SMART CRC‑лічильники; переукладіть/замініть кабелі; спробуйте інші відсіки; оновіть прошивку HBA; потім очистіть помилки і моніторьте.
7) «Ми не можемо розширити RAIDZ vdev так, як очікували»
- Симптоми: додали один диск, ємність майже не змінилась або розширення неможливе.
- Корінна причина: геометрія топ‑рівневого vdev фіксована; ви розширюєте шляхом додавання нових vdev (або через нові можливості платформи/версії з обмеженнями).
- Виправлення: плануйте ширину vdev з першого дня; для зростання додавайте ще один vdev схожого класу продуктивності; уникайте «франкенштейн‑пулів».
Чеклісти / покроковий план
План A: від першого пулу до «достатньо безпечного» продакшну за 10 кроків
- Інвентаризація обладнання: підтвердіть тип дисків, розміри секторів, модель HBA і наявність захисту від втрати живлення на SSD.
- Вибір топології: mirrors для латентності, RAIDZ2/3 для ємності; уникайте RAIDZ1 на великих дисках, якщо вам не подобається азарт.
- Назвіть пристрої розумно: використовуйте шляхи
/dev/disk/by-id; документуйте відповідність відсіків. - Створіть пул явно: встановіть
ashiftі властивості кореневого датасету (compression, atime, xattr). - Створіть датасети за навантаженням: apps vs VMs vs users; встановіть recordsize і політику sync свідомо.
- Встановіть обмеження ємності: квоти для «людей», резервації для «не повинно падати».
- Графік scrub: щомісячний базовий; частіше, якщо диски підозрілі або середовище суворе.
- Політика снапшотів: наприклад, щогодини 24h, щодня 30d, щомісяця 12m — налаштуйте під бізнес‑потреби і бюджет зберігання.
- Реплікація: send/receive на іншу систему; тестуйте відновлення через клон зі снапшоту.
- Моніторинг: алерти на DEGRADED, checksum‑помилки, зростання SMART CRC/realloc/pending, пороги заповнення пулу та невдачі scrub.
План B: міграція від «воно існує» до «воно придатне в експлуатацію» без фантазій про відсутність даунтайму
- Припиніть робити зміни для всього пулу. Почніть вимірювати і документувати поточний стан:
zpool status,zpool list,zfs get all(відфільтровано). - Розділіть датасети за навантаженням, щоб налаштовувати і робити снапшоти незалежно.
- Впровадьте політику ретеншну і обріжте снапшоти, що більше не потрібні для відновлення.
- Налаштуйте реплікацію і проведіть тест відновлення. Доведіть це до себе за допомогою змонтованого клону.
- Сплануйте «невідворотні виправлення» (неправильний ashift, неправильна топологія) як міграцію в новий пул. Магічного тумблера немає.
Операційний ритм (що робити щотижня/щомісяця/щокварталу)
- Щотижня: перегляд алертів, перевірка нових лічильників помилок, підтвердження запуску джобів снапшотів, валідація прогнозів заповнення.
- Щомісяця: scrub, перегляд трендів тривалості scrub, перевірка хоча б одного тесту відновлення з реплікації.
- Щокварталу: репетиція сценарію «відмова диска + відновлення», перегляд властивостей датасетів відповідно до змін навантажень, валідація базових прошивок.
FAQ
1) Обирати mirrors чи RAIDZ для зберігання VM?
Mirrors, якщо у вас немає вагомої причини і протестованого профілю навантаження. VM зазвичай виконують дрібні випадкові I/O і карають накладні витрати парності RAIDZ.
Якщо мусите використовувати RAIDZ, тримайте ширину vdev розумною, зберігайте запас ємності і налаштовуйте recordsize для датасетів VM.
2) Чи прийнятний RAIDZ1 колись?
На маленьких дисках і некритичних даних — можливо. На великих сучасних дисках RAIDZ1 підвищує ризик того, що друга проблема під час resilver виведе пул з ладу.
Якщо ви не можете терпіти недоступність і довгий час відновлення, не запускайте однопаритний режим.
3) Яке стиснення варто використовувати?
lz4 для майже всього. Вимикайте лише для датасетів, де дані вже стиснені або зашифровані, і ви виміряли вплив на CPU.
4) Наскільки можна заповнювати пул?
Намагайтеся тримати нижче ≈80% для здорової продуктивності, особливо на RAIDZ і змішаних навантаженнях. Вище — фрагментація і поведінка алокацій можуть значно підвищити латентність.
Точний «обрив» залежить від навантаження, але фраза «ми довели до 95%» часто передує інциденту.
5) Чи потрібен мені SLOG?
Лише якщо у вас значні синхронні записи і ви піклуєтеся про їхню латентність. Якщо навантаження переважно асинхронне, SLOG не допоможе.
Якщо додаєте, використовуйте витривалі пристрої з захистом від втрати живлення. Дешеві споживчі SSD — не журнал, а провідник сюрпризів.
6) Чи потрібен L2ARC?
Зазвичай — ні на початку. Почніть з RAM (ARC) і правильної топології пулу. L2ARC може допомогти при читально‑важких навантаженнях з робочим набором більшим за RAM,
але він споживає пам’ять для метаданих і додає складності.
7) Чи можна змінити ashift після створення пулу?
Ні. Не на місці. Неправильний ashift виправляється міграцією даних у новий правильно створений пул. Це причина, чому перевірка розміру секторів — завдання дня 0.
8) Як дізнатися, чи снапшоти причина, що простір не звільняється?
Перелічіть снапшоти і відсортуйте за used. Якщо є великі снапшоти — вони утримують блоки. Видаліть снапшоти (обережно, за політикою),
потім спостерігайте зміну простору. Також перевірте наявність клонів.
9) Чи є ZFS «бекапом», бо має снапшоти?
Ні. Снапшоти — локальні точки відновлення. Бекапи вимагають окремих зон відмови. Використовуйте send/receive реплікацію (або іншу систему бекапів) і тестуйте відновлення.
10) Яка найкраща звичка, щоб уникати жалю?
Робіть регулярні тести відновлення з реплікації. Все інше — лише управління ймовірностями; тест відновлення — це правда.
Висновок: практичні наступні кроки
Якщо ви прагнете «продакшну без жалю», не ганяйтесь за екзотичними прапорцями. Зробіть три хороші структурні рішення (топологія, ashift, межі датасетів),
потім запускайте нудний операційний цикл (scrub, снапшот, реплікація, тест відновлення, моніторинг помилок).
Наступні кроки, які ви можете зробити цього тижня:
- Запишіть у один абзац топологію пулу і терпимість до відмов. Якщо не можете — у вас ще немає дизайну.
- Створіть датасети для трьох головних навантажень і свідомо встановіть властивості (compression, recordsize, atime, квоти).
- Запустіть scrub і зафіксуйте час виконання. Тренд цієї тривалості стане сигналом здоров’я.
- Налаштуйте реплікацію через send/receive на іншу систему і проведіть один тест відновлення через клон і монтування.
- Перетворіть базові перевірки на алерти: стан пулу, заповнення, checksum‑помилки і SMART‑індикатори транспорту/носія.
ZFS подарує вам цілісність даних і операційну перевагу. Він також охоче збереже кожне ваше хибне припущення.
Обирайте припущення так, ніби дзвонить вам на пейджер. Бо саме вам.