ZFS має репутацію: або це файлова система, що рятує вашу кар’єру, або та, що непомітно з’їдає оперативну пам’ять, поки ваша база даних плаче. Обидві історії можуть бути правдою. ZFS — це не «файлова система» у вузькому сенсі; це система зберігання, яка розглядає диски, надмірність, кешування та цілісність даних як єдину задачу дизайну. Ось чому вона може здаватися чарівною, коли підходить, і впертою, коли ні.
Це операційний погляд: що ZFS реально дає на реальному обладнанні з реальними режимами відмов, як її перевіряти командами, які ви використовуватимете о 2 ночі, і чесні випадки, коли ext4 або XFS просто кращий інструмент. Якщо ви шукаєте релігію — ви в неправильній кімнаті. Якщо ви хочете зберігати дані правильними й затримки непомітними — читайте далі.
Зміст
- 1) Що таке ZFS насправді (і чому воно поводиться інакше)
- 2) Що ви отримуєте на практиці
- 3) Коли перемагають ext4/XFS (і чому це не є єрессю)
- 4) Цікаві факти й історичний контекст
- 5) Практичні завдання: команди, які ви справді виконуватимете
- 6) Швидка діагностика (як швидко знайти вузьке місце)
- 7) Три короткі корпоративні історії
- 8) Поширені помилки: симптоми й виправлення
- 9) Контрольні списки / покроковий план
- 10) FAQ
- Висновок
1) Що таке ZFS насправді (і чому воно поводиться інакше)
З ext4 або XFS зазвичай у вас є блочний пристрій (можливо RAID-том, можливо LVM) і файлова система зверху. ZFS перевертає стек: воно володіє «RAID», менеджментом томів і файловою системою, тому може забезпечувати наскрізну цілісність. Ось чому в ZFS більше говорять про пули, vdev та datasets, ніж про «розділи».
Основна модель у двох словах
Пул ZFS (zpool) складається з одного або більше vdev (віртуальних пристроїв). Vdev може бути дзеркалом, групою RAIDZ, окремим диском (будь ласка, не робіть так) або пристроєм для спеціальних цілей. ZFS страйпить дані по vdev, а не по дисках всередині vdev. Ця різниця важлива при збільшенні ємності чи продуктивності: додавання vdev підвищує пропускну здатність; змінити тип vdev… — це не те, що робиться просто так.
Copy-on-write — це функція, що лежить в основі інших можливостей
ZFS використовує copy-on-write (CoW). Коли ви змінюєте блок, він записує новий блок в інше місце і лише потім оновлює метадані, щоб посилатися на нього. Це робить знімки дешевими (це просто старі вказівники) і зменшує ймовірність «пошарпаних» записів. Але це також означає, що фрагментація поводиться інакше, а синхронні параметри запису — це перша класа змінна продуктивності.
Наскрізні контрольні суми: те, чого ви не помічаєте, поки не помітите
Кожен блок має контрольну суму, збережену в батьківських метаданих. Читання перевіряють контрольні суми; відновлення відбувається автоматично, якщо є надмірність. Це не «параноя по битроту». Це базова гігієна в світі, де диски, контролери, прошивки й кабелі іноді брешуть.
Жарт №1: ZFS як датчик диму — ви зазвичай помічаєте його лише коли він кричить, і тоді ви дуже раді, що він був встановлений.
2) Що ви отримуєте на практиці
2.1 Цілісність даних, яку можна експлуатувати
Чесна презентація: ZFS ловить мовчазну корупцію, яку інші стеки можуть безтурботно передати вашому застосунку як «валідні дані». Воно робить це за допомогою контрольних сум на кожному блоці і самовідновлення при наявності надмірності (mirror/RAIDZ). На практиці це експлуатується через scrubs, які обходять пул і верифікують все.
Що це змінює у щоденних операціях:
- Ви можете запланувати scrub і трактувати помилки контрольних сум як конкретний сигнал, а не як привид.
- Ви можете довести, що резервна копія консистентна на рівні зберігання, а не лише «вона завершилася».
- Ви можете проактивно замінювати нестабільні диски, бо ZFS скаже, що він ремонтує, а не просто падає.
2.2 Знімки, що достатньо швидкі, щоб бути нудними
Знімки ZFS майже миттєві, бо це маркери метаданих. На практиці це змінює вашу операційну постановку: ви можете зробити знімок перед ризикованими змінами, робити знімки часто для відновлення після ransomware, і тримати короткі періоди зберігання без паніки від I/O-штормів.
Підвох тонкий: знімки дешево створювати, але не безкоштовно зберігати. Якщо ви тримаєте тисячі і потім робите багато випадкових перезаписів, змінюються метадані й профіль фрагментації. ZFS все одно працюватиме; але ваша latency SLO може страждати.
2.3 Компресія, що переважно допомагає більше ніж шкодить
Сучасна компресія ZFS (зазвичай lz4) — це одна з тих рідкісних функцій, що одночасно продуктивна і корисна. Ви часто отримуєте кращу ефективну пропускну здатність, бо рухаєте менше байтів з диска. Для багатьох навантажень це «безкоштовний обід» — але це не безкоштовно; це «оплачено» CPU, який у вас може вже бракувати.
На практиці: вмикайте compression=lz4 для більшості datasets за замовчуванням, якщо у вас немає виміряної причини не робити цього (наприклад, вже стиснені медіафайли або пристрої з дефіцитом CPU).
2.4 Управління на рівні dataset: квоти, резервації і розумне мультиорендне зберігання
Datasets ZFS дають вам властивості на рівні дерева: compression, recordsize, atime, квоти, резервації, розклад знімків, mountpoints. Тут ZFS відчувається як платформа зберігання, а не просто «файлова система». У корпоративних системах це часто різниця між «хаосом спільного NFS-сервера» і «передбачуваним сервісом зберігання».
2.5 Передбачувана реплікація за допомогою send/receive
zfs send/zfs receive — це практичний подарунок. Вони реплікують знімки як потоки, а інкрементальні потоки можуть бути ефективними. Коли це налаштовано чисто, це не просто бекап — це шлях відновлення, стратегія міграції та DR-механізм, який можна тестувати без героїки.
2.6 Звідки беруться несподіванки продуктивності
ZFS може бути надзвичайно швидким, але воно чутливе до шаблонів навантаження та конфігурації. Найпоширеніший «сюрприз» у продакшені — це синхронні записи: якщо ваше навантаження інтенсивно використовує fsync() (бази даних, NFS, образи VM), ZFS виконає їх. Без належного SLOG (і належного захисту від втрати живлення) це може перетворитися на сплески латентності, що виглядають як «ZFS повільний». Воно не повільне; воно чесне.
Жарт №2: ZFS не втрачає ваші дані — воно просто змушує вас зустрітися з вашими припущеннями, що якось гірше.
3) Коли перемагають ext4/XFS (і чому це не єрессю)
3.1 Коли простота — ваш SLO
ext4 — це Toyota Corolla серед файлових систем Linux: не захоплює, але заводиться щоранку. Якщо у вашому стеку зберігання вже є надмірність і гарантії цілісності (хороший RAID-контролер із кешем + BBU, корпоративний SAN із контрольними сумами, хмарне блочне сховище з гарантіями цілісності), ext4 може бути правильним вибором, бо має менше рухомих частин і менше ручок для неправильних налаштувань.
XFS подібно «нудне в хорошому сенсі», особливо для великих файлів, паралельного I/O і деяких metadata-важких навантажень, де його allocation groups добре масштабуються.
3.2 Коли ви не можете дозволити побічні ефекти CoW
Copy-on-write змінює шаблон запису. Для деяких навантажень — особливо тих, що перезаписують блоки на місці, очікуючи стабільну локальність — CoW може створити фрагментацію і збільшити read amplification з часом. Ви можете пом’якшити це, налаштувати або проектувати навколо. Але якщо ви хочете «писати байти на місці, зберігати локальність», XFS/ext4 може забезпечити більш передбачувану довгострокову поведінку.
3.3 Коли потрібні мінімальні накладні витрати
Контрольні суми, метадані та функції ZFS коштують ресурсів. Часто ви повертаєте ці витрати (компресія, менше корупцій, простіші знімки). Але для дуже скромних систем — вбудованих пристроїв, мінімальних VM або середовищ, де RAM на вагу золота — ext4 може перемогти просто через малий пам’ятний і CPU слід, який легко прогнозувати.
3.4 Коли ваша операційна команда не готова до ZFS
Це не образа; це реальність. ZFS зручний в експлуатації, коли його знають, але він вимагає розуміння розмітки vdev, ashift, scrubs, керування знімками і ARC. Якщо у вас немає людей, які візьмуть на себе ці деталі, ext4/XFS зменшують площу для тонких помилок.
3.5 Коли потрібні схеми онлайн-зростання, яких ZFS не пропонує
Розширення ZFS базується на vdev. Ви часто можете збільшити дзеркало, замінивши диски на більші і давши йому resilver-нутися, або додати нові vdev, щоб розширити пул. Але ви не можете просто «перетворити RAIDZ1 у RAIDZ2» після факту, і ребалансування даних між vdev не таке, як традиційна reshape RAID. Якщо ваша закупівельна реальність вимагає частих незручних переробок, ext4/XFS зверху LVM/MDRAID може підходити краще.
4) Цікаві факти & історичний контекст (коротко, конкретно)
- ZFS було розроблено в Sun Microsystems у середині 2000-х як частину Solaris, щоб замінити розподіл «volume manager + filesystem» і зменшити ризик корупції.
- Його твердження про «128-бітну файлову систему» — переважно спосіб сказати «нам не скоро закінчиться простір», а не обіцянка приєднати диски розміром Юпітера.
- Наскрізні контрольні суми ZFS були прямою реакцією на мовчазну корупцію в реальних стеках зберігання — не теоретичні космічні промені, а звичайні збої апаратури й прошивки.
- Copy-on-write знімки стали практичним ops-інструментом у ZFS задовго до того, як «знімки» стали мейнстрімом у VM і контейнерних платформах.
- ZFS популяризувало ідею, що компресія може бути фічею продуктивності, а не лише трюком економії місця — бо зменшення I/O може бути швидшим за переміщення сирих байтів.
- OpenZFS еволюціонував як багатоплатформенна відкрита реалізація; на Linux воно стало де-факто стандартом для використання ZFS, незважаючи на ліцензійні обмеження, що тримають його поза деревом ядра.
- RAIDZ — це не просто «RAID5/6 під брендом». Деталі реалізації (змінна ширина смуги, вказівники блоків) роблять його поведінку відмінною — особливо при часткових записах.
- Scrub ZFS відрізняються від RAID «consistency checks». Вони верифікують контрольні суми наскрізь і можуть ремонтувати за наявності надмірності.
- ARC (Adaptive Replacement Cache) — це більше, ніж page cache; це кеш, керований ZFS, з політиками, які можна налаштовувати й спостерігати.
5) Практичні завдання: команди, які ви справді виконуватимете
Усі приклади припускають Linux з встановленим OpenZFS. Замініть імена пулів/dataset за потреби. Після кожної команди я скажу, що означає в операційній практиці, а не академічно.
Завдання 1: Інвентаризація пулів і базове здоров’я
cr0x@server:~$ sudo zpool list
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
tank 7.25T 3.10T 4.15T - - 12% 42% 1.00x ONLINE -
cr0x@server:~$ sudo zpool status -x
all pools are healthy
Інтерпретація: FRAG — це підказка, а не вирок, але якщо вона росте і продуктивність падає, ви пов’яжете це з навантаженням. status -x — ваш швидкий «щось горить?» чек.
Завдання 2: Отримати детальну картину під час проблем
cr0x@server:~$ sudo zpool status -v tank
pool: tank
state: ONLINE
scan: scrub repaired 0B in 04:12:55 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-SAMSUNG_SSD_1 ONLINE 0 0 0
ata-SAMSUNG_SSD_2 ONLINE 0 0 0
errors: No known data errors
Інтерпретація: лічильники READ/WRITE/CKSUM кажуть вам, чи маєте справу з помираючим диском, хитким кабелем/контролером чи реальною корупцією на диску. «Scrub repaired» не завжди означає паніку, але це підстава для тикету.
Завдання 3: Подивитись datasets і куди пішов простір
cr0x@server:~$ sudo zfs list -o name,used,avail,refer,mountpoint
NAME USED AVAIL REFER MOUNTPOINT
tank 3.10T 3.92T 192K /tank
tank/home 420G 3.92T 410G /home
tank/vm 1.90T 3.92T 1.20T /tank/vm
tank/backups 780G 3.92T 120G /tank/backups
Інтерпретація: USED включає знімки та нащадків. REFER — це «живі дані в цьому dataset». Якщо USED великий, а REFER помірний — знімки ймовірно винуватці.
Завдання 4: Швидко знайти роздування через знімки
cr0x@server:~$ sudo zfs list -t snapshot -o name,used,refer,creation -s used | tail -n 5
tank/vm@auto-2025-12-24-0100 120G 1.20T Wed Dec 24 01:00 2025
tank/vm@auto-2025-12-23-0100 118G 1.19T Tue Dec 23 01:00 2025
tank/vm@auto-2025-12-22-0100 111G 1.18T Mon Dec 22 01:00 2025
tank/vm@auto-2025-12-21-0100 109G 1.18T Sun Dec 21 01:00 2025
tank/vm@auto-2025-12-20-0100 103G 1.17T Sat Dec 20 01:00 2025
Інтерпретація: це used — «унікальні блоки, які утримує знімок». Якщо він росте щодня — ваш churn високий (образи VM, бази даних). Плануйте ретеншн відповідно.
Завдання 5: Перевірити ключові властивості, що змінюють продуктивність
cr0x@server:~$ sudo zfs get -o name,property,value -s local,default recordsize,compression,atime,sync,logbias tank/vm
NAME PROPERTY VALUE
tank/vm atime off
tank/vm compression lz4
tank/vm logbias latency
tank/vm recordsize 128K
tank/vm sync standard
Інтерпретація: recordsize має відповідати домінантному розміру I/O для файлів (бази даних часто віддають перевагу 16K/8K, образи VM — 16K/64K залежно від випадку). sync і logbias визначають, як ZFS обробляє синхронні навантаження.
Завдання 6: Безпечно вмикнути компресію на dataset
cr0x@server:~$ sudo zfs set compression=lz4 tank/home
cr0x@server:~$ sudo zfs get -o name,property,value compression tank/home
NAME PROPERTY VALUE
tank/home compression lz4
Інтерпретація: Це впливає на нові записані блоки. Воно не перезапише старі дані, якщо ви їх не перезапишете/скопіюєте. Операційно — це добре: можна вмикати без великої міграції.
Завдання 7: Виміряти, чи допомагає компресія
cr0x@server:~$ sudo zfs get -o name,property,value compressratio,logicalused,used tank/home
NAME PROPERTY VALUE
tank/home compressratio 1.42x
tank/home logicalused 580G
tank/home used 420G
Інтерпретація: Якщо compressratio близько 1.00x для dataset із вже стисненими даними, ви марнуєте CPU даремно. Якщо це 1.3x+ на загальних dataset — зазвичай виграш по суті.
Завдання 8: Запустити і моніторити scrub
cr0x@server:~$ sudo zpool scrub tank
cr0x@server:~$ sudo zpool status tank
pool: tank
state: ONLINE
scan: scrub in progress since Wed Dec 24 02:10:11 2025
1.25T scanned at 1.10G/s, 410G issued at 360M/s, 3.10T total
0B repaired, 13.2% done, 0:02:41 to go
Інтерпретація: «scanned» проти «issued» каже, скільки даних фактично читається проти обходу метаданих. Якщо scrubs займають вічність, можливо ви обмежені IOPS або маєте повільні/SMR диски.
Завдання 9: Замінити несправний диск у дзеркалі (поширений випадок)
cr0x@server:~$ sudo zpool status tank
pool: tank
state: DEGRADED
config:
NAME STATE READ WRITE CKSUM
tank DEGRADED 0 0 0
mirror-0 DEGRADED 0 0 0
ata-SAMSUNG_SSD_1 ONLINE 0 0 0
ata-SAMSUNG_SSD_2 FAULTED 12 0 3 too many errors
cr0x@server:~$ sudo zpool replace tank ata-SAMSUNG_SSD_2 /dev/disk/by-id/ata-SAMSUNG_SSD_NEW
cr0x@server:~$ sudo zpool status tank
scan: resilver in progress since Wed Dec 24 03:01:10 2025
210G scanned at 2.5G/s, 88G issued at 1.0G/s, 3.10T total
88G resilvered, 2.8% done, 0:49:12 to go
Інтерпретація: Замінюючи через /dev/disk/by-id ви уникаєте рулетки імен пристроїв після перезавантажень. Моніторьте швидкість resilver; якщо вона повзе — пул зайнятий або одна сторона хвора.
Завдання 10: Підтвердити ashift (вирівнювання розміру секторів) перед створенням пулу
cr0x@server:~$ sudo zdb -C tank | grep -E "ashift|vdev_tree" -n | head
35: ashift: 12
36: asize: 7998634579968
Інтерпретація: ashift=12 означає 4K сектори. Помилковий ashift — це постійний податок. Якщо у вас вийшло ashift=9 на сучасних 4K/8K пристроях, ви можете платити за це вічно через write amplification.
Завдання 11: Спостерігати поведінку ARC (чи допомагає RAM чи її бракує?)
cr0x@server:~$ cat /proc/spl/kstat/zfs/arcstats | egrep "size|c_max|hit|miss" | head
hits 1802345678
misses 234567890
size 17179869184
c_max 25769803776
Інтерпретація: Високий hit rate зазвичай означає, що читання обслуговуються з RAM. Якщо misses підіймаються під час доступу до робочого набору — ви обмежені RAM або ваш шаблон доступу занадто великий/випадковий для ефективного кешування.
Завдання 12: Дивитися I/O пулу і латентність у реальному часі
cr0x@server:~$ sudo zpool iostat -v tank 1
capacity operations bandwidth
pool alloc free read write read write
---------- ----- ----- ----- ----- ----- -----
tank 3.10T 4.15T 820 1600 210M 380M
mirror-0 3.10T 4.15T 410 800 105M 190M
sda - - 205 400 52.5M 95.0M
sdb - - 205 400 52.5M 95.0M
Інтерпретація: Якщо один диск виконує непропорційно багато роботи в дзеркалі — підозрюйте помилки, проблеми з прошивкою або пристрій, що тихо повільніший. Якщо ops високі, а пропускна здатність низька — ви IOPS-забиті (рандом). Якщо пропускна здатність висока, а ops помірні — ви стримите потік.
Завдання 13: Створити dataset для бази даних і встановити розумні значення за замовчуванням
cr0x@server:~$ sudo zfs create tank/pg
cr0x@server:~$ sudo zfs set atime=off compression=lz4 recordsize=16K tank/pg
cr0x@server:~$ sudo zfs get -o name,property,value atime,compression,recordsize tank/pg
NAME PROPERTY VALUE
tank/pg atime off
tank/pg compression lz4
tank/pg recordsize 16K
Інтерпретація: Це не «єдине істинне налаштування для БД», але це розумний початок: менший recordsize для сторінок БД, відсутній atime-шторм, компресія увімкнена.
Завдання 14: Безпечно зробити snapshot і відкотити (коли ви збираєтесь робити сміливе)
cr0x@server:~$ sudo zfs snapshot tank/home@pre-upgrade
cr0x@server:~$ sudo zfs list -t snapshot tank/home
NAME USED AVAIL REFER MOUNTPOINT
tank/home@pre-upgrade 0 - 410G -
cr0x@server:~$ sudo zfs rollback tank/home@pre-upgrade
Інтерпретація: Знімок миттєвий. Відкат швидкий, але руйнівний для змін після знімка. На практиці: зробіть знімок, змініть, перевірте, потім збережіть або видаліть знімок залежно від результатів.
Завдання 15: Реплікація за допомогою send/receive (інкрементальна)
cr0x@server:~$ sudo zfs snapshot tank/home@daily-1
cr0x@server:~$ sudo zfs snapshot tank/home@daily-2
cr0x@server:~$ sudo zfs send -i tank/home@daily-1 tank/home@daily-2 | sudo zfs receive -u backup/home
cr0x@server:~$ sudo zfs list -t snapshot backup/home | tail -n 2
backup/home@daily-1 0 - 410G -
backup/home@daily-2 0 - 412G -
Інтерпретація: Інкрементальні стріми означають, що ви передаєте тільки зміни. Параметр -u тримає dataset не змонтованим, поки ви не готові. Операційно: ви можете тестувати відновлення, не чіпаючи продакшн-монтування.
6) Швидка діагностика (план дій)
Це послідовність «не метушіться». Мета — вирішити, чи ваша проблема в обладнанні, у розкладці пулу, у шляху синхронного запису, у пам’яті/кеші чи в вашому навантаженні.
Крок 1: Пул здоровий, або ви тестуєте деградовану систему?
cr0x@server:~$ sudo zpool status -x
all pools are healthy
Якщо не здоровий: припиніть тонке налаштування продуктивності. Замініть несправний пристрій, вирішіть проблеми з кабелями/контролерами, дайте resilver завершитися. Продуктивність під час resilver не є базовою — це режим надзвичайної ситуації.
Крок 2: Пул закінчується місцем або сильно фрагментований?
cr0x@server:~$ sudo zpool list -o name,size,alloc,free,cap,frag,health
NAME SIZE ALLOC FREE CAP FRAG HEALTH
tank 7.25T 6.70T 550G 92% 61% ONLINE
Інтерпретація: Пули вище ~80–85% є проблемними. Це не моральна провина; це реальність аллокатора. Якщо CAP високий і записи повільні — вільне місце перше, що потрібно вирішити.
Крок 3: Ви обмежені синхронними записами (fsync latency)?
cr0x@server:~$ sudo zpool iostat -v tank 1
Інтерпретація: Шукайте високу кількість операцій запису з низькою пропускною здатністю і високою латентністю в ширшій системі. Якщо ваш застосунок робить синхронні записи і у вас немає належного SLOG, ZFS чекатиме на стабільне зберігання. На HDD-пулах це може бути жорстоко.
Крок 4: ARC допомагає чи вам бракує RAM?
cr0x@server:~$ cat /proc/spl/kstat/zfs/arcstats | egrep "hits|misses|size|c_max" | head
Інтерпретація: Якщо робочий набір вміщується і hit rate хороший — читання мають бути швидкими. Якщо misses домінують і ваше навантаження читацьке — можливо потрібно більше RAM, або прийняти, що шаблон не кешується.
Крок 5: Один vdev є обмежувачем?
cr0x@server:~$ sudo zpool iostat -v tank 1
Інтерпретація: ZFS страйпить по vdev, тому продуктивність часто масштабується числом vdev. Один RAIDZ vdev — один блок продуктивності. Якщо ви побудували «один великий RAIDZ2» і чекали «багато IOPS», тут приходить реальність.
Крок 6: Знімки і churn викликають писаний ампліфікацію?
cr0x@server:~$ sudo zfs list -t snapshot -o name,used -s used | tail
Інтерпретація: Великий унікальний простір знімків плюс навантаження з перезаписом означає, що пул постійно алокує нові блоки. Це може виглядати як «випала рандомна продуктивність запису», коли реальна проблема — політика знімків vs churn rate.
7) Три корпоративні короткі історії (реалістичні, технічно точні)
Коротка історія A: Інцидент через хибне припущення (ZFS — не кеш RAID-контролера)
Компанія перемістила кластер PostgreSQL з SAN на пару локальних серверів зберігання. Старий SAN мав батарейно-захищений write cache; база користувалася низькою латентністю fsync() і ніколи про це не думала. Нові сервери зробили з HDD у RAIDZ2 і «немає потреби у фішках, бо ZFS розумне».
Міграційний вікенд пройшов добре, поки в понеділок вранці при поверненні клієнтського трафіку латентність commit зросла з «нормальної» до «застрягання аплікації». Моніторинг показував CPU майже вільний, диски не насичені по пропускній здатності, але база стояла. Класичний випадок: система була обмежена синхронними записами. Кожен commit вимагав стабільного зберігання, а стабільне зберігання на RAIDZ HDD без виділеного лог-пристрою означало чекати на ротаційну латентність і підрахунок паритету.
Хибне припущення було тонким: «ZFS має ZIL, тож це як write cache». ZIL — це механізм для коректності, а не магічний акселератор. Без SLOG-пристрою, призначеного для низьких латентностей синхронних записів (і з захистом від втрати живлення), ZFS просто робить безпечно, але повільно.
Виправлення не було героїчним. Вони додали правильні NVMe в якості дзеркального SLOG, перевірили, що пристрої мають реальний захист від втрати живлення, і відкотили одну ризиковану правку: хтось поставив sync=disabled під час тестування і подумав, що «все ок», бо нічого не падає. Після змін база повернулась до передбачуваної латентності комітів, а постмортем зробив простий висновок: «Коректність — це вимога продуктивності».
Коротка історія B: Оптимізація, що відбилась боком (recordsize і образи VM)
Інше середовище працювало приватний кластер віртуалізації з десятками завантажених VM на ZFS. Інженер прочитав гайди з налаштування і вирішив «більші блоки = швидше», встановивши recordsize=1M для VM dataset. Бенчмарк у тихому середовищі виглядав відмінно для послідовних читань. Усім сподобалось і справу закрили.
Через два місяці почали з’являтись скарги на латентність. Не постійно, а спорадично: VM «заморожувалася» на короткі проміжки під випадковим навантаженням запису. Пул не був повний, диски не падали, ARC здавався здоровим. Проблема була у шаблоні запису: образи VM роблять багато малих випадкових записів. З дуже великим recordsize малі перезаписи могли викликати поведінку read-modify-write і підвищувати write amplification. Додайте сюди знімки (бо їх тримали довше, ніж треба), і CoW створив ще більше нових алокацій.
Вони повернули dataset до більш розумного recordsize (зазвичай 16K або 64K залежно від гіпервізора і шаблонів гостя), обрізали ретеншн знімків, і спайки в основному зникли. Урок не в «ніколи не налаштовувати». Він у «ніколи не налаштовувати в одній площині». CoW + recordsize + ретеншн знімків — це тристороння задача, і продакшн завжди знаходить нестабільну орбіту.
Важливий пункт постмортему: будь-яка оптимізація продуктивності вимагала тесту, що відтворює навантаження (рандомні записи, churn знімків і конкуренція), і плану відкату. Ніхто не заборонив налаштовувати; просто перестали робити це як ритуал опівночі.
Коротка історія C: Нудна, але правильна практика, що врятувала день (scrubs + by-id + spares)
Найдорожча відсутність простою, яку я не мав — була попереджена календарним нагадуванням. Команда тримала ZFS дзеркала для критичного файлового сервісу. Нічого екзотичного: хороші диски, помірне навантаження, стабільне зростання. Практика була нудною: щомісячні scrubs, алерти на помилки контрольних сум і заміна дисків за постійними ID, а не за іменами /dev/sdX.
Одного місяця scrub відзвітував невелику, але ненульову кількість відремонтованих байтів на один член дзеркала. Ніяких користувацьких скарг, ніяких SMART-тріщин, нічого очевидного. Алерт все одно породив тикет, бо правило було просте: réparирані контрольні суми означають, що щось солгало. Вони переглянули логи, побачили переривчасті скидання лінку в певному відсіку, пересілили диск, замінили підозрілий кабель і планово замінили диск у робочий час.
Через два тижні інший диск у тому самому дзеркалі почав кидати жорсткі помилки читання. Якби та рання мовчазна корупція не була знайдена й усунена, вони могли б опинитися за день від втрати блоків, які не вдасться відновити. Натомість це був рутинний обмін без драм.
Нічого в цьому порятунку не було гламурного. Ніхто не «героїв» не робив 3-ї ночі. Система залишилася нудною, бо вони робили нудні речі: scrubs, алерти, що мали значення, і апаратну гігієну. У продакшн нудність — це фіча.
8) Поширені помилки (конкретні симптоми й виправлення)
Помилка 1: Побудувати один гігантський RAIDZ vdev і чекати високих IOPS
Симптом: Відмінна послідовна пропускна здатність, жахлива латентність рандомного I/O під навантаженням; VM чи БД відчувають «застряглість».
Чому: RAIDZ vdev поводиться як один IOPS-одиниця у багатьох шаблонах; паритетна робота і кількість дисків не множать рандомні IOPS чарівним чином.
Виправлення: Використовуйте дзеркала для IOPS-важких навантажень або кілька RAIDZ vdev (більше vdev = більше паралелізму). Якщо переробити неможливо, ізолюйте навантаження, зменшіть синхронний тиск і будьте реалістичні щодо IOPS.
Помилка 2: Встановити sync=disabled щоб «поліпшити продуктивність»
Симптом: Продуктивність відмінна; але після втрати живлення або крешу база або файлові системи VM пошкоджені або втрачені недавні транзакції.
Чому: Ви наказали ZFS брехати додаткам про надійність.
Виправлення: Встановіть sync=standard (за замовчуванням) і розв’яжіть реальну проблему: додайте правильний дзеркальний SLOG з захистом від втрати живлення, якщо вам потрібні низькі латентності синхронних записів.
Помилка 3: Невірний ashift при створенні пула
Симптом: Писання повільне без видимої причини; малі записи викликають великі пристроєві записи; витривалість SSD падає швидше, ніж очікувалось.
Чому: Невідповідність вирівнювання секторів спричиняє write amplification. Ви не можете змінити ashift після створення.
Виправлення: Пересоздайте пул правильно (часто ashift=12 або 13 залежно від пристроїв). Якщо не можете — живіть з податком.
Помилка 4: Дати пулу «гаряче» працювати (занадто заповнений)
Симптом: Усе з часом повільнішає; scrubs/resilvers займають довше; операції з метаданими відчуваються затриманими.
Чому: У аллокатора менше вибору; фрагментація і write amplification зростають.
Виправлення: Тримайте запас вільного простору. Додайте ємність (нові vdev), зменшіть ретеншн або перемістіть холодні дані. Розглядайте 80% як поріг планування, а не жорсткий закон.
Помилка 5: Накопичення знімків без усвідомлення churn
Симптом: «Ми видалили дані, але простір не повернувся», плюс дрейф продуктивності.
Чому: Знімки утримують старі блоки. Важкий churn + довга ретеншн знімків = тиск на простір і фрагментацію.
Виправлення: Аудит знімків, імплементація політик ретеншну по dataset і узгодження частоти знімків з цілями відновлення, а не з відчуттями.
Помилка 6: Змішувати повільні й швидкі пристрої так, щоб підсилити повільніший
Симптом: Сплески латентності; один диск показує високе завантаження, інші простають.
Чому: Дзеркала швидкі лише як повільніший член для багатьох операцій; гетерогенні vdev ускладнюють передбачуваність.
Виправлення: Підбирайте члени vdev під матч. Якщо потрібно змішувати — робіть це навмисно (наприклад, спеціальний vdev для метаданих) і ретельно моніторте.
Помилка 7: Обробляти SMR-диски як звичайні HDD
Симптом: Resilver і scrubs займають вічність; продуктивність запису падає під тривалим навантаженням.
Чому: Поведінка запису SMR може бути караюча для патернів відновлення ZFS.
Виправлення: Уникайте SMR для пулів ZFS, що потребують передбачуваного відновлення. Якщо ви застрягли — зменшіть навантаження під час resilver і перегляньте дизайн надмірності.
9) Контрольні списки / покроковий план
Чекліст дизайну (перед створенням пулу)
- Класифікуйте навантаження: переважно послідовне (бекап/медіа), переважно рандомне (VMs/БД), змішане (домашні каталоги), синхронно-важке (бази даних/NFS).
- Виберіть тип vdev за потребами IOPS: дзеркала для IOPS; RAIDZ для ємності/пропуску з меншими очікуваннями IOPS.
- Визначте ashift наперед: припускайте 4K+ сектори; перевірте, потім створюйте пул. Розглядайте це як незворотне.
- Плануйте запас: планування ємності, що тримає вас поза зоною 90%.
- Визначте політику знімків: частота і ретеншн по dataset, а не одне правило для всіх.
- Визначте стратегію sync: якщо у вас синхронно-важкі навантаження — плануйте SLOG (дзеркальний, PLP) або приймайте латентність.
План розгортання (перший тиждень у продакшн)
- Створіть datasets по навантаженнях (VMs, БД, home, backups), а не один моноліт.
- Встановіть базові властивості:
compression=lz4,atime=offде потрібно, recordsize під навантаження. - Реалізуйте моніторинг: здоров’я
zpool status, результати scrub, помилки контрольних сум, заповненість та тренди тривалості scrub. - Заплануйте scrubs у вікна низького трафіку, але не вважайте їх опціональними.
- Протестуйте відкат snapshot на некритичних даних, щоб команда мала м’язову пам’ять.
- Протестуйте
zfs send/receiveвідновлення, а не лише створення бекапу.
Чекліст змін (перед «оптимізацією»)
- Озвучте гіпотезу: який метрик покращиться і чому.
- Виміряйте базову лінію з продакшн-подібною конкуренцією й I/O-патернами.
- Змінюйте одну ручку за раз: recordsize, sync, спеціальний vdev тощо.
- Визначте критерії відкату і відрепетируйте кроки відкату.
- Спостерігайте щонайменше один бізнес-цикл, якщо навантаження циклічне.
10) FAQ
Q1: Чи безпечніше ZFS, ніж ext4/XFS?
Відповідь: ZFS надає наскрізні контрольні суми і самовідновлення за наявності надмірності. ext4/XFS зазвичай покладаються на нижчий рівень пристрою для цілісності. Якщо вам важлива детекція та ремонт мовчазної корупції, ZFS має реальну перевагу.
Q2: Чи потрібна ECC RAM для ZFS?
Відповідь: ECC настійно рекомендована для будь-якої серйозної системи зберігання, ZFS чи ні. ZFS добре виявляє корупцію на диску, але не може виправити погані дані, створені в RAM до того, як їх зачеексумовано. Багато хто працює без ECC; менше людей спить спокійно.
Q3: Чи завжди ZFS потребує «багато RAM»?
Відповідь: ZFS охоче використовує RAM для ARC, і більше RAM часто покращує читання. Але це не жорстка вимога для коректності. Питання в тому, чи ваше навантаження виграє від кешування. Якщо робочий набір не вміщується, RAM допомагає менше, і ext4/XFS можуть відчуватися подібно.
Q4: Чи варто вмикати deduplication?
Відповідь: Зазвичай ні для загального продакшну. Dedup витратний по RAM і може створювати різкі падіння продуктивності при недостачі ресурсів. Якщо у вас вузьке, виміряне застосування (наприклад, багато ідентичних образів VM) і ви протестували — можливо. Інакше спочатку використовуйте компресію.
Q5: У чому різниця між ZIL і SLOG?
Відповідь: ZIL — це журнал намірів на диску, що використовується для безпечної обробки синхронних записів. SLOG — це окремий пристрій, куди ZFS може помістити цей журнал, щоб прискорити синхронні записи. Без SLOG ZIL живе на основних пристроях пулу.
Q6: Коли sync=disabled припустимо?
Відповідь: Майже ніколи для чогось, що вам шкода втратити. Може бути припустимо для тимчасових scratch-даних або деяких pipeline-ів інгесту, що вже толерують втрату. Якщо ви не впевнені — вважайте це «небезпечним».
Q7: Чи заміняють знімки резервні копії?
Відповідь: Ні. Знімки допомагають швидко відновитися від логічних помилок на тій самій системі. Резервні копії захищають від втрати пулу, втрати сайту і помилок адміністратора, що видаляють і дані, і знімки. Використовуйте знімки як шар, а не як заміну.
Q8: Чому мій пул сповільнюється при заповненні?
Відповідь: Коли вільного місця стає менше, ZFS має менше суміжних регіонів для алокацій, що може підвищити фрагментацію і мета-роботу. Також CoW означає постійний пошук нових місць для запису. Тримайте запас і плануйте розширення ємності.
Q9: ext4/XFS теж мають контрольні суми, правда?
Відповідь: Вони мають контрольні суми для деяких метаданих (журнали тощо) залежно від можливостей. ZFS контролює дані й метадані наскрізь і валідує при читанні. Це інший рівень покриття.
Q10: Якщо ZFS таке добре, чому його не використовують скрізь?
Відповідь: Бо компроміси реальні: пам’ятний слід, поверхня налаштувань, поведінка CoW і потреба в експертності операційної команди. Також деякі середовища вже отримують вигоди іншим чином (фічі SAN, гарантії хмарного зберігання), роблячи ext4/XFS простішим і безпечнішим вибором.
Висновок
ZFS — це вибір, коли ви хочете, щоб шар зберігання був «дорослим»: воно верифікує те, що читає, може ремонтувати знайдене, робить знімки рутиною і дає чисті примітиви для реплікації. На практиці воно змінює типи відмов, які ви бачите: менше загадкової корупції, більше чесних обмежень продуктивності і більше моментів «ми можемо відкотитися».
ext4 і XFS ще виграють багато випадків. Вони виграють, коли вам потрібна простота, коли історія цілісності вирішується інакше, коли ваша команда хоче менше ручок і коли передбачувана поведінка запису на місці важливіша за знімки й наскрізні контрольні суми. Кращий вибір — не той, що має найбільше фіч; це той, що робить вашу продакшн-систему нудною у тих специфічних способах, які потрібні вашому бізнесу.