Деякі інциденти трапляються гучно й помітно. Проблеми із затримкою читання в ZFS зазвичай — ні. Вони проявляються як «додаток ніби неначе глючить», дашборди виглядають нормально, поки ви не роздивитесь деталі, і як користувачі, що раптом відкривають у собі неймовірне терпіння.
Якщо ви тримаєте продакшн на ZFS і колись дивилися на zpool iostat, дивуючись, чому пропускна здатність здається здоровою, а затримка палає, цей матеріал для вас. Ми будемо користуватися zpool iostat -r як дорослі: вимірювати правильне, швидко ізолювати вузьке місце і вносити зміни, що не породжують ще один інцидент.
Що -r насправді повідомляє (і чого не повідомляє)
zpool iostat — найшвидший тест «чи хворий мій пул?», який не вимагає трасування ядра. Додайте -r — і ви отримаєте затримки читання за інтервал (а залежно від платформи/версії — структурований вигляд затримок, розбитих по стадіях). Це інструмент, до якого ви тягнетеся, коли треба відповісти на питання:
- Чи чергуються запити на читання?
- Пул повільний через диски, чи ми просимо ZFS виконувати дорогі операції?
- Чи тягне один vdev увесь пул вниз?
Неприємна правда: -r не розкриває магічно весь шлях читання через ARC, стиснення, контрольні суми, відновлення RAID-Z, прошивку пристрою, контролер, HBA і назад. Він дає сильні сигнали. Думати доведеться вам.
Що означає «затримка читання» в термінах ZFS
Затримка читання — це час від «запит на читання віддано» до «дані повернено». Але пул бачить це в дуже специфічний спосіб: ZFS вимірює й повідомляє таймінги на рівні пулу/vdev. Це включає черги й час обслуговування в стеку зберігання. Це може не включати час, який ваш процес витратив, очікуючи на CPU, локи чи планувальник перед відправкою I/O.
Чому -r відрізняється від інструментів «дискова затримка»
Інструменти на кшталт iostat -x та sar -d фокусуються на блочних пристроях. Вони чудові, але не розуміють топологію vdev. ZFS — розуміє. Дзеркало поводиться інакше, ніж RAID-Z, а спеціальний vdev змінює шлях читання. zpool iostat -r — найближче до «рідного» ZFS вигляду затримки читання, який ви можете отримати без повного DTrace/eBPF.
Практична модель затримки для пулів ZFS
Якщо ви хочете читати zpool iostat -r як професіонал, вам потрібна ментальна модель, що достатньо проста, щоб працювати під стресом, але достатньо точна, щоб уникнути неправильних рішень.
Затримка зазвичай — одне з чотирьох
- Пеня за промах кеша (ARC/L2ARC не допомагає — читаєте з дисків).
- Черги (пул/vdev насичений; запити чекають своєї черги).
- Час обслуговування (пристрій повільний по кожному I/O: носій, прошивка, контролер, SMR, конкуренція від rebuild/scrub).
- Додаткова робота/ампліфікація (парність RAID-Z, декомпресія, контрольні суми, gang blocks, малі випадкові читання по широких vdev).
Ваше завдання — зрозуміти, що домінує прямо зараз. Не те, що філософськи важливіше. Не те, що гарно виглядає у слайдах.
Затримка читання формується робочим навантаженням
Поведінка читання в ZFS сильно відрізняється залежно від патерну доступу:
- Випадкові читання 4–16K: обмеження по IOPS. Дзеркала блискучі. Широкі RAID-Z vdev можуть відставати.
- Великі послідовні читання: обмеження по пропускній здатності. RAID-Z може виглядати чудово, поки не почне страждати (фрагментація і recordsize важливі).
- Навантаження з великою кількістю метаданих: багато малих читань; спеціальні vdev і вибір recordsize мають велике значення.
- Змішане читання/запис: записи можуть тягнути читання вниз через конкуренцію, особливо під час синхронних операцій і фонового опрацювання.
Знайте свій «добрий» діапазон затримки
Універсальної «доброї» затримки не існує. Але є здорові діапазони:
- NVMe дзеркала: однозначні мілісекунди під навантаженням часто нормальні; суб-мс звичні при невеликому навантаженні.
- SAS/SATA SSD: кілька мс нормальні; десятки мс вказують на черги або бізнес-процеси збору сміття.
- 7200 RPM HDD: 8–15 ms сервісного часу нормальні; 30–100+ ms ймовірно означає черги або конкуренцію з rebuild/scrub.
Ключ — кореляція: затримка з IOPS та пропускною. Висока затримка при низьких IOPS — «пристрій або шлях повільний». Висока затримка тільки при високих IOPS — «щось насичене».
Цитата, яку варто наклеїти на монітор:
«Надія — це не стратегія.» — Gene Kranz
Цікаві факти й історичний контекст (коротко і корисно)
- ZFS був спроектований з end-to-end цілісністю даних (контрольні суми всюди). Ця робота по цілісності може проявлятися як навантаження на CPU при екстремальних швидкостях читання.
- ARC (Adaptive Replacement Cache) замінив просте LRU на щось більш стійке до сканів; це круто для реальних навантажень, але іноді дивує під великими послідовними читаннями.
- RAID-Z зʼявився в великій мірі тому, що «hardware RAID брехав» щодо порядку записів та обробки помилок; ZFS хотів передбачуваної семантики і можливості scrubb’у.
- Scrub не опційний «чисто для обслуговування»; це спосіб ZFS валідувати надлишковість. Але scrubs точно конкурують за I/O на читання і можуть підвищувати затримки.
- ashift — навічно для vdev: оберіть погано (напр., 512-байтні сектора на 4K-дисках) — і ви створите ампліфікацію, що переслідуватиме затримку.
- L2ARC історично мав репутацію «кеша, що їсть RAM», бо його метадані можуть тиснути на ARC; новіші реалізації покращили поведінку, але компроміс реальний.
- Спеціальні vdev (для метаданих/малих блоків) — відносно сучасне доповнення в OpenZFS і можуть драматично змінити затримку читання для навантажень з метаданими — також нове місце для помилок.
- Розширення RAID-Z — новіша можливість; раніше зміна ширини vdev часто означала перебудову пулу, що впливало на дизайн під латентність (дзеркала стали дефолтом).
- Префетч у ZFS еволюціонував; він допомагає при послідовних читаннях, але може зашкодити при невірних передбаченнях, генеруючи зайві I/O і затримки для реальних читань.
Розбір виводу: колонки, одиниці і підводні камені
zpool iostat має кілька режимів виводу, і точні колонки залежать від версії OpenZFS та пакета ОС. Принцип залишається: ви дивитесь статистику за пулом і vdev за інтервал, і з -r отримуєте дані про затримку читання.
Два підводні камені зʼявляються постійно:
- Дивитися тільки на затримку на рівні пулу. Пул — це сума vdev, і один поганий vdev може отруїти досвід.
- Плутати «середню затримку» з «хвостовою затримкою».
zpool iostatбазується на інтервалах і зазвичай дає середні значення. Ваші клієнти живуть у хвості розподілу.
Також: затримка, яку повідомляє ZFS, не завжди збігається з тим, що відчуває додаток. Якщо додаток блокується через CPU або локи, ZFS може виглядати невинним, поки користувачі страждають.
Жарт №1: Затримка — як сміття: можна ігнорувати її деякий час, поки вона не почне приймати рішення замість вас.
Швидкий план діагностики (перший/другий/третій)
Перший: підтвердьте, що це реальна проблема і знайдіть охоплення
- Запустіть
zpool iostat -rз коротким інтервалом, щоб зловити сплески і визначити, який пул/vdev задіяний. - Перевірте, чи виконується фонове опрацювання (scrub, resilver). Якщо так — вирішіть, чи призупиняти/пригальмувати його.
- Перевірте поведінку ARC: якщо у вас промахи кеша, диски будуть зайняті і затримка зросте. Підтвердіть це статистикою ARC.
Другий: вирішіть, це насичення, одиночний винуватець або неправильна конфігурація
- Насичення: затримка росте з IOPS/пропускною і падає, коли навантаження зменшиться. Ймовірно черги або обмеження пристрою.
- Одиночний винуватець: один vdev показує значно вищу затримку читання ніж решта. Підозрівайте диск, шлях, кабелі, прошивку або деградований дзеркальний vdev.
- Неправильна конфігурація: висока ампліфікація читань (малий recordsize на HDD RAID-Z, неправильний ashift, спеціальний vdev майже заповнений, дивні volblocksize) створює постійну затримку при нормальному навантаженні.
Третій: підтвердіть одним додатковим інструментом, не пʼятьма
Виберіть мінімум додаткових інструментів:
iostat -x— щоб перевірити черги й час обслуговування на пристроях.zpool status— щоб підтвердити помилки, деградовані vdev чи фонові операції.arcstatабо еквівалент — щоб підтвердити тренди хіт-рейту кеша.
Якщо треба переходити до трасування — робіть це усвідомлено. Інциденти затримок люблять людей, які метушаться, збираючи «всі дані».
Практичні завдання: команди, що означає вивід і рішення
Це production-рівневі завдання. Кожне містить: виконувану команду, репрезентативний фрагмент виводу, що це означає і що робити далі. Підлаштуйте імена пулів і шляхи пристроїв під вашу систему.
Завдання 1: Отримати базову затримку читання по vdev
cr0x@server:~$ zpool iostat -v -r 1 10
capacity operations bandwidth read latency
pool alloc free read write read write read
-------------------------- ----- ----- ----- ----- ----- ----- -----
tank 2.15T 5.12T 3200 410 210M 18.2M 7ms
mirror-0 1.07T 2.56T 1580 210 104M 9.1M 6ms
sda - - 790 105 52.1M 4.6M 6ms
sdb - - 790 105 52.0M 4.6M 6ms
mirror-1 1.08T 2.56T 1620 200 106M 9.1M 7ms
sdc - - 810 100 53.0M 4.5M 7ms
sdd - - 810 100 53.0M 4.5M 7ms
-------------------------- ----- ----- ----- ----- ----- ----- -----
Значення: Читання пулу розподілене доволі рівномірно по дзеркалах. Затримка послідовна по vdev і дисках. Це виглядає як нормальне навантаження, не як одиночний некоректний диск.
Рішення: Якщо затримка «занадто висока», ймовірно це насичення або невідповідність навантаження — не один повільний диск. Продовжуйте перевірку робочого навантаження і кеша.
Завдання 2: Впіймати короткі сплески затримки, розширивши вікно вибірки
cr0x@server:~$ zpool iostat -v -r 5
capacity operations bandwidth read latency
pool alloc free read write read write read
-------------------------- ----- ----- ----- ----- ----- ----- -----
tank 2.15T 5.12T 900 60 58.0M 2.1M 3ms
tank 2.15T 5.12T 4100 120 260M 6.0M 22ms
tank 2.15T 5.12T 800 55 52.0M 1.8M 4ms
^C
Значення: Другий інтервал показує сплеск: IOPS і пропускна різко зростають, і затримка зростає. Класика — черги при бурсті навантаження.
Рішення: Знайдіть джерело сплеску (завдання резервного копіювання, аналітичний запит, scrub/resilver). Розгляньте обмеження швидкості навантаження або збільшення паралелізму vdev (додавання дзеркал), якщо це тримається довго.
Завдання 3: Підтвердити здоровʼя пулу і фонові операції
cr0x@server:~$ zpool status -v tank
pool: tank
state: ONLINE
status: One or more devices is currently being resilvered.
action: Wait for the resilver to complete.
scan: resilver in progress since Tue Dec 24 10:12:11 2025
1.24T scanned at 820M/s, 410G issued at 270M/s, 1.24T total
0B resilvered, 32.9% done, 1:05:12 to go
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
sda ONLINE 0 0 0
sdb ONLINE 0 0 0
mirror-1 ONLINE 0 0 0
sdc ONLINE 0 0 0
sdd ONLINE 0 0 0
Значення: Resilver — операція, що багато читає, і може підвищувати затримку читання для клієнтів, особливо на HDD.
Рішення: Якщо це інцидент затримок, заплануйте resilver/scrub на периферійний час або налаштуйте швидкість сканування (див. Завдання 10).
Завдання 4: Перевірити затримку та черги на рівні пристрою
cr0x@server:~$ iostat -x 1 3
Linux 6.6.0 (server) 12/25/2025 _x86_64_ (32 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
12.10 0.00 4.60 1.80 0.00 81.50
Device r/s rkB/s rrqm/s %rrqm r_await rareq-sz w/s wkB/s w_await aqu-sz %util
sda 380.0 52000.0 0.0 0.0 6.10 136.8 55.0 4600.0 3.20 2.10 78.0
sdb 379.0 51900.0 0.0 0.0 6.00 136.9 55.0 4600.0 3.10 2.05 77.5
sdc 402.0 53000.0 0.0 0.0 7.20 131.8 50.0 4500.0 3.00 2.40 82.0
sdd 401.0 52900.0 0.0 0.0 7.10 131.9 50.0 4500.0 3.10 2.35 81.5
Значення: Затримка читання на рівні пристрою приблизно відповідає затримці ZFS з попереднього прикладу. Завантаження високе, розмір черги немалий: ви навантажуєте диски.
Рішення: Якщо потрібна нижча затримка — зменшіть навантаження, додайте vdev або перемістіть «гарячі» дані на швидші носії. Не «налаштовуйтеся», щоб обійти фізику.
Завдання 5: Визначити, чи ARC вас рятує або підводить
cr0x@server:~$ arcstat 1 5
time read miss miss% dmis dm% pmis pm% mmis mm% arcsz c
10:44:01 8200 980 12 40 0 920 11 20 0 96.2G 128G
10:44:02 7900 1100 13 38 0 1040 13 22 0 96.2G 128G
10:44:03 8100 4200 51 45 0 4130 51 25 0 96.2G 128G
10:44:04 8300 3900 46 42 0 3830 46 28 0 96.2G 128G
10:44:05 8000 1000 12 40 0 940 12 20 0 96.2G 128G
Значення: Два рядки показують раптовий сплеск промахів. Це часто скан, запит, що трощить кеш, або нове робоче множина, що не вміщується. Сплески промахів сильно корелюють зі сплесками затримки читання.
Рішення: Якщо це запланований скан (бекуп, AV, аналітика) — ізолюйте його або обмежте швидкість. Якщо це нормальний трафік — можливо потрібно більше RAM, краща розкладка датасетів або швидші диски.
Завдання 6: Перевірити властивості датасету, що формують затримку читання
cr0x@server:~$ zfs get -o name,property,value,source recordsize,compression,atime,primarycache,secondarycache tank/app
NAME PROPERTY VALUE SOURCE
tank/app recordsize 128K local
tank/app compression lz4 inherited from tank
tank/app atime off local
tank/app primarycache all default
tank/app secondarycache all default
Значення: recordsize впливає, скільки даних ZFS читає на логічний запит. Для баз даних з випадковими читаннями 128K може створювати зайву ампліфікацію читань. Стиснення може допомогти, зменшуючи фізичні I/O, але коштує CPU.
Рішення: Для OLTP-подібних випадкових читань розгляньте менший recordsize (наприклад, 16K) на рівні окремого датасету. Не міняйте властивість на весь пул без тесту.
Завдання 7: Підтвердити топологію пулу і дисбаланс vdev
cr0x@server:~$ zpool status tank
pool: tank
state: ONLINE
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
raidz2-0 ONLINE 0 0 0
sda ONLINE 0 0 0
sdb ONLINE 0 0 0
sdc ONLINE 0 0 0
sdd ONLINE 0 0 0
sde ONLINE 0 0 0
sdf ONLINE 0 0 0
Значення: Один широкий RAID-Z2 vdev концентрує обмеження IOPS. Випадкова затримка читання зростатиме раніше порівняно з множиною дзеркал або кількома вузькими vdev.
Рішення: Якщо ваше навантаження — випадкові читання і чутливість до латентності — віддавайте перевагу дзеркалам або декільком vdev. RAID-Z підходить для ємності і стрімінгу, але не творить дива для IOPS.
Завдання 8: Виявити повільний диск у дзеркалі
cr0x@server:~$ zpool iostat -v -r 1 5
capacity operations bandwidth read latency
pool alloc free read write read write read
-------------------------- ----- ----- ----- ----- ----- ----- -----
tank 2.15T 5.12T 2400 200 160M 8.0M 18ms
mirror-0 1.07T 2.56T 1200 100 80.0M 4.0M 35ms
sda - - 600 50 40.0M 2.0M 34ms
sdb - - 600 50 40.0M 2.0M 36ms
mirror-1 1.08T 2.56T 1200 100 80.0M 4.0M 2ms
sdc - - 600 50 40.0M 2.0M 2ms
sdd - - 600 50 40.0M 2.0M 2ms
-------------------------- ----- ----- ----- ----- ----- ----- -----
Значення: Mirror-0 значно гірший за mirror-1. Навіть якщо обидва диски в mirror-0 показують схожу затримку, це може бути спільний шлях (SAS expander, порт HBA) або проблема носія.
Рішення: Перевірте апаратний шлях: поміняйте кабелі/порти, перевірте SMART, логи HBA. Якщо підтвердите, що диск повільний — замініть його до того, як він стане «degreaded + slow», найгірше поєднання.
Завдання 9: Перевірити помилки контрольних сум, що провокують дорогі читання
cr0x@server:~$ zpool status -v
pool: tank
state: ONLINE
status: One or more devices has experienced an unrecoverable error.
action: Replace the device or restore the pool from backup.
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
sda ONLINE 0 0 12
sdb ONLINE 0 0 0
errors: Permanent errors have been detected in the following files:
tank/app@autosnap:2025-12-25:00:00:00:/var/lib/app/index.dat
Значення: Помилки контрольних сум можуть спричиняти повторні читання, реконструкцію та повільні операції читання. Навіть якщо пул лишається ONLINE, затримка може сплескувати, коли ZFS мусить працювати більше, щоб повернути коректні дані.
Рішення: Трактуйте помилки контрольних сум як термінові. Замініть сумнівний носій/шлях, зробіть scrub після заміни і перевірте ризик корупції на рівні додатка.
Завдання 10: Керувати впливом scrub/resilver на затримку читання
cr0x@server:~$ cat /sys/module/zfs/parameters/zfs_vdev_scrub_min_active
1
cr0x@server:~$ cat /sys/module/zfs/parameters/zfs_vdev_scrub_max_active
2
Значення: Ці параметри впливають на агресивність I/O для scrub. Вищі значення можуть завершити scrub швидше, але точно підвищать затримку читання в робочий час.
Рішення: На системах чутливих до затримки тримайте агресивність сканів консервативною в піки і плануйте scrubs на непікові години. Якщо ваша платформа має zpool scrub -s, призупинення scrub під час інцидентів — прагматичний крок.
Завдання 11: Перевірити здоровʼя і заповненість special vdev (гарячий шлях метаданих)
cr0x@server:~$ zpool list -v tank
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
tank 7.27T 2.15T 5.12T - - 18% 29% 1.00x ONLINE -
special 894G 770G 124G - - 35% 86% - ONLINE -
mirror-2 894G 770G 124G - - 35% 86% - ONLINE -
nvme0n1 - - - - - - - - ONLINE -
nvme1n1 - - - - - - - - ONLINE -
Значення: Special vdev заповнений на 86%. Саме туди тягнуться інциденти затримки. Коли special заповнюється, поведінка ZFS змінюється і розміщення метаданих може псутися.
Рішення: Тримайте special vdev значно нижче «страшного» заповнення. Якщо він заповнюється — додайте ємності special або обережно відкоригуйте, які блоки можуть потрапляти туди. Підходьте до special vdev як до критичної залежності tier‑0.
Завдання 12: Виявити патологічні читання малими блоками через подання блок-розміру
cr0x@server:~$ zpool iostat -v -r -w 1 3
capacity operations bandwidth read latency
pool alloc free read write read write read
-------------------------- ----- ----- ----- ----- ----- ----- -----
tank 2.15T 5.12T 9000 200 72.0M 6.0M 14ms
mirror-0 1.07T 2.56T 4600 100 36.0M 3.0M 15ms
mirror-1 1.08T 2.56T 4400 100 36.0M 3.0M 13ms
-------------------------- ----- ----- ----- ----- ----- ----- -----
Значення: Високі IOPS з помірною пропускною здатністю означають малі розміри I/O. Це гра на IOPS, а не на throughput.
Рішення: Якщо це HDD‑бекований RAID-Z — готуйтеся до болю. Для SSD/NVMe дзеркал перевірте CPU і шлях метаданих. Розгляньте special vdev для метаданих/малих блоків, якщо це доречно.
Завдання 13: Перевірити ashift, щоб уникнути read-modify ампліфікації
cr0x@server:~$ zdb -C tank | grep -E 'ashift|vdev_path' -n
45: ashift: 12
62: path: '/dev/disk/by-id/ata-SAMSUNG_SSD_870_EVO_2TB_S5...'
88: ashift: 9
105: path: '/dev/disk/by-id/ata-WDC_WD40EFRX-68...'
Значення: Змішані значення ashift можуть зустрічатися по vdev, особливо якщо пул розрісся з часом. ashift: 9 (512B) на 4K‑нативних або емульованих дисках створює додаткову роботу і затримку.
Рішення: Якщо знайдете неправильний ashift на vdev — плануйте ремедіацію: заміну/міграцію vdev, перебудову пулу або прийняття вартості. Немає безпечної in‑place кнопки «перевернути ashift».
Завдання 14: Перевірити, чи ваша «оптимізація» не є префетч‑трешем
cr0x@server:~$ cat /sys/module/zfs/parameters/zfs_prefetch_disable
0
Значення: Prefetch увімкнено. Для послідовних робочих навантажень це допомагає. Для деяких змішаних/випадкових патернів воно може додати марні читання і погіршити затримку.
Рішення: Не вимикайте префетч навмання. Тестуйте на конкретному навантаженні і дивіться zpool iostat -r разом зі статистикою промахів ARC. Якщо вимкнення зменшує затримку читання без втрати пропускної — залишайте його вимкненим для цього хоста.
Три корпоративні міні-історії з фронту затримок
1) Інцидент через неправильне припущення
Команда мала платформу VM на ZFS. Дзеркала на SSD, багато RAM, пристойний HBA. Одного понеділка користувачі скаржились, що консолі VM лагують і деплої тайм‑аутяться. Графіки показували CPU в нормі, мережу — в нормі, а «дискова пропускна здатність» не була катастрофічною. ОНК дивився на zpool iostat і бачив, що пропускна читання комфортно нижче того, що SSD могли витримати. Вони вирішили, що сховище не винне.
Було винне. zpool iostat -v -r показував сплески затримки читання до десятків мілісекунд на короткі інтервали. Нічого тривалого, але достатнього, щоб синхронні операції (напр., читання метаданих під час масових завантажень) падали. Пул мав special vdev для метаданих на парі невеликих NVMe. Один з них тихо кидав помилки носія, ще не деградував повністю дзеркало, але викликав повторні читання й повільні шляхи.
Вони замінили NVMe, запустили scrub — проблема зникла. Пост‑мортем дав просте правило: коли користувачі кажуть «лаг», дивіться на латентність перш за все. Пропускна — це про те, чим хизуються після інциденту.
2) Оптимізація, що відбилася бумерангом
Команда баз даних хотіла швидших читань. Вони увімкнули L2ARC на великому SSD і відсвяткували покращення хіт‑рейту ARC у синтетичному бенчмарку. А потім продакшн став… повільнішим. Не катастрофічно, але хвостові затримки перетворилися з «нервуючих» на «генеруючих тікети».
zpool iostat -r показував сплески затримок у моменти, що співпадали з CPU softirq і памʼятним тиском. Розмір ARC виглядав стабільним, але система витрачала значно більше часу на управління метаданими кеша. L2ARC пристрій був швидкий; хост — зайнятий. У їхньому випадку навантаження мало великий послідовний компонент плюс гарячу множину випадкових блоків. L2ARC часом допомагав, але теж підштовхував більше churn і накладних витрат.
Провал не в L2ARC як такому. Провал у тому, що вони ставились до нього як до безкоштовного приросту швидкості. L2ARC вимагає RAM і CPU, і при певних патернах доступу може додати роботи на прочит в такій мірі, що виграш по I/O відміняється.
Вони відкотили зміни, потім знову ввели L2ARC з меншим розміром і додали RAM на хості. Справжній виграш зʼявився пізніше: перемістили кілька датасетів із великою кількістю метаданих на дзеркальний NVMe special vdev, що знизило латентність малих читань без драм кеш‑churn.
3) Нудна, але правильна практика, що врятувала день
Кластер зберігання проводив nightly scrubs і мав непопулярну політику: вікна scrub фіксовані, і будь‑яка команда, що хотіла запускати важкі пакетні читання, мусила координуватися. Люди нарікали — виглядало бюрократично.
Одного тижня регрес прошивки вдарив по партії дисків. Нічого не вийшло з ладу відразу. Натомість один диск у дзеркалі став довше відповідати під тривалими читаннями. Затримка повільно зростала. Цікаво, що моніторинг мав щотижневий «профіль затримки scrub», бо scrubs були послідовні. Коли диск почав глючити, scrub‑вікно показало чітке відхилення: затримка читання на одному vdev зросла, інші лишались пласкими.
Вони проактивно замінили диск. Жодного простою, жодного деградованого vdev на піку, ніяких «містичних інцидентів продуктивності». Нудна практика — регулярні scrubs у відомому графіку — стала раннім попередженням.
Коли питали, чому не «scrub коли треба», відповідь проста: послідовність створює базові профілі, а бази ловлять повільні відмови. Рандомність породжує фольклор.
Жарт №2: Єдине, що передбачуваніше за відмови дисків — це зустріч, на якій хтось каже: «Але в стейджингу ж працювало».
Поширені помилки: симптом → корінь → виправлення
1) Симптом: сплески затримки читання в робочий час, особливо короткі
Корінь: фонові скани (scrub/resilver) або пакетні завдання, що створюють черги.
Виправлення: плануйте важкі скани на непіковий час, зменшуйте агресивність scrub і обмежуйте швидкість пакетних читачів. Підтвердіть через zpool status і порівняйте zpool iostat -r під час/без завдання.
2) Симптом: один vdev показує значно вищу затримку ніж інші
Корінь: один повільний диск, поганий SAS‑lane, порт HBA або періодичні помилки носія, що викликають повтори.
Виправлення: перевірте через iostat -x, SMART і логи HBA. За можливості поміняйте порти/кабелі; замініть підозрілий диск раніше.
3) Симптом: висока затримка читання при низьких IOPS і низькій пропускній
Корінь: пристрій повільний по кожному I/O (прошивка GC, SMR, відновлення помилок) або затори на рівні ядра.
Виправлення: підтвердіть через iostat -x (r_await високе, %util низько‑середнє), перевірте логи диска, розгляньте заміну класу пристрою. Для HDD-пулів перевірте, чи випадково не потрапили SMR‑диски.
4) Симптом: затримка читання зростає при малих I/O на RAID-Z
Корінь: обмеження IOPS і ампліфікація читань на широких RAID-Z vdev; домінують звертання метаданих.
Виправлення: переробіть архітектуру під дзеркала або додайте vdev для збільшення паралелізму. Для існуючих пулів розгляньте переміщення чутливих датасетів на дзеркальний SSD/NVMe пул.
5) Симптом: після додавання special vdev затримка покращилася, але через місяці погіршилася
Корінь: special vdev заповнився або фрагментувався; метадані/малі блоки змушені повертатися на основні vdev або розміщуються неефективно.
Виправлення: тримайте special vdev значно нижче критичного заповнення, додавайте ємність завчасно й моніторте окремо розподіл спеціальних алокацій. Трактуйте special vdev як production‑критичний.
6) Симптом: сплески затримки після зміни recordsize або volblocksize
Корінь: невідповідність між I/O‑патерном і розміром блоку, що створює ампліфікацію, плюс старі дані не переписані (властивості застосовуються переважно до нових записів).
Виправлення: тестуйте зміни на канарковому датасеті, при потребі перезапишіть дані (міграція/реплікація) і перевіряйте через zpool iostat -r під репрезентативним навантаженням.
7) Симптом: піки затримки виглядають як проблеми зі сховищем, але затримка ZFS нормальна
Корінь: CPU‑конкуренція додатка або хоста, конфлікти локів або затримки планувальника. Сховище — цап‑виновник, бо його легко виміряти.
Виправлення: корелюйте з чергою виконання CPU, vmstat та профілюванням додатка. Не «налаштовуйте ZFS», коли проблема не в ZFS.
Чеклісти / покроковий план
Покроково: коли вам дзвонять через «повільні читання»
- Підтвердіть симптом: це користувацька латентність, таймаути додатка чи уповільнення пакетних задач? Отримайте конкретний приклад і мітку часу.
- Запустіть
zpool iostat -v -r 1 10на ураженому хості. Визначте найгірший пул/vdev. - Перевірте
zpool statusна предмет scrub/resilver, помилок, деградованих vdev. - Перевірте через
iostat -x 1 3, чи пристрої насичені або повільні по I/O. - Перевірте хіт‑рейт ARC (Завдання 5). Якщо промахи стрибнули — знайдіть робоче навантаження, що це спричинило.
- Зробіть найменший безпечний крок:
- призупиніть або відкладіть scrub/resilver, якщо це можливо й доречно,
- обмежте швидкість пакетного читача,
- виґнате явно хворий диск, якщо є сильні докази і надлишковість,
- перемістіть «гарячий» датасет у швидший пул, якщо він доступний.
- Підтвердіть покращення тими ж командами й інтервалом. Не оголошуйте перемогу за відчуттями.
- Запишіть, що бачили: «mirror-0 read latency 35ms while mirror-1 2ms» — золото для подальшого аналізу.
Чекліст: вибір архітектури, що запобігає інцидентам затримки читання
- Обирайте топологію vdev згідно з потребами IOPS (дзеркала для випадкових читань; RAID-Z для ємності/стрімінгу).
- Встановлюйте
ashiftправильно під час створення. - Тюньте на рівні датасетів (
recordsize,atime, compression) замість глобальних «героїчних» змін. - Тримайте special vdev здоровими, у дзеркалі й далеко від повного заповнення.
- Плануйте scrubs послідовно і зберігайте базові профілі.
- Моніторьте затримку, а не тільки пропускну здатність і вільне місце.
Чекліст: чого не робити під час інциденту затримки
- Не змінюйте одночасно пʼять параметрів. Ви не знатимете, що допомогло.
- Не «фіксуйте» затримку відключенням контрольних сум чи функцій цілісності. Це не інженерія — це заперечення.
- Не вважайте, що швидкий SSD‑пул не може створити проблеми. NVMe теж може накопичувати черги.
- Не ігноруйте одиночний vdev‑аутлайер. Пул швидкий лише настільки, наскільки швидкий його найповільніший критичний шлях.
FAQ
1) Що саме вимірює zpool iostat -r?
Він повідомляє затримку читання, спостережувану на рівні пулу/vdev за кожний інтервал вибірки. Думайте «час, щоб задовольнити читання, яке бачить ZFS», включаючи черги й сервісний час пристрою.
2) Чому мій додаток повільний, коли zpool iostat -r виглядає нормально?
Бо сховище не завжди є вузьким місцем. Затримки можуть спричиняти планування CPU, конфлікти локів, мережа або серіалізація додатка. Корелюйте з системними і аплікаційними метриками.
3) Чому затримка зростає під час scrubs, якщо scrubs — «лише читання»?
Scrub конкурує за ту ж пропускну та IOPS, що і клієнти, і може збільшувати рух голівок на HDD. Навіть на SSD він додає черги і знижує ефективність кеша.
4) Чи може L2ARC зменшити затримку читання?
Так — коли робоче множина стабільне і вміщується, і хост має RAM/CPU для управління ним. Але L2ARC може дати зворотний ефект через накладні витрати і churn. Міряйте до і після.
5) Чи RAID-Z завжди гірший за дзеркала для затримки читання?
Для малих випадкових читань зазвичай так: дзеркала масштабують IOPS з кількістю vdev і мають простішу реконструкцію. Для великих послідовних читань RAID-Z часто відмінний. Підбирайте топологію під навантаження.
6) Моя затримка читання висока, але диски показують низький %util. Чому?
Можливі причини: вузьке місце вище дисків (CPU, чексуми/декомпресія, конкуренція), вікно вимірювання приховує сплески, або пристрій повільний по кожному I/O без явної «зайнятості». Використайте коротші інтервали і перехресну перевірку.
7) Який найшвидший спосіб ідентифікувати «поведінку одного поганого диска»?
Порівняйте затримки по vdev через zpool iostat -v -r, а потім перевірте середні часи очікування по пристрою через iostat -x. Якщо один шлях систематично гірший — починайте розкопки з нього.
8) Чи змінить recordsize затримку читання для існуючих даних?
Не безпосередньо. recordsize впливає на те, як нові дані розкладаються. Існуючі блоки зберігають стару структуру, поки їх не перезаписати (міграція/реплікація).
9) Чи варто вимикати prefetch, щоб зменшити затримку читання?
Іноді. Prefetch допомагає послідовним навантаженням і може зашкодити при помилкових передбаченнях. Не копіюйте бездумно: тестуйте на реальному навантаженні і дивіться затримку разом з промахами ARC.
10) Яке значення затримки повинно викликати виклик на пейджинг?
Встановлюйте пороги відносно вашої базової лінії і робочого навантаження. Краще правило: пейджити при стійкому відхиленні (наприклад, 3–5× бази протягом кількох хвилин) плюс вплив на користувачів, а не через одиночний сплеск.
Висновок: наступні кроки, які ви дійсно можете виконати
Якщо ви хочете стати вправним у роботі із затримками ZFS — перестаньте ставитися до них як до містичної властивості дисків. Це вимірюваний результат топології, навантаження, поведінки кеша і фонового опрацювання. zpool iostat -r дає найправдивішу картину, якщо ви ставите правильні питання.
Зробіть наступне:
- Запустіть
zpool iostat -v -r 1 10під нормальним навантаженням і збережіть вивід як базу. - Плануйте scrubs послідовно й записуйте профілі затримки, щоб виявляти повільні відмови рано.
- Визначте свої 2–3 найчутливіші до затримки датасети і перевірте їх властивості (
recordsize, compression, eligibility для special vdev). - Вирішіть, чи топологія пулу відповідає навантаженню. Якщо ні — прийміть, що реальне виправлення архітектурне, а не налаштування.
Затримка не цікавиться вашими намірами. Виміряйте її, поважайте — і зазвичай вона поводиться. Зазвичай.