Сховище медіафайлів — це місце, куди хороші файлові системи іноді тихо «вмирають». Ви створюєте гарний пул, копіюєте кілька терабайт відео, додаєте другого клієнта, і раптом «вчора працювало» стає найпоширенішою фразою у вас вдома або в офісі.
ZFS може зробити медіанавантаження нудними — у найкращому сенсі — якщо перестати ставитися до нього як до універсальної файлової системи і почати налаштовувати під те, чим медіа фактично є: великі послідовні читання, великі послідовні записи та метадані, що вибухають зі зростанням бібліотеки.
Чого насправді потребують медіавантаження (і чого не потребують)
Почнемо з очевидного: більшість «медіа-серверів» не обмежені IOPS. Зазвичай вони обмежені пропускною здатністю або піддаються стрибкам латентності через метадані та дрібні випадкові читання. Типовий фільм великий і читається в основному послідовно. Навіть кілька одночасних стрімів часто означають послідовні читання з різних зсувів.
Що ламає систему — це те, що оточує медіа:
- Сканування бібліотеки: багато дрібних читань і запитів метаданих; скан Plex/Jellyfin/Emby може виглядати як навантаження дрібних файлів, приховане під медіа-навантаженням.
- Мініатюри, прев’ю, субтитри: дрібні файли, що спричиняють випадковий I/O і інтенсивну роботу з метаданими.
- Завантаження/транскодинг: послідовні записи плюс велике навантаження на CPU, іноді в тих же dataset (не робіть так).
- Резервні копії та реплікація: тривалі послідовні читання, що конкурують зі стрімінгом.
Отже задача: оптимізувати шлях для великих файлів, не саботуючи шлях для метаданих і дрібних файлів. ZFS дає вам регулятори для цього на рівні dataset. Користуйтеся ними.
Оціночна базова думка: якщо ви зберігаєте великі, переважно читаємі медіафайли, вам слід думати про recordsize, compression, sync, atime і special vdev / локалізацію метаданих перед тим, як марнувати час на суперечки RAIDZ проти mirror на Reddit.
Перший короткий жарт (1/2): Налаштування сховища схоже на дієту: найшвидший прогрес приходить, коли ви припиняєте очевидні шкідливі звички, а не купуєте дорожчу вагу.
Великі блоки: як фактично поводиться recordsize
Recordsize — це не «розмір блоку» і не гарантія
ZFS зберігає дані файлів у змінних блоках до максимального розміру. Для файлових систем (dataset типу filesystem) цей максимум — recordsize. За замовчуванням часто 128K. Для медіа це зазвичай обережна установка.
Ключова поведінка: ZFS використовує менші блоки, коли це необхідно. Якщо ви встановите recordsize=1M, ви не змусите кожну I/O-операцію бути 1M. Малі файли і «хвости» залишаються меншими. Виправлення випадкових ділянок також може породжувати менші блоки через copy-on-write.
Чому великі блоки допомагають медіа
Відтворення медіа любить довгі послідовні читання. Великі блоки можуть дати:
- Менше I/O-операцій для тієї ж пропускної здатності (нижчі накладні витрати на операцію).
- Кращі можливості компресії (більше даних на одне рішення про стиснення).
- Менше непрямих блоків для великих файлів (менше метаданих, за якими треба бігати).
Але великі блоки не безкоштовні:
- Гірше роздування читань при дрібних випадкових запитах (читати 1M блок заради 4K — нерозумно).
- Може бути болючіше при перезаписах, якщо ви редагуєте на місці (рідко для фіналізованих медіафайлів; поширено для образів VM — інша історія).
- Більший тиск на RAM у деяких схемах кешування (ARC тримає великі буфери; не завжди проблема, але не ігноруйте).
Що встановлювати для медіа
Для фіналізованих медіафайлів (фільми, епізоди, архіви музики) встановлюйте recordsize=1M на dataset, що їх зберігає. Якщо ваша версія OpenZFS це підтримує і навантаження вкрай послідовне, recordsize=2M також може працювати, але 1M — практичний оптимум: великий приріст при мінімальних несподіванках.
Не встановлюйте один глобальний recordsize для всього. Ваш каталог завантажень, мініатюри та метадані додатків не повинні потрапляти в «світ великих блоків». Тримайте їх у окремих dataset з відповідним recordsize (часто дефолт 128K або навіть менше для дуже метаданих-насичених навантажень).
А як щодо volblocksize?
Якщо ви експортуєте iSCSI LUN або використовуєте zvol-backed сховище, ця стаття частково для вас. volblocksize фіксується при створенні zvol і поводиться інакше. Медіа-зберігання зазвичай файлове (SMB/NFS), тож зосередьтеся на recordsize.
Велика компресія: коли вона працює, а коли вводить в оману
Компресія — це не лише економія місця
На сучасних CPU компресія часто підвищує пропускну здатність, оскільки міняє CPU-цикли на менше читань/записів диска. Для медіа це звучить як зайве, бо «відео вже стиснено». Це правда, але не повна.
Навіть у медіабібліотеці ви знайдете:
- Текстові супроводи (субтитри, NFO-метадані): добре стискаються.
- Обкладинки/арт: іноді вже стиснені, іноді ні (PNG іноді ще піддається стисненню; сирі зображення стискаються сильно).
- Артефакти завантажень (логи, тимчасові файли): високо стискаються.
- Аудіоформати: FLAC вже стиснутий, WAV — ні.
Отже компресія «перемагає» за замовчуванням частіше, ніж думають. І коли вона не значно зменшує розмір, вона все одно може зменшити I/O для метаданих і супровідних файлів.
Вибирайте алгоритм доросло
Мої звичні вибори для медіа-dataset:
compression=lz4— для постійної компресії з невеликим ризиком і низькою затримкою.compression=zstd— для dataset з великою кількістю метаданих, документів або змішаного контенту. Починайте зzstd-3доzstd-6. Вищі рівні можуть бути прийнятні, але тестуйте запас CPU.
Для чисто фіналізованих відеофайлів компресія не зменшить фільм драматично. Але зазвичай і не зашкодить. Єдина справжня заборона — вибрати важкий рівень компресії на машині, яка вже зайнята транскодуванням.
Другий короткий жарт (2/2): Якщо ви вмикаєте максимальну компресію на сервері, який вже транскодує 4K, ви фактично винайшли обігрівач із почуттями.
Що може зламати компресія
Компресія рідко ламає коректність; ZFS тут надійний. Що ламає — це ваш бюджет латентності, якщо ви перетворюєте CPU-легку машину на CPU-навантажену. Симптоми виглядають як «диск повільний», бо все стоїть у черзі за CPU.
Також: коефіцієнти стиснення можуть вводити в оману. Dataset може показувати «посередній» загальний коефіцієнт, але при цьому зберегти багато I/O для несжатих частин (супровідні файли), що викликають стрибки латентності.
Розмітка dataset для медіа: тримайте все нудним і швидким
Розділяйте dataset за поведінкою I/O
Не кладіть усе під одним dataset з назвою tank/media і не вважайте цим справу завершеною. Вам потрібні різні властивості для різної поведінки. Практична структура:
tank/media— фіналізовані медіафайли (великі послідовні читання).recordsize=1M,compression=lz4(або помірний zstd),atime=off.tank/downloads— активні записи, часткові файли, розпаковування. Залиштеrecordsizeдефолтним або 128K; компресія тут допомагає багато.tank/app— стан додатків (метадані Plex/Jellyfin). Часто виграє від дефолтного recordsize; розгляньте спеціальний vdev, якщо він у вас є.tank/backups— цілі реплікації; налаштуйте окремо під send/receive патерни.
atime: просто вимкніть його для медіа
atime оновлює час доступу до файлів. Для медіа це зайві записи метаданих без користі. Встановіть atime=off на медіа-dataset і на все, що читається часто. Єдиний випадок, коли хочеться atime=on, — якщо додаток використовує його в логіці (рідко зараз).
sync, лог-пристрої та реалії медіа
Більшість інгестів медіа за своєю природою асинхронні: завантаження, копіювання файлів, ріпи. Якщо ви подаєте медіа через SMB/NFS, поведінка клієнта і налаштування протоколу визначають, скільки синхронних записів буде.
Рекомендації:
- Не встановлюйте
sync=disabledбездумно. Це робить бенчмарки красивими й інцидентні звіти сумними. - Якщо у вас є SSD SLOG і навантаження реально робить sync-запити (бази даних, VM, жорсткий NFS),
sync=standardплюс хороший SLOG можуть допомогти. Для чисто медіа-читання це часто неважливо.
Special vdev: недооцінене оновлення для медіа
Великі медіафайли послідовні, але метадані для великої бібліотеки — ні. Special vdev (швидкі SSD, виділені під метадані й малі блоки) може зробити перегляд бібліотеки і скани чутливими без переміщення терабайтів на флеш.
Правила взаємодії:
- Ррактуйте special vdev як критичний. Якщо він помре і ви не зеркалили його, пул може бути знищено.
- Налаштуйте
special_small_blocksобережно, якщо хочете, щоб малі файли також лежали на special, а не лише метадані.
Ashifts, розміри секторів і чому ваш пул назавжди
ashift встановлюється при створенні vdev і важко змінюється. Якщо ви використовуєте диски з 4K секторами (більшість), виберіть ashift=12 (або вище, якщо у вас дійсно 8K). Неправильна установка не завжди показує «повільно»; частіше — «якийсь дивний приріст повільності» плюс додаткове write amplification.
Це одне з тих налаштувань «заплати зараз або плати вічно».
Цитата про надійність (парафразована ідея)
Парафразована ідея (Werner Vogels): Все ламається, постійно — тож проектуйте системи, які очікують відмов і продовжують працювати.
Цікаві факти та історичний контекст (бо це важливо)
- ZFS народився в Sun Microsystems як «файлова система з пулом зберігання», що об’єднала управління томами та семантику файлової системи в одну модель адміністрування.
- Copy-on-write — це не фігня; воно дозволило консистентні снапшоти без «заморожування» файлової системи, саме тому робочі процеси реплікації такі зручні.
- Енд-ту-енд контрольні суми — фундамент: ZFS перевіряє цілісність даних від диска до шляху читання в додатку, а не лише «RAID каже, що все добре».
- ARC — це не «просто кеш»; це адаптивний кеш в пам’яті, який може зберігати і дані, і метадані та суттєво впливає на відчутну продуктивність.
- LZ4 став дефолтом у багатьох дистрибуціях тому, що він достатньо швидкий, щоб бути фактично «безкоштовним» на сучасних CPU для загальних навантажень.
- За замовчуванням recordsize були обережними, бо файлові системи загального призначення мають поводитися нормально для змішаних навантажень, а не тому, що 128K — магічно правильне для відео.
- RAIDZ існує частково, щоб зменшити penalty при записі паритету у порівнянні з класичним RAID5 в певних патернах, але має свої компроміси для випадкового I/O.
- Функція special vdev відносно нова у порівнянні з класичним ZFS; вона змінила економіку прискорення навантажень, насичених метаданими.
Практичні завдання: команди, виводи та рішення (12+)
Кожне завдання нижче містить: команду, реалістичний вивід, що це значить, і яке рішення з цього випливає. Припущення: Linux з інструментами OpenZFS, пул називається tank, та dataset як описано раніше.
Завдання 1: Підтвердити стан пулу і очевидні «червоні прапорці»
cr0x@server:~$ zpool status -v tank
pool: tank
state: ONLINE
status: Some supported features are not enabled on the pool.
action: Upgrade the pool to enable all features.
scan: scrub repaired 0B in 06:12:31 with 0 errors on Sun Dec 15 03:10:12 2025
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
raidz2-0 ONLINE 0 0 0
ata-WDC_WD140EDFZ-... ONLINE 0 0 0
ata-WDC_WD140EDFZ-... ONLINE 0 0 0
ata-WDC_WD140EDFZ-... ONLINE 0 0 0
ata-WDC_WD140EDFZ-... ONLINE 0 0 0
ata-WDC_WD140EDFZ-... ONLINE 0 0 0
ata-WDC_WD140EDFZ-... ONLINE 0 0 0
errors: No known data errors
Значення: Пул ONLINE; scrub чистий; помилок читання/запису/контрольної суми немає. «Some supported features not enabled» — інформаційне повідомлення.
Рішення: Якщо стан не ONLINE або ви бачите CKSUM помилки, припиніть тюнінг і почніть з виправлення обладнання/кабелів. Оптимізація продуктивності на хворому пулі — театральне представлення.
Завдання 2: Перевірити властивості dataset, що важливі для медіа
cr0x@server:~$ zfs get -o name,property,value -s local,default recordsize,compression,atime,sync tank/media
NAME PROPERTY VALUE
tank/media recordsize 128K
tank/media compression off
tank/media atime on
tank/media sync standard
Значення: Dataset має загальні значення: recordsize 128K, компресія відключена, atime увімкнено.
Рішення: Для фіналізованих медіа змініть на recordsize=1M, compression=lz4, atime=off. sync лишіть, якщо ви не розумієте поведінку sync-запитів клієнтів.
Завдання 3: Застосувати медіа-дружні налаштування (безпечно, по dataset)
cr0x@server:~$ sudo zfs set recordsize=1M compression=lz4 atime=off tank/media
Значення: Нові файли будуть використовувати до 1M записи; існуючі блоки не переписуються автоматично.
Рішення: Якщо ви хочете, щоб існуючі файли отримали переваги, сплануйте перепис (Завдання 8).
Завдання 4: Перевірити, чи застосувалися налаштування
cr0x@server:~$ zfs get -o name,property,value recordsize,compression,atime tank/media
NAME PROPERTY VALUE
tank/media recordsize 1M
tank/media compression lz4
tank/media atime off
Значення: Dataset налаштовано для великих послідовних читань з низько-накладною компресією.
Рішення: Перейдіть до валідації: чи бачимо ми насправді більші блоки і кращу пропускну здатність?
Завдання 5: Спостерігати реальні I/O під час відтворення або копіювання
cr0x@server:~$ iostat -xm 2 3
Linux 6.8.0 (server) 12/25/2025 _x86_64_ (16 CPU)
Device r/s rkB/s rrqm/s %rrqm r_await rareq-sz w/s wkB/s w_await wareq-sz aqu-sz %util
sda 18.0 2400.0 0.0 0.0 8.1 133.3 0.5 64.0 2.0 128.0 0.2 14.0
sdb 17.5 2320.0 0.0 0.0 7.9 132.6 0.6 80.0 2.1 133.3 0.2 13.5
md0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
Значення: Читання йдуть із середнім розміром запиту близько ~128K на рівні блочного пристрою. Це не обов’язково «погано», але вказує, що ZFS може все ще віддавати менші I/O (або навантаження не чисто послідовне).
Рішення: Перевірте статистику ZFS (ARC, prefetch, розміри блоків) і чи файли були записані до зміни recordsize.
Завдання 6: Перевірити ARC і меморіальний тиск
cr0x@server:~$ arcstat 2 3
time read miss miss% dmis dm% pmis pm% mmis mm% arcsz c
12:01:10 520 40 7 8 20 30 75 2 5 48.2G 52.0G
12:01:12 610 55 9 10 18 42 76 3 5 48.3G 52.0G
12:01:14 590 60 10 12 20 45 75 3 5 48.3G 52.0G
Значення: Розмір ARC ~48G з ціллю c ~52G. Рівень промахів низький; є промахи prefetch (стрімінг медіа їх генерує).
Рішення: Якщо ARC маленький або постійно зменшується, перевірте обмеження пам’яті та інші сервіси. Медійні сервери, які одночасно запускають контейнери і транскодування, можуть обдурити ARC і звинуватити диски.
Завдання 7: Підтвердити фактичні розміри блоків на диску для медіафайлу
cr0x@server:~$ zdb -bbbb tank/media "movie.mkv" | head -n 12
Indirect blocks:
0 L0 512K 1/1/200 16384L/32768P F=1 B=1000/1000
1 L0 512K 1/1/200 16384L/32768P F=1 B=1000/1000
2 L0 512K 1/1/200 16384L/32768P F=1 B=1000/1000
3 L0 512K 1/1/200 16384L/32768P F=1 B=1000/1000
Значення: Цей файл використовує 512K блоки, а не 1M. Це все ще більше за 128K і може відображати, як він був записаний (або попередні налаштування).
Рішення: Якщо вам потрібні 1M блоки, перепишіть або перекопіюйте файл після встановлення recordsize=1M (Завдання 8). Не ганяйтесь за примарами: recordsize — максимум, а не гарантія.
Завдання 8: Переписати існуючі медіа, щоб вони успадкували новий recordsize/compression
cr0x@server:~$ rsync -aH --inplace --no-whole-file /tank/media/ /tank/media_rewrite/
sending incremental file list
movie.mkv
episode01.mkv
episode02.mkv
sent 119,845,232,110 bytes received 1,842 bytes 112,394,820.31 bytes/sec
total size is 119,842,001,002 speedup is 1.00
Значення: Ви копіюєте файли у новий dataset (або директорію), щоб вони були розкладені з новими властивостями. (Використовуйте окремий dataset як tank/media_new для чистої семантики.)
Рішення: Після перевірки поміняйте точки монтування або перейменуйте dataset. Уникайте перепису «на місці», якщо не впевнені та не маєте бекапів; бібліотеки медіа великі, помилки дорогі.
Завдання 9: Перевірити ефективність компресії на dataset
cr0x@server:~$ zfs get -o name,property,value compressratio,compression tank/media
NAME PROPERTY VALUE
tank/media compression lz4
tank/media compressratio 1.08x
Значення: Загальна економія ~8%. Для «переважно відео» dataset це правдоподібно: супровідні файли та метадані стискаються; відео — майже ні.
Рішення: Тримайте компресію увімкненою. Ви отримуєте економію з мінімальним навантаженням на CPU. Якщо CPU обмежений, залишайтеся на lz4 замість важкого zstd.
Завдання 10: Виміряти реальну пропускну здатність тестом читання (і інтерпретувати уважно)
cr0x@server:~$ dd if=/tank/media/movie.mkv of=/dev/null bs=8M status=progress
40097546240 bytes (40 GB, 37 GiB) copied, 38 s, 1.1 GB/s
48273149952 bytes (48 GB, 45 GiB) copied, 46 s, 1.0 GB/s
50331648000 bytes (50 GB, 47 GiB) copied, 49 s, 1.0 GB/s
Значення: Ви читаєте приблизно 1.0 GB/s. Це може бути ARC (кеш) або диски, залежно від повторення і стану системи.
Рішення: Повторити після очищення кешів не просто з ZFS. Натомість тестуйте з кількома великими файлами і дивіться zpool iostat, щоб підтвердити фізичні читання (Завдання 11).
Завдання 11: Спостерігати пропускну здатність vdev і черги
cr0x@server:~$ zpool iostat -v tank 2 3
capacity operations bandwidth
pool alloc free read write read write
---------- ----- ----- ----- ----- ----- -----
tank 48.2T 26.1T 320 12 1.02G 45.3M
raidz2-0 48.2T 26.1T 320 12 1.02G 45.3M
sda - - 55 2 174M 7.5M
sdb - - 54 2 171M 7.4M
sdc - - 53 2 170M 7.6M
sdd - - 54 2 171M 7.6M
sde - - 52 2 168M 7.6M
sdf - - 52 2 167M 7.6M
---------- ----- ----- ----- ----- ----- -----
Значення: Читання розподілені по дисках, агрегатно ~1.02 GB/s. Це фізичне читання. Добре.
Рішення: Якщо пропускна здатність низька, але клієнти буферизують — перевірте мережу та CPU. Якщо диски показують високу кількість операцій, але низьку пропускну здатність — ви робите дрібні випадкові I/O і слід зосередитися на метаданих/special vdev/налаштуванні app dataset.
Завдання 12: З’ясувати, чи метадані — справжній вузький горлечко (повільні обходи директорій)
cr0x@server:~$ sudo zpool iostat -r tank 1 5
read IOs
pool raidz2-0 sda sdb sdc sdd sde sdf
---------- ------- ---- ---- ---- ---- ---- ----
tank 900 150 148 151 149 151 151
tank 1200 200 198 201 199 201 201
tank 1100 184 182 185 183 184 182
Значення: Високі IOPS без згадки про широку пропускну здатність вказують на багато дрібних читань (метадані, мініатюри, дрібні файли).
Рішення: Розгляньте special vdev або перенесення метаданих додатків на SSD-пул/окремий dataset. Також перевірте primarycache і розмір ARC.
Завдання 13: Перевірити патологічну фрагментацію і тиск вільного простору
cr0x@server:~$ zpool list -o name,size,alloc,free,frag,cap,health tank
NAME SIZE ALLOC FREE FRAG CAP HEALTH
tank 74.3T 48.2T 26.1T 38% 64% ONLINE
Значення: 38% фрагментації і 64% використання — не тривожно. Фрагментація важливіша при високому заповненні та випадкових записах.
Рішення: Якщо ви вище ~80% і фраг росте, очікуйте обриви продуктивності під час записів і resilver. Плануйте розширення до того, як пул стане «запакованим чемоданом».
Завдання 14: Перевірити вирівнювання секторів (ashift) на vdev
cr0x@server:~$ zdb -C tank | grep -E "ashift|vdev_tree" -n | head
56: vdev_tree:
72: ashift: 12
Значення: ashift=12 вказує на 4K сектори. Добре для сучасних дисків.
Рішення: Якщо ashift = 9 на дисках 4K, продуктивність і витривалість страждають. Виправлення вимагає перебудови vdev/pool; вирішуйте рано, а не після 50TB.
Завдання 15: Перевірити, чи sync-записи несподівано вбивають інгест
cr0x@server:~$ zpool iostat -w tank 2 3
capacity operations bandwidth
pool alloc free read write read write
---------- ----- ----- ----- ----- ----- -----
tank 48.2T 26.1T 10 220 4.2M 38.0M
---------- ----- ----- ----- ----- ----- -----
Значення: Багато записів, але скромна пропускна здатність може вказувати на дрібні sync-записи або інтенсивну мета-роботу.
Рішення: Перевірте навантаження (SMB durable handles, NFS sync, поведінка додатка). Якщо у вас справжні sync-запити і ви дбаєте про латентність інгесту, розгляньте дзеркальний SLOG на SSD з захистом від втрати живлення. Якщо ви не впевнені — не торкайтеся sync=disabled.
Завдання 16: Підтвердити, що снапшоти не нівечать простір мовчки
cr0x@server:~$ zfs list -o name,used,usedbysnapshots,refer,avail -r tank/media | head
NAME USED USEDBYSNAPSHOTS REFER AVAIL
tank/media 22.1T 3.4T 18.7T 26.1T
Значення: 3.4T утримується снапшотами. Це не «погано», але пояснює, чому видалення не повертає простір.
Рішення: Якщо тиск простору зростає, впровадьте політику збереження снапшотів (тримайте кілька, обрізайте решту), особливо для dataset з великим числом змін як downloads і метадані додатків.
Швидкий план діагностики: знайдіть вузьке місце за хвилини
Це чек-лист, який я реально використовую, коли хтось каже «стрімінг буферизується» або «копіювання повільне». Мета — уникнути годин налаштувань, коли проблема — у кабелі, повному пулі або одному проблемному диску.
Перше: чи пул здоровий і не відновлюється?
- Запустіть
zpool status -v. Якщо бачите DEGRADED, resilvering або помилки контрольної суми — продуктивність другорядна. Виправляйте стан спочатку. - Перевірте, чи scrub/resilver працює і не насичує I/O.
Друге: що це — диски, CPU чи мережа?
- Диски:
zpool iostat -v 2іiostat -xm 2. Шукайте один пристрій з високим await/%util відносно інших. - CPU:
topабоmpstat -P ALL 2. Шукайте одно-потоковий вузький елемент або повністю завантажений CPU (транскодування + компресія + контрольні суми складаються). - Мережа:
ip -s linkі лічильники комутатора. Шукайте помилки/втрати або лінк 1Gb там, де ви очікували 10Gb.
Третє: чи випадково робите дрібні випадкові I/O?
- Високі IOPS і низька пропускна здатність у
zpool iostat— маркер. - Генерація метаданих і мініатюр: перемістіть на SSD/special vdev або ізолюйте dataset.
- Перевірте
atimeі вимкніть його для читаючих dataset.
Четверте: чи пул занадто повний або фрагментований?
zpool listдля перевірки заповнення і фрагментації.- Якщо ви вище ~80–85% використання, не очікуйте чудес. Плануйте розширення, видалення з урахуванням снапшотів або додавання vdev.
П’яте: чи ваше налаштування відповідає dataset?
zfs get recordsize,compression,atimeдля проблемного dataset.- Якщо ви недавно змінили recordsize, перевірте нові файли, не старі. Старі блоки лишаються.
Три корпоративні міні-історії з «полів»
1) Інцидент через неправильне припущення: «Це просто послідовні читання, RAIDZ підходить»
Команда виробництва медіа побудувала спільний NAS для монтажерів. Навантаження «виглядало як медіа», тому вони спроектували його для пропускної здатності: великий HDD-пул, RAIDZ2, багато шпинделів, широкий мережевий канал. Усі були щасливі під час першого копіювання і першого тижня відтворення.
Але бібліотека виросла. Менеджер активів почав генерувати проксі, мініатюри, preview хвилі та індексні метадані. Редактори почали шукати по таймлайнах і перемотувати файли. Патерн I/O перетворився на неприємну суміш: послідовні читання для відтворення плюс випадкові читання для мініатюр та випадкові записи для оновлення метаданих.
Неправильне припущення було в тому, що «медіа = послідовне». Медіа плюс інструменти = змішане навантаження. RAIDZ2 не був «поганим», але пул не мав швидкого місця для метаданих, і стрибки латентності зіпсували UI. Це виглядало як проблема мережі, бо клієнти буферизували і SMB-сесії залишалися підключеними. Звісно, всі звинуватили комутатор.
Виправлення було нудним: розділити dataset, перенести метадані додатків на SSD, додати зеркалений special vdev і припинити бити той самий dataset фіналізованими медіа й постійно змінними метаданими. Налаштування recordsize допомогло, але справжній виграш був у тому, щоб дати метаданим швидку доріжку.
Після цього продуктивність стала передбачуваною. Не «максимальний бенчмарк» — справжня передбачуваність. Така, що зупиняє Slack-повідомлення.
2) Оптимізація, що обернулася проти: вимкнули sync, щоб «прискорити інгест»
Корпоративна група комунікацій завантажувала сотні ГБ на день з камер. Хтось запустив швидкий бенчмарк, побачив, що записи повільні, і знайшов відомий тумблер: sync=disabled. Переключили — інгест подвоївся. Герой з’явився.
Через тижні стався відключення живлення. UPS зробив, що міг, але хост втратив живлення під час інгесту. Після перезавантаження пул імпортувався нормально. Файлова система змонтувалася. Але найсвіжіші файли були пошкоджені тонко — деякі кліпи грали з артефактами, у деяких відсутні кінцеві сегменти, у деяких додаток показав помилку контрольної суми.
Немає одного очевидного «ZFS зламався» повідомлення. Ось у чому пастка. Вимкнення sync не ламає пул; воно ламає ваші угоди. Додатки, які покладалися на fsync() як «на стабільне збереження», були обмануті. Вони робили те, що мали — сховище цього не гарантувало.
Відновлення зайняло час: повторний інгест з джерела, впровадження захисту від втрати живлення і повернення sync=standard. Додали малий зеркалений SLOG на SSD з гарантією при відключенні живлення, що повернуло більшість продуктивності інгесту, зберігши семантику.
Оптимізація, яка базується на брехні додаткам — це не оптимізація. Це борг з відсотками.
3) Нудна, але правильна практика, яка врятувала день: щомісячні scrub і алерти
Внутрішній стрімінговий архів працював на великому ZFS-пулі. Нічого особливого: пристойні контролери, дзеркальний boot, RAIDZ2 для даних і зеркалений special vdev для метаданих. Команда мала одну релігійну практику: скраби за розкладом і алерти, які реально викликали когось, хто хвилюється.
Одного місяця scrub виявив кілька помилок контрольної суми на одному диску. Система відновила дані за допомогою надлишковості, але алерт спрацював. Диск не виглядав явно мертвим; SMART був «в порядку», бо SMART любить оптимізм.
Вони замінили диск у робочий час, спокійно, до того як це переросло в багатодискову відмову під час resilver. Через тиждень другий диск з тієї ж партії почав показувати помилки читання. Якби перший не був замінений вчасно, це могло б стати поганим днем.
Ніяких героїчних налаштувань. Ніяких секретних sysctl. Просто scrub, алерти і готовність замінити диск, що попередив про себе раніше. Надійність — це відмова від здивування.
Поширені помилки: симптом → корінь проблеми → виправлення
1) «Під час сканування бібліотеки стрімінг буферизується»
Симптом: Відтворення паузиться або UI затормажується під час сканів, генерації мініатюр чи оновлення метаданих.
Корінь проблеми: Навантаження метаданих/дрібних файлів конкурує з потоковими читаннями на тих самих vdev; ARC трясається від дрібних випадкових читань.
Виправлення: Розділіть dataset; перемістіть метадані додатків на SSD або додайте зеркалений special vdev; тримайте медіафайли в dataset з великими block’ами; розгляньте обмеження одночасності сканів у додатку.
2) «Я поставив recordsize=1M, але нічого не прискорилось»
Симптом: Ніяких вимірюваних змін після тюнінгу.
Корінь проблеми: Існуючі файли зберігають стару розкладку блоків; recordsize впливає насамперед на нові записи.
Виправлення: Перепишіть/перекопіюйте файли у dataset з новими налаштуваннями (rsync або zfs send/recv). Перевірте з zdb приклад файлу.
3) «Записи повільні і iostat показує дрібні записи з високою латентністю»
Симптом: Інгест обмежений на десятки MB/s; спостерігаються сплески латентності.
Корінь проблеми: Sync-запити від SMB/NFS/додатка, немає SLOG, або повільні диски змушені часто комітити.
Виправлення: Тримайте sync=standard. Якщо sync-запити реальні й важливі, додайте дзеркальний, захищений від втрати живлення SLOG; інакше налаштуйте клієнт/додаток, які змушують sync.
4) «Пул став повільнішим з часом, хоча диски здорові»
Симптом: Поступове падіння продуктивності, особливо при записах і під час обслуговування.
Корінь проблеми: Високе заповнення пулу і фрагментація; багато churn під снапшотами; RAIDZ write amplification погіршується при високій заповненості.
Виправлення: Тримайте пул під ~80–85% використання; чистіть снапшоти; додавайте vdev до того, як стане критично; ізолюйте churn’ові dataset як downloads.
5) «SMB-перегляд повільний, але стрімінг в порядку»
Симптом: Перерахунок директорій і відкриття папок займає секунди; відтворення після початку — ок.
Корінь проблеми: Латентність метаданих. Обхід директорій і виклики stat — це дрібні випадкові читання; можливо, також оновлення atime.
Виправлення: atime=off; special vdev для метаданих; переконайтеся, що ARC має достатньо RAM; не кладіть стан додатків на ті ж спінні диски, що й масивні медіа, якщо можна уникнути.
6) «Під час scrub з’являються помилки контрольних сум»
Симптом: zpool status показує відновлені байти або зростаючу кількість CKSUM.
Корінь проблеми: Несправний диск, поганий кабель/бэкплейн, проблеми контролера або (рідше) нестабільна пам’ять.
Виправлення: Трактуйте як інцидент обладнання. Пересадіть/замініть кабелі, перемістіть диски в інші корзини, запустіть довгі SMART-тести, замініть підозрілі диски. Не «тюньте» помилки контрольних сум.
Чек-листи / покроковий план
План A: Новий медіа-пул, зроблений правильно
- Оберіть топологію vdev, враховуючи домен відмов і час відновлення: RAIDZ2 для великих HDD-пулів — розумний дефолт; дзеркала якщо потрібен кращий випадковий I/O і швидші resilver.
- Встановіть ashift правильно при створенні (зазвичай 12 для сучасних 4K HDD).
- Створіть dataset за робочим навантаженням: media, downloads, app metadata, backups.
- Встановіть властивості dataset:
- Media:
recordsize=1M,compression=lz4,atime=off. - Downloads: компресія увімкнена; recordsize дефолтний; завжди розглядайте
sync=standard. - App: дефолтний recordsize; розгляньте SSD/special vdev.
- Media:
- Впровадьте снапшоти з політикою збереження (особливо для app і downloads). Тримайте політику простою, щоб вона реально виконувалась.
- Scrub за розкладом + алерти. Якщо ви не налаштували алерти — ви не скрабите; ви ведете журнал жаль.
- Тестуйте реальними робочими навантаженнями: одночасні стріми + скан + інгест. Синтетичні тести покажуть лише синтетичне життя.
План B: Існуючий пул з загальними налаштуваннями
- Підтвердьте здоров’я:
zpool status. Виправте помилки спочатку. - Розділіть dataset: створіть
tank/media,tank/app,tank/downloads, якщо ще не маєте. - Застосуйте властивості для медіа лише до
tank/media. - Перепишіть або перекопіюйте файли, щоб вони успадкували recordsize/компресію.
- Перенесіть метадані додатків з спінних дисків, якщо перегляд повільний (SSD-пул або special vdev).
- Переоцініть заповнення і фрагментацію; сплануйте розширення до того, як ви досягнете 90% використання.
План C: Ви вже в кризі (продукція буферизується)
- Зупиніть фонові задачі: призупиніть скани, резервні копії, відкладіть scrubs/resilvers, якщо це безпечно і дозволено політикою.
- Запустіть
zpool iostat -v 2і знайдіть явно повільний диск; замініть/перемістіть його, якщо очевидно, що він ламається. - Перевірте мережеві налаштування і угоди.
- Підтвердьте навантаження: чи ви транскодуєте? CPU може бути вашою «дисковою» проблемою.
- Після стабілізації впровадьте розділення dataset і прискорення метаданих.
Поширені питання
1) Чи завжди ставити recordsize=1M для медіа?
Для фіналізованих великих медіафайлів — так. Для всього, що робить дрібні випадкові читання/записи (метадані додатків, завантаження в процесі, мініатюри) — ні. Розділяйте dataset і налаштовуйте під навантаження.
2) Чи компресія зашкодить потоковому відео?
Зазвичай ні з lz4. Відео вже стиснене, тож заощадження невеликі, але вартість CPU низька. Ризик — у використанні важкого zstd на машині, яка вже зайнята транскодуванням.
3) Якщо compressratio лише 1.02x, чи це марно?
Ні. Навіть невеликі загальні виграші можуть ховати значну економію на супровідних файлах і метаданих. Крім того, стиснені блоки можуть означати менше байтів, що читаються з диска для стисненних частин, зменшуючи стрибки латентності.
4) Яка краща розмітка: RAIDZ2 чи дзеркала?
Для масових медіа на HDD RAIDZ2 — розумний дефолт з погляду ємності і надійності. Дзеркала виглядають швидшими для змішаного випадкового I/O і швидших resilver, але коштують дорожче в дисках. Якщо ваш вузький горлечко — латентність метаданих, special vdev може дати більше, ніж зміна топології.
5) Чи потрібен L2ARC для медіа-сервера?
Рідко. Стрімінг медіа часто послідовний і мало виграє від L2ARC, якщо тільки ви не читаєте одні й ті самі дані багаторазово і маєте недостатньо RAM. Якщо перегляд повільний — спочатку виправте локалізацію метаданих.
6) Чи вимикати atime всюди?
На медіа і читаючих dataset — так. На dataset, де робочі процеси залежать від atime (нечасто), тримайте його включеним. Якщо не знаєте — вимкніть для медіа і залиште дефолт для app dataset доти, поки не перевірите.
7) Чи коли-небудь прийнятне sync=disabled?
Тільки якщо ви свідомо приймаєте ризик втрати даних при відключенні живлення і розумієте семантику навантаження. Для бізнесу або чогось, за що ви плачете, тримайте sync=standard і використовуйте належне обладнання (UPS, SLOG якщо потрібно).
8) Наскільки заповненим можна тримати ZFS-пул?
Спробуйте тримати під ~80–85% для передбачуваної продуктивності і відновлюваності. Вище цього фрагментація і обмеження алокації можуть підсилювати латентність, особливо на RAIDZ під час записів і обслуговування.
9) Чи можна змінити ashift після створення пулу?
Не «на місці» у розумний спосіб. Практичний метод — перебудова: заміна vdev або міграція даних у новий пул. Вибирайте ashift правильно з самого початку.
10) Як снапшоти впливають на зберігання медіа?
Снапшоти дешеві, поки не стають дорогими. Медіафайли рідко змінюються, тому снапшоти не ростуть швидко — якщо ви не зберігаєте churn’ові downloads або бази додатків в тому ж dataset. Використовуйте окремі dataset і політику збереження, що відповідає рівню churn.
Висновок: практичні наступні кроки
Якщо ви хочете «великі виграші» без перетворення сховища на експериментальний арт-проєкт, зробіть три речі:
- Розділіть dataset за поведінкою: фіналізовані медіа, downloads і метадані додатків не повинні ділити одні й ті ж властивості.
- Зробіть медіа нудними:
recordsize=1M,compression=lz4,atime=offна media dataset. - Діагностуйте з доказами:
zpool status,zpool iostat,iostat, ARC-статистика та перевірка заповнення/фрагментації перед тим, як крутити ручки.
Потім, якщо перегляд і скани досі схожі на ходіння крізь мед, перестаньте звинувачувати диски і почніть ставити метадані як окреме важливе навантаження: SSD-backed dataset для додатків або зеркалений special vdev змінять досвід більше, ніж будь-який recordsize налаштування.