Планування ширини vdev у ZFS: чому більше дисків у vdev має свою ціну

Було корисно?

Ви купили купу дисків. У таблиці видно: «один величезний RAIDZ2 vdev» — це найефективніше. Потім продакшен питає: «чому під час scrub латентність підскочила до 80ms?» а ваш виклик на пульт говорить: «вітаємо, це тепер ваша проблема».

Планування ширини vdev — це момент, коли зберігання перестає бути шопінгом і стає управлінням ризиками. Ширші vdev можуть виглядати як безкоштовна ємність і пропускна здатність. Насправді вони не безкоштовні. Вони змінюють області відмови, терміни відновлення, поведінку для малих блоків I/O та спосіб розподілу роботи ZFS.

Ментальна модель: vdev — одиниці продуктивності

Пули ZFS будуються з vdev (віртуальних пристроїв). Пул здійснює стрипінг даних по vdev, а не по окремих дисках. Всередині кожного vdev ZFS покладається на макет надмірності (mirror, RAIDZ1/2/3, dRAID тощо), щоб перетворити кілька фізичних дисків на один логічний пристрій.

Останнє речення — це пастка. Люди бачать 24 диски і думають «24 шпинделі IOPS». У ZFS ви отримаєте приблизно «кількість vdev у пулі IOPS», з поправкою на макет. Пул з одним RAIDZ2 vdev — це одна черга I/O (на верхній рівень vdev) для випадкових читань і записів. Пул з шістьма mirror vdev — це шість черг I/O. Ті самі сирі диски. Інша поведінка під навантаженням.

Планування ширини vdev — це вибір області відмови та форми продуктивності. Ширші vdev консолідують ємність і можуть покращувати велику послідовну пропускну здатність. Вони також концентрують ризик і можуть зробити дрібні випадкові I/O схожими на проходження крізь патоку.

Два правила, що лишаються в силі, коли все інше міняється

  • Правило 1: Якщо ваше навантаження важко по випадкових I/O (VM, бази даних), зазвичай потрібні більше vdev, а не ширші.
  • Правило 2: Якщо ваше навантаження переважно великі послідовні операції (бекапи, медіа, архіви), ширші RAIDZ можуть бути прийнятними — доки вікна відновлення не стануть вашим новим хобі.

Цитата, яку варто тримати на стіні, бо це сутність: Надія — це не стратегія. (парафразована ідея, часто пов’язана з практиками експлуатації та культури надійності)

Жарт №1: «один гігантський vdev» — як однолінійна автострада: чудово, поки не заглохне перша машина, а тоді всі вивчають нові слова.

Короткі факти та історичний контекст

Інженери зберігання люблять сперечатися про ширину vdev, оскільки «правильна» відповідь залежить від навантаження, толерантності до ризику та того, наскільки ви ненавидите вихідні дні. Проте історія допомагає зрозуміти, чому компроміси виглядають так, як виглядають.

  1. ZFS почався в Sun Microsystems в середині 2000-х з моделлю «інтегрований volume manager + filesystem». Саме тому vdev існують: файловa система контролює RAID-рішення.
  2. RAIDZ — це не класичний апаратний RAID5/6. ZFS використовує змінну ширину стрипу для RAIDZ, що зменшує класичні проблеми «RAID5 write hole», коли його поєднують із copy-on-write і контрольними сумами.
  3. «IOPS на vdev» стало правилом великого пальця, бо ZFS відсилає I/O на рівні vdev. Це не вся історія, але це передбачає біль дивовижно добре.
  4. Scrub були задумані як операції цілісності, а не як функція продуктивності. Вони читають усе для перевірки контрольних сум. На широких vdev з великими дисками «усе» — це… багато.
  5. Зростання ємності дисків випередило IOPS протягом десятиліть. Сучасний HDD великий, але не швидкий. Ширші vdev підсилюють невідповідність «великий, але повільний» під час resilver.
  6. Реальність 4K сектора (ashift) змінила планування. Неправильне вирівнювання секторів (неправильний ashift) може тихо примножувати write amplification і латентність, особливо в RAIDZ.
  7. SSD змінили правила, але не скасували фізику. Ви можете зробити vdev широкими на SSD, і це «працюватиме», але математика parity і відновлення все одно коштує CPU і викликає латентність.
  8. dRAID існує здебільшого через те, що resilver займав занадто багато часу. Він розподіляє запасну ємність і роботу з відновлення, зменшуючи «один диск по одному днями» вікно відмови, типове для широкого RAIDZ на великих HDD.

Що насправді коштує «більше дисків у vdev»

1) Ви купуєте ємність з більшим доменом відмови

Верхній vdev — атомарна одиниця надмірності. Якщо RAIDZ2 vdev витримує втрату двох дисків, то будь-яка третя відмова в тому самому vdev катастрофічна для пулу. Коли ви робите vdev ширшим, ви кладе більше дисків у той самий «кошик з двома дозволеними відмовами».

При наявності кількох менших vdev відмови частіше розподіляються між ними. При одному широкому vdev доля пулу залежить від паритетного бюджету тієї групи. Ось вартість «радіусу ураження».

2) Відновлення триває довше, а довгі відновлення — податок на надійність

ZFS виконує resilver на рівні блоків (лише виділені дані) у багатьох випадках — і це чудово. Але пул все одно має сканувати метадані, ви все ще повинні читати з живих дисків і записувати реконструйовані блоки. Коли диски більші, «лише виділене» може бути все одно багатьма терабайтами.

Широкі vdev збільшують кількість дисків, що беруть участь у реконструкції I/O для кожного блоку. Це означає більше загальних читань під час resilver, більший шанс натрапити на латентні секторні помилки, більше конкуренції з продуктивними навантаженнями і більше часу в небезпечному вікні, коли друга/третя відмова все закінчує.

3) Малі випадкові I/O: парність не безкоштовна

Mirrors дружні до випадкових I/O: читання можна балансувати між обома сторонами, а малі записи відносно дешеві. RAIDZ мусить обчислювати парність і часто виконувати read-modify-write для часткових стрипів. ZFS розумна, але не магічна.

Зі збільшенням ширини vdev «повний розмір стрипу» зростає. Для робочих навантажень із малими блоками (типово для VMs і баз даних) ви часто пишете часткові стрипи. Це штовхає RAIDZ до додаткових читань і оновлень парності. Ширші vdev означають більше роботи на запис і більше варіацій латентності.

4) Латентність стає більш стрибкоподібною під фоновими роботами

Scrub, resilver і тяжкі послідовні читачі зачіпають кожен диск. На широкому vdev ці операції вмикають більше дисків одночасно і роблять це довше. Пул все ще може обслуговувати нормальне I/O, але черги глибшають. Відсотильні показники латентності ростуть. І саме відсотилі будять вас вночі, а не середнє значення.

5) Ви не отримуєте «більше продуктивності», як ви думаєте

Для послідовної пропускної здатності ширший RAIDZ може допомогти, бо більше дисків долучається до кожного стрипу. Для випадкових IOPS, особливо записів, один RAIDZ vdev поводиться як один пристрій з накладними витратами парності. Якщо потрібні більші випадкові IOPS — потрібні більше верхньорівневих vdev.

Отже, аргумент «більше дисків у vdev» зазвичай: краща ємнісна ефективність, іноді краща послідовна пропускна здатність, менше vdev для моніторингу. Рахунок приходить як: гірша випадкова продуктивність на ТБ, більший домен відмови, довші відновлення, суворіший вплив фонових робіт.

6) Планування розширення стає незручним

ZFS історично розширював пули додаванням vdev, а не «додаванням дисків у RAIDZ vdev». Розширення RAIDZ стало можливим в сучасному OpenZFS, але це не картка «вийти з в’язниці безкоштовно»: це важка операція, займає час, і ви все одно отримаєте ширший vdev та всі згадані витрати.

Планування ширини vdev — це також планування того, як ви будете рости. Якщо ваша модель зростання — «купити ту ж саму полиці знову», менші vdev, що відповідають геометрії полиці, зазвичай краще старіють.

Підійдіть ширину vdev під навантаження: послідовні, випадкові, змішані

Великі послідовні (репозиторії бекапів, медіа, архіви)

Послідовні записи і читання — це місце, де RAIDZ може виглядати чудово. Ви стрімуєте великі блоки, ZFS може зібрати великий I/O, і диски зайняті впорядковано. Ширші vdev можуть збільшити агрегатну пропускну здатність, бо більше дисків беруть участь у кожному стрипі.

Але: репозиторії бекапів також роблять scrub, обрізку і іноді багато паралельних відновлень. Якщо ви побудуєте один монстр RAIDZ2 vdev, фонові роботи й хвилі відновлень будуть конкурувати в тій самій одиничній черзі vdev. Якщо ви можете це терпіти (і ваш RTO дозволяє) — гаразд. Якщо відновлення — це момент, коли ваш CEO дізнається про зберігання, не ризикуйте.

Важкі по випадкових I/O (VM datastore, бази даних)

Тут широкий RAIDZ зазвичай — не те, що треба. Не тому, що він «повільний», а тому, що він непередбачуваний під тиском. Латентність випадкових записів — вбивця. Mirrors (або більше vdev більш вузького RAIDZ) розподіляють I/O по більшій кількості незалежних черг і зменшують накладні парності.

Якщо ви мусите використовувати RAIDZ для зберігання VM на HDD, тримайте vdev вужчими, використайте достатньо vdev для паралелізму і будьте чесними щодо очікувань продуктивності. Якщо це SSD/NVMe, RAIDZ може бути прийнятним, але макети mirror часто виграють по tail latency у багатьох реальних навантаженнях.

Змішані навантаження (файлові шаринги + VMs + бекапи в одному пулі)

Ось де «один пул, щоб керувати всім» стає гострим. Змішані навантаження створюють змішані розміри I/O. RAIDZ погано переживає змішані малі випадкові записи, коли хтось інший читає послідовно. Ваш моніторинг покаже «завантаження» і «пропускну здатність», а ви все одно отримаєте скарги, бо люди відчувають латентність.

У корпоративному житті змішані навантаження відбуваються через бюджети. Якщо не можете розділити пули, хоча б розділіть vdev: більше vdev дає ZFS опції. Також розгляньте спеціальні vdev для метаданих/малих блоків, якщо знаєте, що робите — зроблено правильно, це може перетворити роботу з великою кількістю директорій і малих файлів.

RAIDZ: парність, ширина vdev і фізика, з якою не домовишся

Рівні парності: RAIDZ1 vs RAIDZ2 vs RAIDZ3

Парність — це ваша страхова політика. RAIDZ1 (одна парність) все частіше є поганою ідеєю для великих HDD у критичних середовищах, бо вікна відновлення довгі, а латентні помилки читання — не казка. RAIDZ2 — практичний базовий рівень для HDD-пулів, що мають значення. RAIDZ3 існує, коли ви хочете спати під час довгого resilver на величезних дисках, але це коштує більше паритетного оверхеду і продуктивності.

Парність не масштабуються з шириною. RAIDZ2 з 6 дисків і RAIDZ2 з 16 дисків обидва витримують дві відмови. Ширший vdev означає «та сама кількість дозволених відмов для більшого числа дисків». Це основний компроміс надійності.

Recordsize, volblocksize і чому «малі записи» стають проблемою для всіх

ZFS пише у рекордах (за замовчуванням recordsize часто 128K для файлових систем), але zvol мають volblocksize (часто 8K/16K). Бази даних і VM-образи зазвичай генерують 4K–16K записи. Якщо ваш повний-стріп RAIDZ великий, а фактичні записи малі, ви в території часткових стрипів. Часткові стрипи — місце, де накладні парності і read-modify-write проявляються у вигляді латентності.

Виправлення не в «крутити ручки, поки стане краще». Виправлення: оберіть макет vdev, що відповідає формі I/O навантаження, і встановіть recordsize/volblocksize свідомо.

Стиснення змінює математику ширини (в основному в хорошу сторону)

Compression (наприклад lz4) зменшує байти, що записуються. Це може зменшити час диска і інколи зменшити паритетну роботу. Також це може робити записи меншими і більш розкиданими, що підвищує метадані. Зазвичай стиснення — виграш, але вимірюйте — особливо на системах, що вже завантажені CPU.

Спеціальні vdev і SLOG: потужні, але гострі інструменти

Спеціальні vdev (для метаданих і малих блоків) можуть врятувати продуктивність для робочих навантажень з малими файлами на HDD RAIDZ. Але вони стають критичними пристроями: втрата спеціального vdev може призвести до втрати пулу. Тому потрібні дзеркальні спеціальні vdev з надійними пристроями і моніторингом.

SLOG (separate log) допомагає лише для синхронних записів. Він не виправить загальну латентність. Встановлюйте його, якщо розумієте свій sync-навантаження, а не тому, що бачили це в форумі.

Жарт №2: Купувати SLOG, щоб виправити латентність випадкових записів — як купити гарніший килимок, щоб зупинити протікання даху.

Математика resilver/rebuild: час, вікно ризику і радіус ураження

Чому широкий vdev робить ризик resilver відчутним особисто

Під час resilver живі диски читаються інтенсивно і безперервно. Це стрес. Це також час, коли ви виявляєте, які диски тихо накопичували помилки. Широкий vdev означає, що більше дисків у тій самій групі надмірності і більше дисків треба прочитати, щоб реконструювати дані. Resilver зачіпає більше обладнання і триває довше, що підвищує шанс, що щось ще вийде з ладу раніше, ніж ви закінчите.

Виділені дані vs повний диск: ZFS допомагає, але не ставте на це роботу

ZFS resilver зазвичай швидший, ніж класичний RAID rebuild, бо він може пропускати не виділені блоки. Чудово. Але реальні пули не пусті, а метадані все одно потребують сканування. Також «швидко» відносне, коли ваші диски — десятки терабайтів і пул зайнятий.

Широкі vdev збільшують побічні втрати під час відновлення

Навіть якщо resilver завершився успішно, широкий vdev має тенденцію деградувати продуктивність більше під час процесу, бо більше дисків зайняті роботою відновлення. Якщо пул обслуговує чутливі до латентності навантаження, вікно відновлення стає інцидентом продуктивності.

Операційна імплікація: план відновлення — частина архітектури

Не плануйте ширину vdev у вакуумі. Плануйте її з урахуванням:

  • Як швидко ви можете замінити відмовний диск (люди, спари, SLA вендора).
  • Скільки деградації продуктивності ви можете терпіти під час resilver.
  • Як довго пул може працювати в «зниженій надмірності» безпечно.
  • Що станеться, якщо другий диск відмовить посеред resilver.

Три корпоративні міні-історії (анонімізовані, але реальні)

1) Інцидент через хибне припущення: «24 диски = багато IOPS»

Компанія була в періоді зростання, мігруючи з legacy SAN на ZFS-пристрій. На папері була одна вимога: «підтримувати існуючу VM-ферму без регресу продуктивності». Учасник команди зробив знайомі підрахунки: 24 HDD, 7200 RPM, отже «достатньо» IOPS. Побудували один RAIDZ2 vdev, бо він максимізував корисний простір і виглядав охайно.

Він пройшов початкові тести. Синтетичний бенчмарк використовував великі послідовні операції. Графіки виглядали героїчно. Міграція пройшла, і тиждень було тихо.

Потім у понеділок ранковий шторм логінів вдарив. VMs завантажувалися, антивірус оновлювався, Windows робив Windows-справи, і латентність піднялася. Не поступово — стрибкоподібно. Хелпдеск писав «все повільно». Логи гіпервізора: «storage latency 100–200ms». Бокс зберігання не «впав», а потонув.

Вони виявили помилку: пул мав один верхній vdev. Одна черга. Випадковий I/O від десятків VMs накопичувався в цю чергу, а накладні RAIDZ робили записи гіршими. Виправлення не було налаштуванню. Виправлення було архітектурним: перебудувати пул у кілька vdev (у їхньому випадку — дзеркала), прийняти менше корисного простору і отримати передбачувану латентність. Жорсткий урок: IOPS приходять від кількості vdev і типу носія, а не просто від загальної кількості дисків.

2) Оптимізація, що відкотилася: «Зробимо ширше, щоб зменшити оверхед парності»

Інша організація вела великий репозиторій бекапів на HDD RAIDZ2. Працювало. Не швидко, але прийнятно. Вони вирішили «оптимізувати», збільшивши ширину vdev під час розширення: менше vdev, ширші кожен, простіший макет, трохи краща ємнісна ефективність. Також менше vdev означало менше об’єктів для моніторингу — що в нарадах завжди звучить добре.

Для великого послідовного інжесту це покращилося. Джоби інжесту завершувалися швидше, і всі себе вітали. Потім квартальний scrub вдарив. Scrub тривав довше, але це терпіли.

Реальна відмова виявилася через кілька тижнів під час дня відновлень. Вони мали кілька паралельних відновлень, поки вже йшла resilver (бо зрештою диск відмовив у завантажений період). Ширший vdev означав, що resilver зачіпав більше дисків, а це більше конкуренції. Продуктивність відновлення впала, і RTO, який вони обіцяли внутрішнім клієнтам, перетворився на інцидент продуктивності.

Оптимізація «працювала» для найкращого випадку і провалилася для найгіршого. Класична корпоративна пастка: бенчмарк на ясний день, життя під час бурі.

3) Нудна, але правильна практика, що врятувала день: вужчі vdev, гарячі спари та дисципліна scrub

Третя команда вела змішане середовище: домашні директорії, артефакти збірки та трохи VM-зберігання. Вони були консервативні. Побудували кілька RAIDZ2 vdev помірної ширини, тримали принаймні один протестований spare на місці і регулярні scrubs з моніторингом тривалості scrub і лічильників помилок.

Це не було гламурно. Ефективність ємності не була «максимальною». Вони також мали правило: жодного пулу вище певного порогу заповнення (вони прагнули зберігати реальний вільний простір, а не фантазійний). Фінанси скаржилися; інженери зітхали і рухалися далі.

Одної п’ятничної години вийшов диск. Spare вставили одразу, і почався resilver. Ночі через півтора дня другий диск у тій самій шафі кинув помилки. Оскільки vdev були вужчими і історія scrub вже виявляла пару маргінальних дисків раніше в році, у них були замінники. Друга відмова трапилася в іншому vdev, отже надмірність витримала. Пул залишився онлайн, продуктивність впала, але залишалася придатною, і понеділок не став розбором інциденту.

Нудна практика не «запобігла» відмові. Вона зменшила радіус ураження і скоротила час в небезпеці. Ось що робить хороша архітектура зберігання.

Швидкий план діагностики: знайдіть вузьке місце перед тим, як «налаштовувати»

Коли продуктивність погана, команди часто починають крутити ZFS-ручки, як радіо. Не робіть так. Спочатку визначте обмежуючий ресурс і чи це структурна проблема (ширина/макет vdev) або ситуаційна (scrub, resilver, один відмовний диск).

По-перше: підтвердіть топологію пулу і поточний стан

  • Це один широкий RAIDZ vdev чи багато vdev?
  • Чи виконується scrub/resilver?
  • Чи є read/write/checksum помилки?

По-друге: визначте, чи проблема в латентності, пропускній здатності чи CPU

  • Висока латентність при низькій пропускній часто означає черги, малі випадкові I/O або хворий диск.
  • Висока пропускна зі прийнятною латентністю означає, що, ймовірно, все добре.
  • Високе навантаження CPU під час записів може означати стиснення, контрольні суми, парність RAIDZ або невідповідність recordsize.

По-третє: ізолюйте, чи один vdev/диск є «булієм»

  • Якщо один диск показує високу латентність або помилки, він може тягнути весь RAIDZ vdev униз.
  • Якщо один vdev насичений, а інші прості — ви обмежені кількістю vdev, а не кількістю дисків.

По-четверте: перевірте вільне місце пулу і індикатори фрагментації

  • Дуже заповнені пули поводяться погано, особливо для RAIDZ з малими блоками.
  • Вільний простір — це бюджет продуктивності, а не лише ємність.

По-п’яте: вирішіть, чи виправлення оперативне чи архітектурне

  • Операційні виправлення: замінити відмовний диск, перенести scrub, обмежити швидкість resilver, додати SLOG лише якщо потрібно для sync.
  • Архітектурні виправлення: додати vdev, перебудувати під дзеркала, розділити навантаження між пулами, розглянути спеціальні vdev або dRAID там, де доречно.

Практичні завдання: 12+ команд, виводів та рішень

Ось команди, які ви виконуєте, коли хтось каже «зберігання повільне», і вам потрібні докази. Кожне завдання включає, що означає вивід і яке рішення прийняти.

Завдання 1: Визначте макет vdev і поточний стан

cr0x@server:~$ zpool status -v tank
  pool: tank
 state: ONLINE
  scan: scrub repaired 0B in 07:12:44 with 0 errors on Tue Dec 24 03:12:01 2025
config:

        NAME                        STATE     READ WRITE CKSUM
        tank                        ONLINE       0     0     0
          raidz2-0                  ONLINE       0     0     0
            /dev/disk/by-id/ata-d1  ONLINE       0     0     0
            /dev/disk/by-id/ata-d2  ONLINE       0     0     0
            /dev/disk/by-id/ata-d3  ONLINE       0     0     0
            /dev/disk/by-id/ata-d4  ONLINE       0     0     0
            /dev/disk/by-id/ata-d5  ONLINE       0     0     0
            /dev/disk/by-id/ata-d6  ONLINE       0     0     0
            /dev/disk/by-id/ata-d7  ONLINE       0     0     0
            /dev/disk/by-id/ata-d8  ONLINE       0     0     0

errors: No known data errors

Значення: Один RAIDZ2 vdev з 8 дисками. Scrub завершився, помилок немає.

Рішення: Якщо цей пул обслуговує випадкові I/O і скарги — швидше за все ви обмежені кількістю vdev. Розгляньте додавання верхніх vdev (або перебудову макету) замість пошуку «крутилок».

Завдання 2: Показати використання vdev і латентність

cr0x@server:~$ zpool iostat -v tank 1 5
                              capacity     operations     bandwidth
pool                        alloc   free   read  write   read  write
--------------------------  -----  -----  -----  -----  -----  -----
tank                        22.1T  12.7T    310    420  42.1M  55.8M
  raidz2-0                  22.1T  12.7T    310    420  42.1M  55.8M
    ata-d1                      -      -     38     52  5.3M   7.1M
    ata-d2                      -      -     40     50  5.4M   6.9M
    ata-d3                      -      -     39     52  5.4M   7.1M
    ata-d4                      -      -     38     53  5.2M   7.2M
    ata-d5                      -      -     39     53  5.4M   7.2M
    ata-d6                      -      -     38     53  5.2M   7.2M
    ata-d7                      -      -     39     53  5.4M   7.2M
    ata-d8                      -      -     39     54  5.4M   7.3M
--------------------------  -----  -----  -----  -----  -----  -----

Значення: Весь I/O йде через один vdev. Розподіл по дисках виглядає рівномірним (добре), але це все одно може бути вузькою чергою для випадкового I/O.

Рішення: Якщо вам потрібно більше випадкових IOPS, додайте ще один vdev (такої самої надмірності) для збільшення паралелізму на верхньому рівні. Ширший vdev тут не допоможе.

Завдання 3: Впіймати відмовний диск по латентності, не лише по помилках

cr0x@server:~$ iostat -x 1 3
Linux 6.8.0 (server)  12/26/2025  _x86_64_  (32 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           6.12    0.00    3.44    9.33    0.00   81.11

Device            r/s     w/s   rkB/s   wkB/s  avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sda              6.0    12.0    512    2048      256.0     0.7   38.2   12.4   51.1   2.4   4.3
sdb             45.0    60.0   5200    7600      245.3     9.9   96.7   90.2  101.5   3.1  32.5
sdc             46.0    59.0   5150    7550      244.9     2.1   19.4   17.2   21.2   2.9  30.8

Значення: sdb має значно вищий await і глибину черги, ніж інші. Може бути повторна спроба або внутрішній ремап.

Рішення: Подивіться SMART і розгляньте профілактичну заміну. Один повільний диск може гальмувати RAIDZ, бо кожен стрип чекає найповільнішого.

Завдання 4: Перевірити SMART-лічильники помилок і історію самотестів

cr0x@server:~$ sudo smartctl -a /dev/sdb | egrep -i 'Reallocated|Pending|Uncorrect|Power_On_Hours|SMART overall|Self-test'
SMART overall-health self-assessment test result: PASSED
Power_On_Hours          37124
Reallocated_Sector_Ct   12
Current_Pending_Sector  3
Offline_Uncorrectable   1
SMART Self-test log structure revision number 1
# 1  Extended offline    Completed: read failure       90%     37110         12345678

Значення: «PASSED» — слабкий сигнал. Pending/uncorrectable сектори та провалений extended тест — гучний сигнал.

Рішення: Замініть диск до того, як він стане другою відмовою під час resilver. Також розгляньте запуск scrub після заміни для перевірки.

Завдання 5: Підтвердити ashift (вирівнювання секторів) для пулу

cr0x@server:~$ zdb -C tank | egrep -m1 'ashift|vdev_tree'
        ashift: 12

Значення: ashift=12 означає припущення про 4K сектори. Добре для сучасних HDD/SSD.

Рішення: Якщо бачите ashift=9 на 4K дисках, очікуйте write amplification і погану продуктивність. Виправлення вимагає перебудови пулу правильно; після факту ashift не змінити простим налаштуванням.

Завдання 6: Ідентифікувати датасети і чи використовуєте ви zvol (VM) чи файлові системи

cr0x@server:~$ zfs list -o name,type,used,available,recordsize,volblocksize -r tank
NAME               TYPE   USED  AVAIL  RECSIZE  VOLBLOCK
tank               filesystem  22.1T  12.7T   128K     -
tank/vmstore       filesystem   8.2T  12.7T   128K     -
tank/vmstore/zvol1 volume      600G  12.7T      -     8K
tank/backups       filesystem  10.3T  12.7T   1M       -

Значення: VMs використовують zvol з volblocksize 8K; датасет бекапів має recordsize 1M (добре для послідовного).

Рішення: Якщо латентність VM погана на широкому RAIDZ, розгляньте переміщення VM на mirrors або SSD, або збільште кількість vdev. Для бекапів ширший RAIDZ може бути прийнятним.

Завдання 7: Перевірити sync-настройки і чи SLOG має значення

cr0x@server:~$ zfs get -o name,property,value,source sync tank/vmstore/zvol1
NAME                PROPERTY  VALUE  SOURCE
tank/vmstore/zvol1   sync      standard  local

Значення: Sync-запити виконуються. Якщо ваше навантаження багато sync (бази даних, NFS з sync), латентність може визначатися поведінкою ZIL.

Рішення: Розглядайте SLOG лише якщо підтвердите значне sync-навантаження і можете забезпечити пристрої з захистом від втрати живлення. Інакше — не ставте.

Завдання 8: Виміряти навантаження sync-записів через ZIL-статистику (Linux OpenZFS)

cr0x@server:~$ cat /proc/spl/kstat/zfs/zil | egrep 'zil_commit|zil_itx_count|zil_itx_indirect_count'
zil_commit                          18442
zil_itx_count                        9921
zil_itx_indirect_count                 144

Значення: Нетривіальні ZIL-коміти відбуваються. Якщо це швидко зростає під час скарги, присутні sync-записи.

Рішення: Якщо sync-латентність — вузьке місце, оцінюйте SLOG (у дзеркалі) або батчинг на рівні додатка. Якщо ні — не звинувачуйте ZIL.

Завдання 9: Підтвердити, чи запущений scrub/resilver і наскільки швидко він просувається

cr0x@server:~$ zpool status tank
  pool: tank
 state: ONLINE
  scan: scrub in progress since Thu Dec 26 08:11:02 2025
        9.21T scanned at 1.12G/s, 2.03T issued at 252M/s, 22.1T total
        0B repaired, 9.19% done, 1 day 01:33:40 to go
config:
...

Значення: Scrub працює і триватиме більше доби. Це довгий період, протягом якого диски діляться ресурсами з продуктивністю.

Рішення: Якщо це впливає на чутливі до латентності навантаження, плануйте scrubs у тихіші вікна і розгляньте вужчі vdev/більше vdev для майбутніх побудов, щоб зменшити вплив scrub на кожен vdev.

Завдання 10: Перевірити вільне місце пулу і прапори спеціального розподілу

cr0x@server:~$ zpool list -o name,size,alloc,free,cap,health
NAME  SIZE   ALLOC   FREE  CAP  HEALTH
tank  34.8T  22.1T  12.7T  63%  ONLINE

Значення: 63% заповнено — комфортно. Якщо ви регулярно понад ~80–85% на RAIDZ зі змішаними навантаженнями, очікуйте погіршення фрагментації і латентності.

Рішення: Якщо використання високе, плануйте розширення до того, як дістанете до критичного рівня. Розширення простіше, ніж відновлення, і дешевше, ніж пояснювати бізнесу, чому записи стали повільні «без причини».

Завдання 11: Визначити розподіл розмірів блоків через швидкий fio-семпл

cr0x@server:~$ fio --name=randwrite --filename=/tank/vmstore/testfile --rw=randwrite --bs=4k --iodepth=32 --numjobs=4 --size=8G --runtime=30 --time_based --direct=1
randwrite: (g=0): rw=randwrite, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=psync, iodepth=32
...
  write: IOPS=820, BW=3.2MiB/s (3.4MB/s)(96MiB/30001msec)
    lat (usec): min=450, max=280000, avg=38500.12, stdev=42000.55

Значення: 4K випадкові записи — низькі IOPS з великою макс/середньою латентністю. На HDD RAIDZ це очікуваний біль.

Рішення: Якщо це нагадує продуктивне навантаження, припиніть намагатись «налаштувати» проблему. Використайте mirrors/SSD, збільшіть кількість vdev або відокремте VM-зберігання від масового.

Завдання 12: Перевірити тиск ARC (пам’ять) і чи читання з кешу чи з диска

cr0x@server:~$ arcstat 1 3
    time  read  miss  miss%  dmis  dm%  pmis  pm%  arcsz     c
08:32:11  12K   4K     33%   2K   16%   2K   16%   96G   110G
08:32:12  11K   5K     45%   3K   27%   2K   18%   96G   110G
08:32:13  13K   4K     30%   2K   15%   2K   15%   96G   110G

Значення: ARC hit rate — задовільний. Якщо miss% високий і ви обмежені по часу читання, диски роблять реальну роботу.

Рішення: Якщо читання не потрапляє в ARC і ваші диски вже зайняті, не розширюйте vdev в надії на диво. Розгляньте додавання RAM (якщо це рентабельно), розділення навантаження або використання special vdev/L2ARC лише після вимірів.

Завдання 13: Перевірити на checksum-помилки, що вказують на тиху корупцію або проблеми кабелювання

cr0x@server:~$ zpool status -v tank | egrep -A2 'READ|WRITE|CKSUM'
        NAME                        STATE     READ WRITE CKSUM
        tank                        ONLINE       0     0     0
        raidz2-0                  ONLINE       0     0     0

Значення: Помилок немає. Якщо бачите CKSUM помилки, не робіть поспішних висновків «поганий диск» — часто це кабель, HBA, expander або живлення.

Рішення: Якщо CKSUM росте, перевірте апаратний шлях (заміна кабелю, порту, HBA). Не перебудовуйте макет, щоб виправити неплотний кабель.

Завдання 14: Проінспектувати властивості датасету, що впливають на форму I/O

cr0x@server:~$ zfs get -o name,property,value,source compression,atime,recordsize,logbias,primarycache tank/vmstore tank/backups
NAME          PROPERTY      VALUE     SOURCE
tank/vmstore  compression   lz4       local
tank/vmstore  atime         off       local
tank/vmstore  recordsize    128K      default
tank/vmstore  logbias       latency   default
tank/vmstore  primarycache  all       default
tank/backups  compression   lz4       local
tank/backups  atime         off       local
tank/backups  recordsize    1M        local
tank/backups  logbias       throughput local
tank/backups  primarycache  all       default

Значення: Бекапи налаштовані під пропускну здатність; VM-store — налаштування за замовчуванням можуть підійти, але вибір zvol важливіший, ніж recordsize.

Рішення: Якщо датасет налаштований проти свого навантаження (наприклад recordsize занадто малий для бекапів, sync увімкнений без причини), виправте властивості. Але не чекайте, що властивості вирішать поганий макет vdev.

Типові помилки: симптом → корінь проблеми → виправлення

Помилка 1: «Латентність стрибає під час scrub; користувачі скаржаться»

Симптоми: Передбачуване збільшення латентності при старті scrub; інтерактивні робочі навантаження гальмують; zpool status показує scrub у процесі.

Корінь: Широкий vdev + HDD означає, що scrub довгий і конкурує за ту ж диск-бандwidth та черги з продуктивним I/O.

Виправлення: Плануйте scrubs у нічні години; розгляньте кілька vdev (більше верхнього паралелізму) для майбутніх побудов; розділіть чутливі до латентності навантаження від масових пулів.

Помилка 2: «У нас 20+ дисків, тож продуктивність VM має бути чудова»

Симптоми: Низькі IOPS, високі хвостові латентності, пропускна здатність виглядає ок але додатки таймаутять; особливо погано під час штормів завантаження.

Корінь: Один (або замало) RAIDZ vdev. Випадковий I/O обмежений кількістю vdev і оверхедом парності.

Виправлення: Використовуйте mirrors для VM/баз даних на HDD, або збільшіть кількість верхніх vdev. Якщо мусите використовувати RAIDZ — тримайте vdev вужчими і додавайте їх більше.

Помилка 3: «Resilver займає вічність; ми нервово живемо кілька днів»

Симптоми: Оцінка часу resilver — кілька днів; продуктивність деградує; тривога щодо другої відмови стає способом життя.

Корінь: Широкий vdev + великі диски + висока заповненість + активне навантаження. Вікно відновлення довге і стресове.

Виправлення: Тримайте нижчу заповненість; обирайте вужчі vdev або dRAID де доречно; матимайте on-site spares; плануйте throttling відновлення і вікна обслуговування.

Помилка 4: «Додали SLOG і нічого не змінилося»

Симптоми: Латентність та ж; немає помітного покращення; іноді гірша стабільність через дешевий SSD.

Корінь: Навантаження не sync-write домінантне, або SLOG не має захисту від втрати живлення, або реальна проблема — write amplification у широкому RAIDZ.

Виправлення: Спочатку виміряйте sync-rate; якщо потрібно — використовуйте правильні enterprise-пристрої і дзеркально їх ставте. Інакше прибирайте зайву складність.

Помилка 5: «Один диск трохи повільний, але почекаємо»

Симптоми: Поки немає ZFS-помилок, але iostat показує один диск з вищою латентністю; іноді таймаути в логах.

Корінь: Диск деградує, шлях кабелю ненадійний або порт expander не в порядку. RAIDZ чекатиме найповільнішого члена.

Виправлення: Проактивно замініть або перемістіть підозрілий компонент. Підтвердіть SMART і логи помилок. Не чекайте, поки він «вийде» під час resilver.

Помилка 6: «Пул на 90% і записи стали повільні; це має бути баг»

Симптоми: Зростаюча латентність з часом; мало вільного місця; фрагментація і зростання метаданих.

Корінь: Copy-on-write потребує вільного простору для ефективного розміщення. RAIDZ страждає більше, коли вільні сегменти зменшуються і записи стають розкиданими.

Виправлення: Додайте ємність до того, як пул заповниться; встановіть внутрішні ліміти (quotas/reservations); архівуйте або видаляйте; розділяйте «гарячі» і «холодні» дані по пулах.

Чеклісти / покроковий план

Покрокове планування ширини vdev (що я зробив би перед купівлею дисків)

  1. Класифікуйте навантаження: переважно послідовне, переважно випадкове або змішане. Якщо не можете визначити — воно змішане.
  2. Визначте толерантність до відмов: RAIDZ2 — базова опція для HDD; RAIDZ3 — для дуже великих дисків або довгого часу заміни; дзеркала — для низької латентності.
  3. Визначте цільову форму продуктивності: скільки випадкових IOPS вам реально потрібно і який відсотиль латентності прийнятний?
  4. Спочатку оберіть кількість vdev: кількість верхніх vdev — ваш бюджет паралелізму. Потім виберіть ширину на vdev.
  5. Оберіть ширину vdev консервативно:
    • Для HDD VM/баз даних: дзеркала, багато vdev.
    • Для HDD бекапів/архіву: RAIDZ2 помірної ширини; уникайте «одного гігантського vdev», якщо не погоджуєтеся з ризиком відновлення.
  6. Плануйте інкременти зростання: додавайте vdev з часом; тримайте макети консистентними. Уникайте одного незвичного vdev, що поводиться інакше.
  7. Тримайте запас вільного простору: встановіть внутрішній ліміт (часто ~80% для змішаних навантажень) і ставте це як політику, не пропозицію.
  8. Плануйте відновлення: on-site spare(и), задокументована процедура заміни, моніторинг ранніх сигналів відмови.
  9. Розділіть рівні, якщо потрібно: розмістіть latency-sensitive VM на mirrors/SSD, масові дані — на RAIDZ.
  10. Тестуйте робочим бенчмарком: random 4K/8K, змішані read/write, плюс scrub у роботі — бо це реальність.

Операційний чекліст (що перевіряти щомісяця)

  • Графік scrub і остання тривалість scrub; розслідуйте, якщо тривалість зростає.
  • SMART-лічильники помилок і провалені self-test; замінюйте проактивно.
  • Тренд використання пулу і прогнозовану «дату 80%».
  • zpool status чистий, без CKSUM помилок.
  • Хвостові показники латентності під піками і під фоновими операціями.

Питання й відповіді

Q1: Чи правда, що «ширший RAIDZ vdev = швидше»?

Для великої послідовної пропускної здатності — так: більше дисків на стрип може підвищити пропускну. Для випадкових I/O, особливо малих записів, ширший часто гірше або принаймні не краще.

Q2: Чому кажуть «IOPS приходять від vdev»?

Тому що ZFS стрипує по верхніх vdev. Кожен vdev — одиниця продуктивності з власним чергуванням. Більше vdev означає більше паралелізму для випадкового I/O.

Q3: Яка «безпечна» ширина RAIDZ2?

«Безпека» залежить від розміру дисків, часу заміни та навантаження. Практично помірні ширини легше витримувати, ніж дуже широкі, бо вікна відновлення і радіус ураження зростають зі шириною.

Q4: Якщо в мене 24 диски, чи робити один 24-wide RAIDZ2?

Майже ніколи не для загального або VM-орієнтованого пулу. Ви отримаєте величезний домен відмови і поведінку «одного vdev» для випадкових I/O. Краще розбити на кілька vdev.

Q5: Дзеркала «витрачають» 50% ємності. Чому б їх обрати?

Бо вони дають низьку латентність, високі випадкові IOPS, простішу поведінку при відмові і часто швидші resilver. Ємність дешевша за простій.

Q6: Чи вирішує додавання L2ARC проблему випадкових I/O у широких vdev?

Іноді допомагає для читаємістих робочих наборів з повторним доступом. Він не виправить латентність випадкових записів або накладні парності. Також L2ARC має пам’ятні й часи прогріву особливості.

Q7: Чи варто використовувати RAIDZ1 на менших дисках?

Для важливих HDD-даних RAIDZ1 — це гра в рулетку. RAIDZ2 — розумний стандарт. RAIDZ1 може бути прийнятним для неважливих, легко відтворюваних даних з короткими вікнами відновлення.

Q8: Чи можна розширити RAIDZ vdev додаванням дискiв пізніше?

Сучасний OpenZFS підтримує розширення RAIDZ, але це важка операція і ви все одно отримаєте ширший vdev і його кошти. Багато організацій все ще вважають за краще додавати новий vdev для росту.

Q9: Чи вирішує dRAID проблему «широкого vdev при rebuild»?

dRAID зменшує час resilver, розподіляючи роботу відновлення і запасну ємність. Це хороший вибір для великих HDD-пулів, але не універсальна заміна дзеркал для низьколатентних навантажень.

Q10: Яка найгірша помилка в плануванні?

Проєктувати для ефективності ємності спочатку і трактувати поведінку продуктивності/відновлення як «проблеми налаштування». Макет — це архітектура. Налаштування — приправи.

Наступні кроки, які можна зробити цього тижня

  • Інвентаризуйте ваші пули: перелічіть макети vdev, які навантаження обслуговують, тривалість scrub і типовий час відповіді.
  • Проганяйте швидкий план діагностики під час вікна скарг і під час scrub; порівняйте результати.
  • Визначте, за що ви оптимізуєте: низька латентність, висока пропускна здатність або максимум корисних ТБ. Оберіть одну основну мету на пул.
  • Якщо ви обмежені кількістю vdev: плануйте розширення шляхом додавання vdev (або міграцію на дзеркала для гарячого шару), а не розширюйте існуючий vdev.
  • Якщо вікна resilver лякають: зменшіть ширину vdev у наступних побудовах, тримайте більше вільного простору і майте протестовані spares на місці.
  • Напишіть runbook відновлення: кроки заміни диска, очікувана поведінка resilver і які метрики тригерять ескалацію.

Якщо ви візьмете одне різке правило з усього цього, нехай буде так: не будьте першими, хто будує свій початковий ZFS-пул як один широкий RAIDZ vdev, якщо навантаження не дійсно послідовне і ризик не прийнятний. Коли це йде не так, воно не йде тихо.

← Попередня
Ubuntu 24.04: Apache vs Nginx — виправте прив’язку портів і проксі-цикли чисто
Наступна →
MariaDB vs PostgreSQL для мультиорендного хостингу: як одна клієнтська сайт не повинен убити всіх

Залишити коментар