Ваш додаток «повільний». Команда баз даних клянеться, що нічого не змінювала. CPU у нормі. Графіки мережі нудні.
І потім хтось вказує на сховище: «ZFS виглядає зайнятим». Вітаємо — ви потрапили в ту частину інциденту,
де люди починають сміливо висловлюватися, керуючись відчуттями.
zpool iostat — це місце, куди відчуття відправляються вмирати. Це також місце, де добрі інженери іноді застрягають,
бо вивід виглядає простим і повним чисел, які здаються такими, що підтверджують будь-яку вашу ранню теорію.
Ось як перетворити ті числа на вузьке місце, яке можна назвати, виміряти і виправити.
Що таке ZFS iostat (і чим він не є)
ZFS дає кілька «лінз» iostat. Та, яку мають на увазі більшість людей, — це zpool iostat, який показує
пропускну здатність і швидкість I/O по пулу та по vdev. Залежно від прапорців, він також може показувати затримку, розмір черги та
розподіли по пристроях. Це погляд ZFS на роботу, а не погляд блочного пристрою і не обов’язково те, що
ваш додаток вважав відправленим.
Чим він не є: це не повний профайлер продуктивності, він не скаже «базі даних не вистачає індексу», і не розділить
«погане навантаження» від «поганого дизайну сховища» сам по собі. Але він скаже, куди пул витрачає час:
який vdev, який пристрій, читання проти записів, пропускна здатність проти IOPS проти затримки, і чи ви заблоковані на
найповільнішому диску або на власних конфігураційних рішеннях.
Корисне правило: якщо ви не можете пояснити інцидент у термінах кількох стабільних метрик (IOPS, пропускна здатність, затримка),
ви ще не завершили відладку; ви тільки почали складати оповідь.
Цікаві факти та історичний контекст
- ZFS почався в Sun на початку 2000-х, щоб вирішити складність файлової системи та менеджера томів, об’єднавши їх в одну систему зі сквозними контрольними сумами.
- Ідея «пулу зберігання» була радикальною в світі розділів і таблиць LUN; вона змінила підхід оперативних команд до управління ємністю.
- vdev — це одиниця продуктивності: ZFS нано-розподіляє дані між vdev, а не між окремими дисками так, як багато хто помилково припускає.
- Математика парності RAIDZ — ось чому малі випадкові записи болючіші на RAIDZ, ніж на дзеркалах; «збільшення запису» — не маркетинг, а арифметика.
- OpenZFS розійшовся й зійшовся: кілька платформ продовжували розвиток ZFS після Oracle, і функції разом з інструментами розвивалися нерівномірно по OS.
- SLOG став важливим, бо синхронні записи — це контракт; ZIL існує, щоб його задовольнити, а iostat — один з найшвидших способів побачити, чи цей контракт дорогий.
- Спеціальні vdev були введені для обробки метаданих/малих блоків на швидшому носії; це продуктивне золото і операційний борг одночасно.
- Боротьба з ashift відбувалася тому, що диски «брехали» (або їх неправильно розуміли) про фізичні розміри секторів; неправильний ashift може назавжди вплинути на продуктивність.
- «L2ARC вирішує все» — повторювана міфологема з часів перших адміністраторів кешування; він не виправляє затримку записів і може вкрасти пам’ять, яка була потрібна в інших місцях.
Путівник полем: як читати zpool iostat серйозно
Почніть з виводу за замовчуванням, але на цьому не зупиняйтеся
Стандартний вивід zpool iostat — це м’який вступ: операції читання/запису та пропускна здатність по пулу і, опційно, по vdev.
Він підходить, щоб зрозуміти «чи він зайнятий?», але не підходить для питання «чому повільно?», бо вузькі місця зазвичай
про розподіл затримки та один повільний шлях, а не про агреговану пропускну здатність.
Що насправді означають колонки
Імена колонок трохи відрізняються по платформах і версіях OpenZFS, але концепції стабільні:
- r/s, w/s: операції читання/запису в секунду, які ZFS бачить на цьому шарі (пул/vdev/пристрій).
- rkB/s, wkB/s: пропускна здатність читання/запису в кілобайтах за секунду.
- await (коли доступно): середній час I/O, що витрачається на очікування + час обслуговування (черга + пристрій).
- r_await, w_await: та сама ідея, розділена по читаннях/записах (дуже корисно коли синхронні записи кусають).
- sqd (інколи показується): середня глибина черги. Висока черга разом з ростом затримки — класичний сигнал «пристрій насичено».
- util не є зазвичай колонкою ZFS як у Linux
iostat; не імпортуйте семантику Linux автоматично. ZFS має свою власну інструментацію.
Речення, яке економить години
Продуктивність ZFS домінує найповільніший vdev, задіяний в операції, і zpool iostat — найшвидший спосіб визначити, який з них поводиться як найповільніший учасник групового проекту.
Практична модель: куди іде час
Коли додаток каже «запиши це», ZFS перетворює це на танець: транзакційні групи (TXG), copy-on-write (COW),
контрольні суми, опційна компресія, виділення metaslab, і лише потім фактичні I/O на пристрої. Читання — це інша історія:
попадання в ARC, попадання в L2ARC, префетч, реконструкція RAIDZ і, нарешті, диски.
zpool iostat не покаже вам час коміту TXG прямо, але він покаже симптоми:
сплески записів, піки затримки, один vdev, що робить більше роботи ніж інші, або пристрій SLOG, який приймає всю
навантаження синхронних записів.
Якщо потрібна швидка мапа від симптому до «який шар болить», ось відверта версія:
- Високий w_await, низька пропускна здатність: малі записи, синхронні записи, накладні витрати парності RAIDZ або затримка пристрою.
- Високий rkB/s, помірний r/s, зростаючий r_await: великі читання, що насичують пропускну здатність.
- Високий r/s, низький rkB/s, високий r_await: випадкові читання, погане кешування або конкуренція за метадані.
- Один топ-рівневий vdev на максимумі: нерівномірне розподілення, один vdev менший/заповнений або фактичний проблемний пристрій.
Одна цитата, яку варто тримати на стіні:
Надія — не стратегія.
— Jim Lovell
Практичні завдання: команди, виводи, рішення (12+)
Це те, що ви реально робите о 02:17, коли хтось каже «сховище повільне». Кожне завдання має: команду,
що ви дивитесь, і рішення, яке воно підтримає. Виконуйте їх по порядку, якщо ви новачок; перескакуйте, якщо маєте підозру і сліди від попередніх інцидентів.
Завдання 1: Отримайте рухливу картинку, а не знімок
cr0x@server:~$ zpool iostat -v 1 5
capacity operations bandwidth
pool alloc free read write read write
---------- ----- ----- ----- ----- ----- -----
tank 3.12T 2.88T 420 310 42.1M 18.7M
mirror 1.56T 1.44T 210 155 21.0M 9.4M
sda - - 110 78 10.4M 4.9M
sdb - - 100 77 10.6M 4.5M
mirror 1.56T 1.44T 210 155 21.1M 9.3M
sdc - - 105 77 10.5M 4.6M
sdd - - 105 78 10.6M 4.7M
Значення: Ви отримуєте п’ять односекундних зразків з деталізацією vdev та дисків. Шукайте дисбаланс
(один диск або дзеркало робить значно більше), і форму навантаження: велика пропускна здатність проти великої кількості операцій.
Рішення: Якщо один пристрій постійно відстає від партнера в дзеркалі, підозрюйте стан пристрою,
кабелі, проблеми контролера або шляхів. Якщо обидві сторони схожі, але затримка пулу погана, шукайте проблему в навантаженні або конфігурації.
Завдання 2: Увімкніть перегляд затримки (якщо підтримується)
cr0x@server:~$ zpool iostat -v -l 1 5
capacity operations bandwidth total_wait
pool alloc free read write read write read write
-------------------------- ----- ----- ----- ----- ----- ----- ----- -----
tank 3.12T 2.88T 430 320 43.2M 19.1M 4ms 28ms
mirror 1.56T 1.44T 215 160 21.5M 9.6M 3ms 26ms
sda - - 112 81 10.7M 5.0M 3ms 25ms
sdb - - 103 79 10.8M 4.6M 3ms 28ms
mirror 1.56T 1.44T 215 160 21.7M 9.5M 4ms 31ms
sdc - - 109 80 10.8M 4.8M 4ms 32ms
sdd - - 106 80 10.9M 4.7M 4ms 30ms
Значення: «total_wait» (або подібне) — це ваш швидкий і простий сигнал затримки.
Тут записи значно повільніші за читання, і вони повільні скрізь, а не лише на одному диску.
Рішення: Якщо час очікування записів високий по всіх vdev, запитайте: синхронні записи? парність RAIDZ?
повільний SLOG? TXG-стагнація? Якщо тільки один vdev/диск, ставтеся до цього як до проблеми апаратури/шляху, поки не доведено інше.
Завдання 3: Звузьте до підозрілих пулів, якщо у вас кілька пулів
cr0x@server:~$ zpool iostat -v tank 1 3
capacity operations bandwidth
pool alloc free read write read write
---------- ----- ----- ----- ----- ----- -----
tank 3.12T 2.88T 440 330 44.1M 19.8M
mirror 1.56T 1.44T 220 165 22.0M 9.9M
sda - - 112 83 10.8M 5.1M
sdb - - 108 82 11.2M 4.8M
mirror 1.56T 1.44T 220 165 22.1M 9.9M
sdc - - 110 82 11.0M 4.9M
sdd - - 110 83 11.1M 5.0M
Значення: Уникайте шуму з різних пулів. Особливо на машинах з кількома орендарями, ваш «повільний додаток»
може бути не єдиним джерелом I/O.
Рішення: Якщо зайнятий пул не є тим, що обслуговує скаргу, не налаштовуйте сховище;
налаштовуйте очікування і досліджуйте конкуренцію за ресурси в інших місцях (або питання білінгу).
Завдання 4: Підтвердіть стан пулу перед тим, як переслідувати привиди продуктивності
cr0x@server:~$ zpool status -v tank
pool: tank
state: ONLINE
scan: scrub repaired 0B in 06:41:12 with 0 errors on Mon Dec 23 03:12:01 2025
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror ONLINE 0 0 0
sda ONLINE 0 0 0
sdb ONLINE 0 0 0
mirror ONLINE 0 0 0
sdc ONLINE 0 0 0
sdd ONLINE 0 0 0
errors: No known data errors
Значення: Якщо ви бачите зростаючі READ/WRITE/CKSUM помилки, «проблеми» продуктивності можуть бути через
повторні спроби, ремапінг і страждання системи. ZFS збереже цілісність даних, а ваша затримка стане гострішою.
Рішення: Будь-які ненульові, що зростають лічильники помилок: припиніть оптимізувати.
Почніть замінювати апаратуру, перевіряти кабелі/HBA і переглядати SMART-дані.
Завдання 5: Перевірте, чи scrub або resilver не «з’їдає» ваші ресурси
cr0x@server:~$ zpool status tank
pool: tank
state: ONLINE
scan: scrub in progress since Tue Dec 24 11:02:09 2025
1.43T scanned at 1.21G/s, 820G issued at 694M/s, 3.12T total
0B repaired, 26.18% done, 00:52:14 to go
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror ONLINE 0 0 0
sda ONLINE 0 0 0
sdb ONLINE 0 0 0
mirror ONLINE 0 0 0
sdc ONLINE 0 0 0
sdd ONLINE 0 0 0
errors: No known data errors
Значення: Scrub — це легітимний споживач I/O. Він також хороша гігієна.
Але під час піку він може проштовхнути вже щільну затримку через край.
Рішення: Якщо система чутлива до затримок, плануйте scrubs поза піковими годинами і/або налаштуйте пріоритет scrub.
Якщо ви не можете терпіти scrubs — ви не можете терпіти експлуатацію сховища.
Завдання 6: Дізнайтеся, чи ви обмежені IOPS чи пропускною здатністю
cr0x@server:~$ zpool iostat -v 2 3
capacity operations bandwidth
pool alloc free read write read write
---------- ----- ----- ----- ----- ----- -----
tank 3.12T 2.88T 4200 180 32.1M 6.2M
mirror 1.56T 1.44T 2100 90 16.0M 3.1M
sda - - 1050 45 8.0M 1.6M
sdb - - 1050 45 8.0M 1.5M
mirror 1.56T 1.44T 2100 90 16.1M 3.1M
sdc - - 1050 45 8.1M 1.6M
sdd - - 1050 45 8.0M 1.5M
Значення: 4200 читань/сек, але лише 32 MB/s: це малі блоки випадкового I/O. Якщо затримка висока,
додавання більше шпинделів (більше vdev) допоможе більше ніж «швидші диски» самі по собі.
Рішення: Робочі навантаження, обмежені IOPS, хочуть дзеркал, більше vdev і адекватних recordsize; навантаження, що потребують пропускної здатності, хочуть послідовного розташування, менше парних штрафів та часто більших блоків.
Завдання 7: Перевірте, чи синхронні записи — лиходій
cr0x@server:~$ zfs get -o name,property,value,source sync tank/db
NAME PROPERTY VALUE SOURCE
tank/db sync standard local
Значення: sync=standard означає, що синхронні записи виконуються, коли додатки запитують їх.
Бази даних часто це роблять.
Рішення: Якщо затримка записів жахлива і ви бачите багато синхронних записів, ваш SLOG (якщо є) має бути
швидким і з захистом від втрати живлення. Якщо ви «виправляєте» це, встановивши sync=disabled, будьте чесні і назвіть це
«вибором втрати даних як функції».
Завдання 8: Перевірте наявність SLOG та чи він справді використовується
cr0x@server:~$ zpool status tank
pool: tank
state: ONLINE
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror ONLINE 0 0 0
sda ONLINE 0 0 0
sdb ONLINE 0 0 0
mirror ONLINE 0 0 0
sdc ONLINE 0 0 0
sdd ONLINE 0 0 0
logs
nvme0n1 ONLINE 0 0 0
errors: No known data errors
Значення: Є окремий лог-пристрій. Це SLOG (separate intent log).
Він прискорює лише синхронні записи, а не звичайні асинхронні записи.
Рішення: Якщо у вас немає синхронно-важких навантажень, SLOG не допоможе і може ускладнити домени відмов.
Якщо є — SLOG має бути з низькою затримкою і з захистом від втрати живлення.
Завдання 9: Слідкуйте за лог-пристроєм під навантаженням (чи піки на ньому?)
cr0x@server:~$ zpool iostat -v 1 5
capacity operations bandwidth
pool alloc free read write read write
---------- ----- ----- ----- ----- ----- -----
tank 3.12T 2.88T 120 1800 3.1M 22.4M
mirror 1.56T 1.44T 60 900 1.5M 11.1M
sda - - 30 450 760K 5.5M
sdb - - 30 450 740K 5.6M
mirror 1.56T 1.44T 60 900 1.6M 11.3M
sdc - - 30 450 780K 5.7M
sdd - - 30 450 820K 5.6M
logs
nvme0n1 - - 0 5200 0 41.6M
Значення: Великі операції запису на nvme0n1 під «logs» сильно вказують, що синхронні записи
фіксуються в SLOG. Якщо пул має високе write wait і лог-пристрій показує багато операцій, у вас навантаження, що домінують синхронні записи.
Рішення: Якщо операції лог-пристрою високі і затримка велика — оновіть/замініть SLOG, перевірте PLP, і переконайтеся, що ви не використовуєте дешевий споживчий NVMe, який «перетворюється на гарбуза» при стійких синхронних записах.
Завдання 10: Перевірте recordsize датасету та невідповідність робочого навантаження
cr0x@server:~$ zfs get -o name,property,value,source recordsize tank/db
NAME PROPERTY VALUE SOURCE
tank/db recordsize 128K default
Значення: Багато баз даних віддають перевагу меншим блокам (наприклад, 8K–16K), щоб не читати/писати зайвих даних.
128K recordsize все ще може працювати, але для випадкових навантажень воно може посилювати I/O.
Рішення: Якщо ваш iostat показує високі IOPS з малою пропускною здатністю (малий випадковий I/O), розгляньте встановлення
recordsize ближче до розміру сторінки БД (після підтвердження рекомендацій конкретної БД).
Завдання 11: Перевірте компресію (вона може зменшити I/O або витратити CPU)
cr0x@server:~$ zfs get -o name,property,value,source compression tank/db
NAME PROPERTY VALUE SOURCE
tank/db compression lz4 local
Значення: lz4 зазвичай виграш: менше даних записано, менше читається з диска, часто швидше.
Але на системах з навантаженим CPU або вже стиснених даних це може бути нейтрально або трохи гірше.
Рішення: Якщо iostat показує насичення диска, а CPU має вільні ресурси, компресія — ваш друг.
Якщо CPU завантажений, а диск простає, не «оптимізуйте сховище» більшою компресією.
Завдання 12: Перевірте ashift (вирівнювання), бо це назавжди
cr0x@server:~$ zdb -C tank | grep -E 'ashift|vdev_tree' -n | head
118: vdev_tree:
134: ashift: 12
Значення: ashift=12 означає 4K сектори. Якщо пул створено з ashift=9 на 4K дисках,
малі записи можуть перетворитися на кошмари read-modify-write.
Рішення: Неправильний ashift — це помилка, що вимагає перебирання. Якщо він неправильний і продуктивність важлива, плануйте міграцію.
Немає магічної «фішки», що безпечно перепише геометрію пулу на місці.
Завдання 13: Виявіть нерівномірне заповнення vdev (упередженість розподілу)
cr0x@server:~$ zpool list -v tank
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH
tank 6.00T 3.12T 2.88T - - 19% 52% 1.00x ONLINE
mirror 3.00T 2.40T 600G - - 28% 80% - ONLINE
mirror 3.00T 720G 2.30T - - 8% 24% - ONLINE
Значення: Одне дзеркало заповнене на 80% і більш фрагментоване; інше — на 24%. ZFS намагається збалансувати,
але історія пулу, розширення і поведінка metaslab можуть призвести до перекосу. Перекіс може зробити один vdev «гарячою точкою».
Рішення: Якщо iostat показує, що заповнений vdev робить більше роботи або має більшу затримку, стратегія ребалансування важлива:
розгляньте додавання vdev раніше, тримайте пули нижче агресивних порогів заповнення і уникайте «додати пізніше» як стратегії продуктивності.
Завдання 14: Скорелюйте ZFS iostat з OS-метриками пристроїв
cr0x@server:~$ iostat -x 1 3
Linux 6.6.0 (server) 12/25/2025 _x86_64_ (32 CPU)
Device r/s w/s rkB/s wkB/s await aqu-sz %util
sda 110.2 81.4 10960.0 5092.0 4.2 0.8 42.1
sdb 105.9 79.6 11010.0 4780.0 4.0 0.7 41.7
sdc 109.8 80.2 11030.0 4960.0 4.6 1.0 44.9
sdd 108.8 80.7 11080.0 5030.0 4.4 0.9 44.1
nvme0n1 0.0 5200.3 0.0 41600.0 0.3 0.6 62.0
Значення: ZFS бачить логічну роботу; ОС бачить фактичні черги пристроїв і їх завантаження.
Якщо ZFS каже, що диск зайнятий, а ОС каже, що він простягає — можливо, ви обмежені вище пристрою (локи, CPU, TXG).
Якщо ОС показує високий await і високий %util — пристрій дійсно обмежує.
Рішення: Використовуйте OS iostat, щоб підтвердити, чи проблема в «плануванні ZFS», чи в «пристрої, який не встигає».
Це рятує від заміни дисків, коли потрібно налаштувати синхронні записи, або навпаки.
Завдання 15: Перевірте тиск на ARC та запас пам’яті (бо читання брешуть)
cr0x@server:~$ arcstat 1 3
time read miss miss% dmis dm% pmis pm% mmis mm% arcsz c
12:10:01 8420 1120 13 620 55 410 36 90 8 58G 64G
12:10:02 9010 1460 16 780 53 590 40 90 6 58G 64G
12:10:03 8770 1310 14 700 53 520 40 90 7 58G 64G
Значення: Рівень пропусків 13–16% може бути нормальним або жахливим залежно від навантаження.
Якщо пропуски стрибають і диски загоряються в zpool iostat, «затримка сховища» може бути просто тим, що кеш працює як задумано.
Рішення: Якщо ARC обмежений і відсоток пропусків високий, додавайте RAM перед купівлею дисків.
Якщо ARC великий, але пропуски все одно високі, ваш робочий набір більший за пам’ять або ви виконуєте потокові читання, які погано кешуються.
Жарт №1: Якщо довго дивитись на iostat, перші не моргають числа. Можете моргнути ви.
Швидкий плейбук діагностики
Коли потрібно швидко знайти вузьке місце, виконайте це в порядку. Мета не ідеальне розуміння; мета — правильне перше виправлення
і чіткий таймлайн інциденту.
По-перше: чи це проблема стану, яка маскується під проблему продуктивності?
- Запустіть
zpool status -v. Шукайте помилки, деградування vdev, повільний resilver або пристрій, що «флапає». - Запустіть метрики на рівні ОС (
iostat -x), щоб побачити, чи один пристрій страждає.
Якщо ви бачите помилки або ресети: зупиніться. Замініть/виправте шлях. Налаштування продуктивності на хворому обладнанні — це як налаштовувати гоночний автомобіль, поки колесо відвалюється.
По-друге: визначте обсяг і форму I/O
zpool iostat -v 1 5: який пул, який vdev, який пристрій найгарячіший?- Подивіться на IOPS проти пропускної здатності: багато операцій з малою пропускною здатністю кричить про випадковий/малий I/O.
- Якщо доступно, додайте
-lдля підказок по wait/latency: читання в порядку, а от записи жахливі?
По-третє: вирішіть, чи вузьке місце — синхронні записи, парність RAIDZ чи заповненість/фрагментація
- Перевірте
zfs get syncна уражених датасетах. - Перевірте на SLOG у
zpool status, потім спостерігайте статистику лог-vdev вzpool iostat -v. - Перевірте
zpool list -vна нерівномірне заповнення vdev і підказки щодо фрагментації.
По-четверте: валідуйте одним перехресним метриком
- Використайте
iostat -x, щоб підтвердити фактичну поведінку черги/await на пристрої. - Використайте
arcstat(або еквівалент платформи) щоб виключити або підтвердити кешування як причину завантаження дисків.
Наприкінці цього плейбуку ви маєте змогу чесно сказати одну з цих фраз:
«Ми насичені по випадкових читаннях IOPS», «Синхронні записи обмежені лог-пристроєм», «Один vdev перевантажений»,
«Ми платимо податок фрагментації/заповнення», або «Пристрій/шлях відмовляє і повторює спроби».
Три корпоратні міні-історії з передової
Інцидент через неправильне припущення: «Це дзеркально, отже швидко»
Середня SaaS-компанія мігрувала клієнтський PostgreSQL-кластер на новий сервер зі сховищем під ZFS.
Пул був збудований з кількох дзеркал. Чисто, просто, заспокійливо. Усі спали краще.
Через тижні під час пікового трафіку почали з’являтися сплески затримки. Графіки були бісучі: CPU не завантажений, мережа в нормі.
On-call запустив zpool iostat -v і побачив, що одне дзеркало показує помітно вищий write wait, ніж інше.
Припущення було миттєвим: «ZFS має балансувати між дзеркалами; дзеркало не може бути вузьким місцем, воно резервне.»
Вони почали шукати в інших місцях.
Справжня проблема була в нерівномірному заповненні vdev, спричиненому попереднім робочим процесом розширення. Одне дзеркало було значно заповнене й більш фрагментоване.
Це дзеркало стало «гарячою точкою» алокації — воно виконувало більше роботи, ставало повільнішим, і пул здавався повільнішим.
Вивід zpool list -v все це намагався сказати увесь час.
Виправлення було не екзотичним: вони переглянули пороги ємності, змінили план розширення, щоб додавати повні vdev раніше, і мігрували
дані в свіжо збудований пул з однаковими розмірами vdev. Найбільша зміна була культурна: «дзеркала» — це не «одна одиниця».
У ZFS суттєві vdev.
Оптимізація, що відкотилася: «Вимкнути sync, відправити»
Команда платформи даних мала канал ingesiton, що писав багато дрібних транзакцій. Під час тесту навантаження затримка записів здавалась поганою.
Хтось знайшов zfs set sync=disabled і швидко прогнав бенчмарк. Затримка впала. Пропускна здатність зросла.
Запит на зміну було готово.
У продакшені перші тижні були чудові. Потім подія з харчуванням в стійці. Сервери перезавантажились. Пайплайн перезапустився чисто.
І через кілька годин з’явилася тиха неконсистентність даних: downstream завдання побачили дублювання і зниклі записи. Команда витратила дні,
«відлагоджуючи Kafka», потім «відлагоджуючи базу даних», і врешті-решт простежила це до підтверджених записів, які ніколи не дійшли на диск.
Ретроспектива була незручною, бо ніхто «не зробив неправильно» в своїй локальній рамці.
Бенчмарк був реальний. Поліпшення було реальним. Навантаження було реальним.
Помилка була в тому, що контракт на міцність даних трактували як налаштування.
Виправлення не було «ніколи чіпати sync». Це було «побудувати правильний шлях запису». Вони додали належний SLOG-пристрій із захистом від втрати живлення,
перевірили його під навантаженням через статистику zpool iostat для logs, і залишили sync=standard.
Продуктивність покращилася, і всі стали спати краще.
Нудна, але правильна практика, що врятувала день: базове зняття показників
Внутрішня платформа використала ZFS на флоті хостів віртуалізації. У них була політика, яка нікого не заводила:
захоплювати 60-секундний зразок zpool iostat -v -l 1 під час «звичних» годин кожного тижня і зберігати його з метаданими хоста.
Без панелей, без пафосу — просто текстові файли з часовими мітками. Те, що ви випадково видаляєте під час весняного прибирання.
Одного дня надійшли скарги на затримки VM. Хости зовні виглядали «в порядку». Пул не був заповнений.
Не було помилок. Та в UI гіпервізора були періодичні затримки.
On-call порівняв поточний зразок iostat з базовим і побачив різницю відразу: write wait подвоївся при тих же IOPS.
Це було не «більше навантаження». Це було «така ж навантаження, але повільніший час обслуговування».
Це звузило пошук до «щось змінилося в I/O-шляху», а не «хтось додав орендарів».
Винуватею виявився апдейт прошивки HBA, який змінив поведінку черг під змішаним навантаженням читань/записів.
Вони відкотили прошивку на постраждалих хостах, підтвердили, що затримка повернулась до бази, і потім працювали з вендором над виправленням.
Нудні базові знімки врятували їх від тижня переслідування привидів і кидання відповідальності.
Жарт №2: Затримка сховища — як корпоративні погодження: ніхто не помічає, поки раптом не стає проблемою для всіх.
Поширені помилки: симптом → корінна причина → виправлення
1) «IOPS пулу високі, отже диски повільні»
- Симптом: Високий r/s або w/s в
zpool iostat; затримка додатка зростає. - Корінна причина: Навантаження змінилося на менші I/O або більш випадкове; агрегована пропускна здатність може бути помірною.
- Виправлення: Перевірте розмір I/O (IOPS проти MB/s), налаштуйте
recordsizeдатасету, додайте vdev (більше шпинделів/дзеркал), або перемістіть «гарячі» дані на SSD/спеціальний vdev.
2) «Один диск у дзеркалі робить менше, отже все гаразд»
- Симптом: В дзеркалі один диск показує менше операцій і/або вищий wait.
- Корінна причина: Пристрій повільний, виконує повтори, має проблему шляху або контролер обмежує його.
- Виправлення: Перевірте лічильники
zpool status, журнали ОС, SMART, перепідключіть/замініть кабелі, перемістіть диск на інший порт/HBA, замініть пристрій при потребі.
3) «Ми додали SLOG; записи все ще повільні; SLOG марний»
- Симптом: SLOG є; затримка записів залишається високою.
- Корінна причина: Навантаження не синхронне, або SLOG повільний/споживчого класу, або sync виключений/увімкнений неочікувано.
- Виправлення: Підтвердіть поведінку sync (
zfs get sync), спостерігайте активність «logs» vdev вzpool iostat -v, використовуйте низьколатентний пристрій з PLP, і не очікуйте, що SLOG прискорює асинхронні записи.
4) «RAIDZ має бути в порядку; це як апаратний RAID»
- Симптом: Малі випадкові записи мають високий wait; пропускна здатність низька; CPU в нормі.
- Корінна причина: Накладні витрати парності RAIDZ і поведінка read-modify-write на малих оновленнях.
- Виправлення: Використовуйте дзеркала для навантажень, чутливих до IOPS, або змініть розміри блоків/робоче навантаження, або додайте більше vdev, або ізолюйте навантаження випадкових записів в дзеркальні/SSD пули.
5) «Затримка висока, отже пул перевантажений»
- Симптом: Високий total_wait; додаток гальмує; але %util пристрою не високий.
- Корінна причина: Вузьке місце може бути вище дисків: TXG sync, конкуренція CPU, тиск пам’яті або конкурентні локи.
- Виправлення: Перевірте OS
iostat -x, спостерігайте поведінку ARC, перевірте CPU steal/interrupts, і шукайте TXG-стагнацію через системні логи і ZFS-налаштування (платформно-залежні).
6) «Продуктивність погіршилась після включення special vdev; ZFS зламався»
- Симптом: Читання стали імпульсними; операції з метаданими гальмують.
- Корінна причина: Special vdev замалий, насичений або на пристрої з поганою консистентністю затримки; також концентрація метаданих збільшує залежність від цього пристрою.
- Виправлення: Переконайтеся, що special vdev має достатню ємність і редундантність, моніторьте його як критичний шар, і не використовуйте один дешевий пристрій як метадані-опору.
7) «Ми лише на 80% заповнені; ємність не може впливати на продуктивність»
- Симптом: Затримка поступово зростає при заповненні пулу; розподіл стає нерівномірним; фрагментація зростає.
- Корінна причина: Вільний простір стає важче виділяти ефективно; росте фрагментація metaslab; деякі vdev стають гарячішими.
- Виправлення: Тримайте пули комфортно нижче «високих» меж для вашого навантаження, додавайте vdev раніше і уникайте розширень в останній момент під час піку навантаження.
Чеклісти / покроковий план
Покроково: від «повільно» до «вузьке місце» за 15 хвилин
-
Підтвердіть пул і датасет, що задіяні.
Перевірте точки монтування/томи і зіставте їх з пулами. Не діагностуйте на невірній машині. -
Спочатку перевірте стан.
Запустітьzpool status -v. Є помилки, деградовані пристрої, resilver або scrubs? Трактуйте це як пріоритет. -
Зніміть короткий iostat.
Запустітьzpool iostat -v 1 10(і-l, якщо доступно). Збережіть його. Інциденти без артефактів стають аргументами. -
Класифікуйте форму навантаження.
IOPS-важке (високі операції, низький MB/s) проти bandwidth-важкого (помірні операції, високий MB/s). Вирішіть, який тип обладнання допоможе. -
Визначте гарячий vdev.
Якщо один vdev гарячіший, запитайте «чому»: перекіс заповнення, інший тип диску, інший шлях, помилки або насичення лог/спеціального пристрою. -
Перевірте поведінку sync.
Запустітьzfs get syncна датасетах. Якщо синхронно-важке, підтвердіть SLOG і його поведінку в iostat. -
Перехресна перевірка на рівні ОС.
Запустітьiostat -x 1 5. Підтвердіть чергу/await пристрою. Якщо пристрої простіють — припиніть звинувачувати диски. -
Визначте перше безпечне пом’якшення.
Приклади: призупинити/перепланувати scrub, перемістити навантаження, обмежити швидкість батч-завдання, додати лог-пристрій, додати vdev або мігрувати датасет.
Чекліст: що зафіксувати для постмортему
- Принаймні 60 секунд зразків
zpool iostat -v, плюс перегляд затримки якщо доступно. - Вивід
zpool status -vв час інциденту. - Метрики пристроїв ОС (
iostat -x) для кореляції. - Властивості датасету:
sync,recordsize,compression,atime, і будь-яка конфігурація special vdev. - Чи був активний scrub/resilver і його швидкість.
- Чітка заява: IOPS-bound, bandwidth-bound, sync-bound або single-vdev-bound.
Питання та відповіді (FAQ)
1) У чому різниця між zpool iostat і Linux iostat?
zpool iostat показує логічний погляд ZFS по пулу/vdev, включно з віртуальними пристроями як logs та special vdev.
Linux iostat показує поведінку блочних пристроїв (черга, await, utilization). Використовуйте обидва: ZFS для знаходження гарячого vdev,
ОС iostat для підтвердження насичення пристрою або проблем шляху.
2) Чому один vdev стає вузьким місцем, якщо ZFS «розподіляє» дані?
ZFS розподіляє по топ-рівневих vdev. Якщо один vdev більш заповнений, повільніший, помиляється або просто має менше дисків, він може стати обмежувальним фактором.
Агрегатна швидкість пулу підтягнеться до найповільнішого vdev, задіяного в навантаженні.
3) Чи SLOG прискорює всі записи?
Ні. SLOG прискорює синхронні записи (записи, які мають бути гарантовано зафіксовані перед поверненням).
Асинхронні записи буферизуються і комітяться через TXG; SLOG мало змінює той шлях.
4) Чому мої записи повільніші за читання в iostat?
Поширені причини: синхронні записи без хорошого SLOG, накладні парності RAIDZ для малих записів, майже заповнений/фрагментований пул,
або пристрій з непостійною затримкою запису. Якщо читання в порядку, а записи жахливі — перевірте sync і поведінку лог-vdev.
5) Чи високі IOPS завжди погано?
Високі IOPS — це просто характеристика навантаження. Вони стають проблемою, коли затримка зростає або система не виконує SLO.
Правильне питання: чи ми обмежені IOPS (малі випадкові) чи пропускною здатністю (великі послідовні)?
6) Скільки зразків треба робити з zpool iostat?
Для триажу 5–10 секунд з інтервалом в 1 секунду підходить. Для діагностики джітера захопіть принаймні 60 секунд і зніміть те ж саме під «звичними» годинами для порівняння.
Проблеми зі сховищем люблять ховатися у варіативності.
7) Чи може фрагментація пояснити піки затримки?
Може, особливо коли пули заповнюються. Фрагментація зазвичай підвищує середню вартість I/O і збільшує дисперсію.
Якщо ви бачите зростаючі часи очікування при схожих IOPS, і пул наближається до повного — фрагментація/податок за ємність реальний підозрюваний.
8) Який найбезпечніший «швидкий фікс» під час інциденту?
Найбезпечніший — зменшити конкуруючі I/O: призупинити/перепланувати scrub, обмежити швидкість батчів або перемістити гучного орендаря.
Зміна sync або перебудова геометрії пулу не є фіксом під час інциденту, якщо ви не готові взяти на себе ризик.
9) Чому zpool iostat показує низьку пропускну здатність, але додаток каже, що багато пише?
Додатки «пишуть» на логічному рівні; ZFS може стискати, коалесцирувати, відкладати або задовольняти записи через кеш і батчинг TXG.
Фактична пропускна здатність, що потрапляє на диск, — це те, що реально б’є по носі дисків. Якщо додаток пише малі випадкові блоки, пропускна здатність може виглядати низькою, навіть якщо система страждає.
10) Чи довіряти середнім показникам затримки?
Довіряйте їм як підказці, а не вердикту. Середні приховують tail latency, а саме вона важлива для користувачів.
Використовуйте зразки в часі, корелюйте з фазами навантаження і підтверджуйте метриками черг на рівні ОС.
Наступні кроки, які можна зробити сьогодні
Якщо ви експлуатуєте ZFS у продакшені, зробіть ці три речі до того, як наступний інцидент зробить їх за вас:
-
Створіть базову лінію. Захоплюйте щотижневий
zpool iostat -v(і перегляд затримки, якщо доступно) для кожного важливого хоста.
Зберігайте це в нудному, довговічному місці. -
Документуйте ваш контракт запису. Для кожного критичного датасету: чи потрібен sync? Якщо так — який SLOG і як ви його валідуєте під навантаженням?
Якщо ні — чому ні і хто підписався на цей ризик? -
Припиніть ставитись до «заповнений пул» як до події тільки ємності. Визначте ваш поріг продуктивності (часто значно нижче 90%),
і плануйте додавання vdev, поки пул ще комфортний.
Коли ви зможете назвати вузьке місце з доказами — IOPS-bound, bandwidth-bound, sync-bound або single-vdev-bound —
шляхи виправлення стануть прямолінійними. Не завжди дешевими. Але простими. Оце і є домовленість.