Ваші користувачі не скаржаться на низьку пропускну спроможність. Вони скаржаться, що іноді все зависає:
логіни затягуються, запити тайм-аутяться, резервні копії «замерзають», а панель показує p99-затримки, що нагадують кардіограму.
У світі ZFS це часто не «пул повільний». Це «один диск має поганий день — і запрошує всіх».
zpool iostat -v — це інструмент, щоб спіймати цей диск на гарячому. Не після факту. Не «може SMART щось казав минулого тижня».
Прямо зараз — поки затримки уроджені — ви можете ізолювати підозрюваного, довести це цифрами і вирішити, офлайнити його, замінити,
або припинити звинувачувати ZFS за те, що насправді апаратна проблема у костюмі софту.
Ментальна модель: продуктивність ZFS залежить від vdev, а не від пулу
Почніть звідси, бо це змінює спосіб читання кожного графіка й кожного оновлення по інциденту.
Пул ZFS — це колекція vdev. Дані шардуються між vdev, але кожен блок живе на конкретному vdev.
Якщо один vdev уповільнюється, будь-яке навантаження, яке читає блоки з цього vdev, страждає.
Якщо vdev — це дзеркало і одна сторона повільна, ZFS інколи може спрямовувати читання в інший бік — аж поки не зможе (або поки йдуть записи,
або тривісний ресилвер, або ваше навантаження інтенсивно синхронне).
Є ще більш неприємна правда: ZFS дуже добре перетворює невеликі, періодичні прикрості пристрою на хвостову латентність усього кластера.
Воно робить це тому, що ZFS — консистентний: чекає на сховище, до якого звернувся. Вашій аплікації байдуже, що 99.9% операцій ОК;
вона запам’ятовує ті 0.1%, які тривали 2 секунди, бо один диск вирішив виконати внутрішній фоновий процес у найгірший момент.
Тому мета zpool iostat -v — не «виміряти пул». Це «знайти vdev або диск з історією, відмінною від інших».
Ви не полюєте за низькими середніми значеннями. Ви шукаєте викиди, спайки, зростання черги та асиметрію.
Короткі факти та історія, що реально допомагають дебагу
- ZFS побудовано навколо end-to-end контрольних сум. Це чудово для цілісності, але також означає, що ZFS голосно виявляє проблемні пристрої, повторюючи операції, лікуючи дані та логуючи помилки замість того, щоб мовчки повертати бите.
- RAIDZ — це не «апаратний RAID у софті». Математика паритету RAIDZ і поведінка алокації роблять малі випадкові записи складнішими, ніж у дзеркалах, що важливо, коли один диск уповільнюється.
- «Повільний диск псує vdev» існувало ще до ZFS. Класичні RAID масиви завжди обмежувалися найповільнішим членом; ZFS просто дає кращу інструментацію, щоб це довести.
- Реальність 4K секторів змінила все. ZFS
ashiftіснує тому, що диски роками брехали (або напів-брехали) про розміри секторів; невірне вирівнювання може посилити I/O і латентність. - Scrub — це функція, а не покарання. ZFS scrub читає все навмисно; мета — знайти латентні помилки, перш ніж ресилвер змусить вас вчитись на важкому.
- ZFS може обирати різні сторони дзеркала для читань. Це може сховати повільний диск при читаннях, тоді як записи все ще страждають, що призводить до конфузних інцидентів «читання нормальне, записи жахливі».
- SLOG — це не кеш для записів. Окремий лог-пристрій прискорює лише синхронні записи; він не виправить латентність асинхронних записів або повільних членів пулу.
- iostat в OpenZFS став кориснішим з часом. Старі реалізації були тоншими; сучасний OpenZFS показує більше поведінки по vdev, а на деяких платформах ви можете отримати гістограми латентності через інші інструменти.
- SSD можуть бути «здоровими» і при цьому ставати причиною затримок. Фірмварні GC та термальне тротлінг можуть створювати спайки латентності без явних SMART-помилок — допоки ви не скорелюєте iostat і температури.
Що насправді показує zpool iostat -v (і що приховує)
The command you’ll actually use
Команда, яку ви справді будете використовувати
Основна робоча конячка:
zpool iostat -v з інтервалом і, за потреби, лімітом по кількості.
Без інтервалу ви отримаєте середні значення за час роботи з моменту завантаження/імпорту — корисно для планування ємності, погано для інцидентів.
З інтервалом ви отримаєте дельти за інтервал. Тут живе правда.
Поширені варіанти:
zpool iostat -v 1для спостереження в реальному часіzpool iostat -v 5 12для 1-хвилинного знімкаzpool iostat -v -y 1щоб приховати перший рядок «з моменту завантаження», який інакше відволікає людей в кімнатах кризzpool iostat -v -pдля точних байтів (без людино-зручних форматів), що важливо, коли ви дивитесь на малі дельти
Що означають колонки (і що з цього слід робити висновок)
В залежності від платформи/версії OpenZFS ви побачите колонки на кшталт capacity, operations, bandwidth.
Типовий вивід показує операції читання/запису і пропускну спроможність читання/запису на рівні пулу, vdev і пристрою-листа.
Цього достатньо, щоб спіймати багато вбивць латентності, бо латентність зазвичай проявляється як зменшення ops плюс нерівномірний розподіл плюс один пристрій робить менше роботи (або дивно більше).
Те, що ви часто не побачите прямо — це мілісекунди латентності. Деякі платформи її демонструють через розширені режими iostat або інші інструменти,
але навіть без явних колонок латентності можна діагностувати: коли навантаження стабільне, повільний пристрій проявляється як падіння ops/пропускної здатності щодо сусідів,
плюс зростання навантаження в інших місцях, плюс видимі користувачам паузи.
Дисципліна: не дивіться на підсумки пулу. Пулові підсумки можуть виглядати «нормально», поки один диск тихо створює хвостову латентність періодичними зависаннями.
Завжди розгортайте до vdev і диска.
Жарт №1: Якби зберігання було командним видом спорту, повільний диск — це той, хто наполягає на «ще одній швидкій справі» перед кожною передачею.
Швидкий план діагностики (перший/другий/третій)
Перший: підтвердьте, що це затримка зберігання, а не CPU, мережа чи пам’ять
Якщо система свопить, або NIC втрачає пакети, або CPU зашкалює через компресію, сховище все одно отримає звинувачення.
Зробіть 60-секундну перевірку:
- Load average проти використання CPU
- Активність swap
- Помилки мережі
- Розмір ZFS arc та викиди
Але не переоцінюйте: якщо латентність аплікації корелює зі спайком пулу — продовжуйте.
Другий: запустіть zpool iostat -v з інтервалом і спостерігайте за асиметрією
Запустіть zpool iostat -v -y 1 під час інциденту. Ви шукаєте:
- Один leaf-пристрій з набагато меншою кількістю ops ніж у братів (або періодичне занулення)
- Один пристрій з дивною пропускною здатністю у порівнянні з іншими (підсилення читань, повтори, трафік ресилверу)
- Один vdev, що тягне вниз операції пулу (поширено для RAIDZ під випадковим I/O)
Третій: підтвердіть телеметрією стану та помилок
Після того як у вас є підозрілий диск, перевірте:
zpool status -vна наявність помилок, активності resilver/scrubsmartctlна помилки медіа, CRC, температуру та шаблони тайм-аутівiostat/nvmeінструменти для рівня пристрою — зайнятість і латентність (залежить від платформи)
Точка прийняття рішення зазвичай одна з таких:
- Офлайн/заміна диска, що відмовляє
- Виправлення шляху/кабелю/контролера (CRC-помилки, сброси лінії)
- Зупинити «оптимізацію», що генерує шкідливий I/O (поганий recordsize, неправильне використання sync, патологічне планування scrub)
- Перебалансувати або переробити розклад vdev, якщо ви його переросли (ширина RAIDZ, дзеркала, спеціальний vdev)
Практичні завдання: команди, значення виводу, рішення
Ось ходи, які можна виконати на живій системі. Кожен містить те, на що ви дивитесь, і яке рішення це підштовхує.
Використовуйте інтервал. Використовуйте -y. І перестаньте копіювати/вставляти середні значення за весь час у канали інцидентів, ніби це щось означає.
Завдання 1: Отримати чистий реальний перегляд по дисках
cr0x@server:~$ zpool iostat -v -y 1
capacity operations bandwidth
pool alloc free read write read write
tank 7.12T 3.80T 980 420 120M 38.0M
raidz2-0 7.12T 3.80T 980 420 120M 38.0M
sda - - 170 70 21.0M 6.2M
sdb - - 165 71 20.8M 6.4M
sdc - - 168 69 20.9M 6.1M
sdd - - 20 180 2.0M 19.3M
sde - - 170 71 21.1M 6.3M
sdf - - 167 70 20.7M 6.2M
Значення: Один диск (sdd) виконує значно менше читань і значно більше записів, ніж його сусіди; патерн асиметричний.
Це може бути реальний дисбаланс навантаження, але в RAIDZ це часто натяк на повтори, реконструкційні читання або дивну поведінку пристрою.
Рішення: Помітьте sdd як підозрюваний і підтвердіть через zpool status та SMART. Поки нічого не замінюйте, але припиніть сперечатися про «пулові підсумки».
Завдання 2: Звузити до одного пулу і зменшити шум
cr0x@server:~$ zpool iostat -v -y tank 2 10
capacity operations bandwidth
pool alloc free read write read write
tank 7.12T 3.80T 950 410 118M 37.6M
raidz2-0 7.12T 3.80T 950 410 118M 37.6M
sda - - 165 68 20.6M 6.0M
sdb - - 163 67 20.7M 6.1M
sdc - - 164 66 20.5M 5.9M
sdd - - 10 175 1.1M 18.7M
sde - - 166 67 20.8M 6.0M
sdf - - 162 69 20.5M 6.1M
Значення: Дисбаланс зберігається між інтервалами. Це не одноразовий сплеск.
Рішення: Ескалюйте від «інтуїції» до «активного розслідування». Хтось повинен почати дамп SMART і перевірку помилок зараз, а не після завершення інциденту.
Завдання 3: Перевірити стан пулу і подивитись, чи ZFS вже не підказує відповідь
cr0x@server:~$ zpool status -v tank
pool: tank
state: ONLINE
status: One or more devices has experienced an unrecoverable error. An
attempt was made to correct the error. Applications are unaffected.
action: Determine if the device needs to be replaced.
scan: scrub repaired 0B in 02:14:33 with 0 errors on Wed Dec 25 03:12:41 2025
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 3 0 0
sde ONLINE 0 0 0
sdf ONLINE 0 0 0
errors: No known data errors
Значення: sdd має помилки читання. ZFS їх виправив (тому дані не пошкоджені), але за це довелося заплатити затримкою.
«Applications are unaffected» означає цілісність даних, а не зручність користувачів.
Рішення: Ставтеся до sdd як до відмовного до тих пір, поки не доведено протилежне. Готуйте заміну і перевіряйте кабелі/контролер також.
Завдання 4: Витягнути SMART-дані і шукати звичні брехуни
cr0x@server:~$ sudo smartctl -a /dev/sdd
SMART overall-health self-assessment test result: PASSED
ID# ATTRIBUTE_NAME VALUE WORST THRESH TYPE UPDATED WHEN_FAILED RAW_VALUE
5 Reallocated_Sector_Ct 100 100 010 Pre-fail Always - 12
187 Reported_Uncorrect 100 100 000 Old_age Always - 3
197 Current_Pending_Sector 100 100 000 Old_age Always - 1
199 UDMA_CRC_Error_Count 200 199 000 Old_age Always - 48
194 Temperature_Celsius 031 048 000 Old_age Always - 57
Значення: «PASSED» — це не гарантія продуктивності. Перелік реаранжованих секторів і очікуваних секторів натякає на деградацію медіа.
CRC-помилки вказують на проблеми кабелю/бекплейну/контролера. 57°C — «я не помер, я просто повільний і роздратований».
Рішення: Якщо CRC росте — переставте/заміни кабель/бекплейн-лан. Якщо є realloc/pending — плануйте заміну диска.
Якщо температура висока — поліпшіть повітряний потік; тепло викликає спайки латентності перед тим, як викликає повну відмову.
Завдання 5: Підтвердити відображення підозрілого диска (щоб не витягти не той)
cr0x@server:~$ ls -l /dev/disk/by-id/ | grep sdd | head
lrwxrwxrwx 1 root root 9 Dec 25 09:10 ata-ST12000NM0007_ZL0ABC12 -> ../../sdd
lrwxrwxrwx 1 root root 10 Dec 25 09:10 wwn-0x5000c500a1b2c3d4 -> ../../sdd
Значення: У вас є стабільні ідентифікатори (WWN/by-id), які переживуть перезавантаження й перенумерацію пристроїв.
Рішення: Використовуйте by-id/WWN у процедурах заміни і в zpool replace, де це можливо.
«Ми витягли не той диск» — різновид інциденту.
Завдання 6: Перевірити, чи scrub/resilver не конкурує за I/O
cr0x@server:~$ zpool status tank
pool: tank
state: ONLINE
scan: scrub in progress since Wed Dec 25 09:02:11 2025
3.11T scanned at 1.25G/s, 1.44T issued at 595M/s, 7.12T total
0B repaired, 20.18% done, 00:18:43 to go
Значення: Scrub активно читає пул. На завантажених пулах scrub може підвищувати затримку, насичуючи черги дисків.
Якщо один диск слабкий, scrub робить це очевидним, тягнучись і запізнюючись.
Рішення: Під час інциденту, орієнтованого на клієнта, розгляньте паузу scrub (zpool scrub -p), якщо політика дозволяє.
Але не «вирішуйте» інцидент постійною відмовою від scrub; так ви перетворите латентні помилки на втрату даних згодом.
Завдання 7: Виявити тиск синхронних записів (і припинити помилково звинувачувати SLOG)
cr0x@server:~$ zfs get -o name,property,value -H sync,logbias tank
tank sync standard
tank logbias latency
Значення: Синхронні записи обробляються за замовчуванням; logbias віддає перевагу лог-пристрою, якщо він є.
Якщо латентність аплікації спричинена fsync-важкими записами, якість SLOG має значення. Якщо ж навантаження не синхронне, SLOG не врятує.
Рішення: Якщо інцидент — це затримки записів і у вас немає SLOG (або він повільний), розгляньте додавання SLOG з гарантією від втрати живлення.
Якщо SLOG вже є, не припускайте, що він працює — виміряйте.
Завдання 8: Наглядайте поведінку по vdev у дзеркалі (ловіть випадок «одна сторона хвора»)
cr0x@server:~$ zpool iostat -v -y ssdpool 1
capacity operations bandwidth
pool alloc free read write read write
ssdpool 812G 989G 4200 1800 520M 210M
mirror-0 812G 989G 4200 1800 520M 210M
nvme0n1 - - 4100 900 505M 110M
nvme1n1 - - 100 900 15M 110M
Значення: Читання обслуговуються переважно з nvme0n1; записи дзеркаляться, тому обидва отримують їх.
Такий патерн може з’явитись, бо ZFS віддає перевагу швидшій стороні для читань. Якщо nvme1n1 гальмує, ви можете не помітити цього до появи затримок записів або ресилверу.
Рішення: Дослідіть «тиху» сторону все одно. Запустіть SMART/NVMe логи і перевірку на термальне тротлінг або помилки медіа.
Завдання 9: Перевірити здоров’я NVMe на тротлінг та зброси
cr0x@server:~$ sudo nvme smart-log /dev/nvme1
temperature : 79 C
available_spare : 100%
percentage_used : 12%
media_errors : 0
num_err_log_entries : 27
warning_temp_time : 148
critical_comp_time : 0
Значення: 79°C плюс значний warning-temp time: пристрій ймовірно тротлиться.
Записи помилок в журналі вказують на зброси/тайм-аути, навіть якщо media_errors == 0.
Рішення: Виправте охолодження і перевірте поведінку фірмвару/контролера. Тротлінг — вбивця латентності, що виглядає як «випадкові паузи ZFS».
Завдання 10: Шукати проблеми контролера або лінку в логах ядра
cr0x@server:~$ sudo dmesg | egrep -i "sdd|ata|reset|timeout|I/O error" | tail -n 8
[ 8123.441122] ata7: hard resetting link
[ 8123.771090] ata7: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
[ 8124.112904] blk_update_request: I/O error, dev sdd, sector 223456789 op 0x0:(READ)
[ 8124.112970] sd 7:0:0:0: [sdd] tag#12 FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
[ 8124.113001] sd 7:0:0:0: [sdd] Sense Key : Medium Error [current]
Значення: Сброси лінку і I/O помилки. Це не «ZFS повільний». Це пристрій або шлях.
Рішення: Замініть/полагодьте шлях (кабель/бекплейн/порт HBA) і, ймовірно, диск. Якщо помилки зберігаються після фіксу шляху — винен диск.
Завдання 11: Підтвердити ashift і зупинити випадкове підсилення записів
cr0x@server:~$ zdb -C tank | egrep "ashift|vdev_tree" -n | head -n 12
56: vdev_tree:
78: ashift: 12
Значення: ashift: 12 означає 4K сектори. Добре для сучасних дисків.
Якщо ви бачите 9 (512B) на 4K медіа, це може створювати брутальну поведінку read-modify-write і підвищену латентність при випадкових записах.
Рішення: Якщо ashift невірний, справжнє виправлення — перебудова пулу правильно. Не вдавайте, що якийсь тюнінг врятує.
Завдання 12: Визначити, чи спеціальний vdev є прихованим вузьким місцем
cr0x@server:~$ zpool status tank | sed -n '1,120p'
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 3 0 0
sde ONLINE 0 0 0
sdf ONLINE 0 0 0
special
mirror-1 ONLINE 0 0 0
nvme2n1 ONLINE 0 0 0
nvme3n1 ONLINE 0 0 0
Значення: Є спеціальний vdev mirror. Якщо він недостатньо розмірний або тротлиться, метадані-важкі навантаження стають повільними, навіть якщо основний RAIDZ виглядає нормальним.
Якщо special vdev впаде, пул може опинитися під загрозою в залежності від того, що там алоковано.
Рішення: Моніторте special vdev як критичний товар (бо він таким і є). Якщо він гарячий або помиляється — ремонтуйте його в першу чергу.
Завдання 13: Скорелювати поведінку ZFS з використанням блочного використання пристроїв
cr0x@server:~$ iostat -x 1 5
avg-cpu: %user %nice %system %iowait %steal %idle
11.20 0.00 6.10 9.40 0.00 73.30
Device r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await svctm %util
sda 168.0 70.0 21000.0 6200.0 224.2 1.10 5.20 1.40 33.2
sdb 166.0 69.0 20800.0 6100.0 223.9 1.08 5.10 1.35 32.9
sdc 167.0 68.0 20900.0 6000.0 224.1 1.12 5.30 1.38 33.5
sdd 10.0 175.0 1100.0 18700.0 225.0 18.40 115.00 5.90 99.8
sde 167.0 69.0 21100.0 6100.0 224.0 1.09 5.20 1.37 33.1
sdf 165.0 70.0 20700.0 6200.0 224.3 1.11 5.10 1.36 33.0
Значення: sdd має величезну чергу (avgqu-sz), високий await і 99.8% завантаження.
Сусіди круїзять на ~33% завантаження з ~5ms await. Ось ваш винуватець затримки.
Рішення: У вас достатньо доказів для дій. Якщо надмірність дозволяє — офлайньте і замініть sdd, або виправте його шлях.
Не чекайте, поки він «впаде ще сильніше».
Завдання 14: Офлайнити диск безпечно (коли ви точно знаєте, що робите)
cr0x@server:~$ sudo zpool offline tank sdd
Значення: ZFS припиняє використовувати цей пристрій. В RAIDZ2 vdev ви можете пережити до двох відсутніх пристроїв; у дзеркалі — один.
Рішення: Робіть це тільки якщо надмірність дозволяє і ви впевнені у ідентичності пристрою. Офлайн може одразу поліпшити латентність, прибравши гальмівний диск із шляху I/O.
Завдання 15: Замінити за by-id і спостерігати розподіл I/O під час resilver
cr0x@server:~$ sudo zpool replace tank /dev/disk/by-id/wwn-0x5000c500a1b2c3d4 /dev/disk/by-id/wwn-0x5000c500d4c3b2a1
Значення: Ви замінюєте конкретний WWN-пристрій на новий. Це уникне рулетки з назвами пристроїв.
Рішення: Після заміни використовуйте zpool iostat -v під час resilver, щоб переконатися, що новий диск поводиться як сусіди і пул залишається чутливим.
Як інтерпретувати патерни: підписи затримки для типових відмов
Підпис 1: Один диск показує менше ops і час від часу «плоскі» інтервали
Ви побачите диск, у якого операції читання/запису падають до майже нуля на інтервалі, потім він «наганяє».
Це класика для фірмварних застоїв, внутрішнього GC (SSD) або сбросів SATA лінії.
Пулова сума може не впасти, бо інші пристрої ще працюють, але ваш p99 виглядатиме жахливо.
Що робити: Перевірте dmesg на зброси/тайм-аути і SMART/NVMe журнали помилок. Перевірте температури. Якщо повторюється — замінюйте.
Підпис 2: Один диск на 100% завантаженні з величезними чергами; сусіди відпочивають
Це пальне свідчення. ZFS виконує те, що може, але пристрій не встигає.
В RAIDZ один диск на 100% може пригальмувати читання реконструкції і операції паритету. У дзеркалах повільна сторона може шкодити записам.
Що робити: Підтвердіть через iostat -x. Якщо проблема шляху (CRC-помилки) — лагодьте кабелі. Якщо медіа — замініть диск.
Підпис 3: Записи повсюди повільні, але читання в нормі
Часто це синхронні записи. Або SLOG, що насправді не швидкий. Або налаштування dataset, яке змушує sync (або аплікація часто викликає fsync).
Дзеркала ховають проблеми читання краще, ніж записи; RAIDZ карає випадкові записи.
Що робити: Перевірте налаштування dataset (sync, logbias), перевірте наявність SLOG-пристрою і переконайтесь, що він низьколатентний і захищений від втрати живлення.
Також перевірте, чи не потрапили ви на фрагментацію і малі записи в RAIDZ.
Підпис 4: Під час scrub/resilver все стає «картоплею»
Scrub/resilver — контактний вид спорту. ZFS буде конкурувати з вашим робочим навантаженням за дискочас.
Якщо у вас є один поганий диск, scrub робить його центром уваги.
Що робити: Плануйте scrub. Розгляньте обмеження через системні інструменти планування I/O (залежить від платформи), замість вимкнення scrub.
Якщо scrub виявляє помилки на конкретному диску — не сперечайтесь; міняйте його.
Підпис 5: Спеціальний vdev або пристрій метаданих гальмує й викликає дивні «все повільно, але диски даних спокійні»
Метадані — це вузьке місце для багатьох навантажень. Якщо special vdev перевантажений або тротлиться, операції файлової системи і дрібні I/O можуть повзти.
Ви побачите, що пристрої special vdev гарячіші/зайнятіші, ніж основний vdev.
Що робити: Моніторте його як компонент першого рівня. Використовуйте zpool iostat -v і телеметрію пристрою, щоб підтвердити, що це не термальне тротлінг.
Один вислів, який варто тримати на стікері (перефразована ідея): повідомлення Джона Оллспо — ви не «перешкоджаєте» відмові; ви будуєте системи, що швидко виявляють і відновлюють.
Жарт №2: SMART «PASSED» — як корпоративний звіт про стан — технічно правда, емоційно марний.
Три корпоративні міні-історії з латентних боїв
Міні-історія №1: Інцидент, спричинений хибним припущенням
Середня SaaS-компанія використовувала ZFS-backed NFS рівень для CI-артефактів і образів контейнерів. Місяцями все було нормально.
Потім почалися «випадкові» уповільнення: збірки зависали, pulls тайм-аутились, і on-call постійно чув, що «знову сховище повільне».
Команда припустила, що це мережеве насичення, бо графіки пропускної здатності пулу не виглядали жахливо.
Вони провели ранок, тонізуючи NFS-потоки і сперечаючись про MTU. Перезавантажили свіч.
Нічого не змінилось. Латентні спайки лишалися, здебільшого у пікові години комітів.
Хтось нарешті запустив zpool iostat -v -y 1 під час інциденту і помітив один диск у RAIDZ2,
який мав значно менше читань, ніж його побратими, з періодичними майже нульовими інтервалами.
Хибне припущення було тонким: вони вірили, що «якщо пропускна здатність нормальна, то сховище не проблема».
Але їхнє навантаження складалось з великої кількості дрібних випадкових читань (метадані, багато маленьких файлів), де хвостова латентність важить більше, ніж агреґований MB/s.
Один диск періодично скидав SATA-лінк. ZFS тримав пул онлайн і лікував помилки, але повтори переклались у видимі користувачам паузи.
Вони замінили диск, і графіки майже не змінились. Оце і є суть: пропускна здатність ніколи не була реальним симптомом.
Квитки клієнтів припинилися за годину, бо p99 перестав робити туристичні об’їзди через відновлення помилок.
Урок, який вони записали: ви не розбираєтесь з інцидентами ZFS за підсумками пулу; ви розбираєтесь з дельтами по-пристрою й доказами.
Міні-історія №2: Оптимізація, що відскочила назад
Фінансово орієнтована компанія мала ZFS-пул, що обслуговував VM’и через iSCSI. Латентність була звичайною, але не видатною.
Інженер запропонував «легку перемогу»: змінити властивості dataset задля продуктивності — менший recordsize «для баз даних», агресивніша компресія
і загальна зміна обробки sync-записів, бо «UPS нас захистить».
Миттєвий бенчмарк виглядав краще. Потім настала продукція.
Бази даних почали виконувати більше I/O на транзакцію через невідповідний recordsize,
компресія збільшила навантаження CPU під спайками, а зміни sync створили патологічну поведінку через fsync аплікації.
Щоб було ще гірше, команда додала споживчий NVMe як SLOG, бо він «швидкий», ігноруючи характеристики збереження живлення і стійку латентність.
zpool iostat -v розповів конкретну історію: SLOG пристрій був завантажений високими write ops у пікові години,
а один член дзеркала почав показувати нерівномірний розподіл, перегріваючись.
Латентність стала гіршою саме тоді, коли команда очікувала покращення.
Відкат виправив інцидент. Постмортем не був про сором; він був про дисципліну.
Оптимізації, що змінюють семантику записів — це не «дрібні налаштування». Це зміни архітектури.
Якщо ви не можете пояснити нові режими відмов — і не вимірюєте їх у живому часі — ви просто переміщаєте ризик, допоки він не впаде на клієнта.
Міні-історія №3: Нудна, але правильна практика, що врятувала день
Постачальник у сфері охорони здоров’я використовував ZFS для сховища документів. Ніхто не любив ту систему; вона була «легасі», тобто критична і недофінансована.
Але інженер збереження мав одну звичку: щотижневі вікна scrub і простий ранбук, що включав захоплення zpool iostat -v під час scrub.
Нудно. Повторювано. Ефективно.
Одного тижня час scrub помітно зріс. Не настільки, щоб викликати пейдж, але достатньо, щоб з’явитись у нотатках.
Під час scrub по-дискові статистики показали один диск, що читав менше і час від часу гальмував.
SMART все ще говорив «PASSED», бо, звісно, говорив, але були зростаючі CRC-помилки і підвищена температура.
Інженер створив заявку на заміну кабелю і, за потреби, диска в наступному вікні обслуговування.
Заміна кабелю зменшила CRC, але не усунула зависання. Вони проактивно замінили диск, ресилвер пройшов чисто, і все повернулося до норми.
Через два місяці інша команда мала майже ідентичну відмову на схожому шасі і зазнала брудного інциденту, бо у них не було історії трендів і звички дивитись по-дискові метрики.
Нудна практика не просто запобігла простою; вона позбавила від неоднозначності.
Коли ви можете сказати «цей диск деградує тижнями», вам дозволяють робити технічне обслуговування замість героїчних заходів.
Типові помилки: симптом → причина → виправлення
1) Симптом: Пропускна здатність пулу виглядає нормально, але p99 латентність жахлива
Корінь проблеми: Один диск періодично гальмує; ZFS повторює/лікує; середні ховають хвостову латентність.
Або спеціальний vdev гальмує операції метаданих.
Виправлення: Використовуйте zpool iostat -v -y 1 під час інциденту; знайдіть асиметрію.
Скорелюйте з iostat -x, dmesg та SMART/NVMe журналами. Замініть відмовний диск/шлях; вирішіть проблему перегріву.
2) Симптом: Записи повільні у дзеркалі, хоча читання швидкі
Корінь проблеми: ZFS може обирати швидшу сторону для читань, приховуючи хворий диск; записи повинні потрапити на обидві сторони.
Або синхронні записи насичують слабкий SLOG.
Виправлення: Шукайте дисбаланс по leaf у дзеркалі за допомогою zpool iostat -v.
Перевірте поведінку SLOG. Виправте/замініть повільний член дзеркала або пристрій SLOG.
3) Симптом: Scrub робить пул непридатним
Корінь проблеми: Scrub конкурує за I/O; пул близький до ємності або фрагментований; один диск маргінальний і стає вузьким місцем.
Виправлення: Плануйте scrub у вікнах низького навантаження; розгляньте паузу під час інцидентів.
Дослідіть повільний диск через zpool iostat -v і SMART; замініть його, якщо він тягне. Тримайте вільне місце здоровим.
4) Симптом: RAIDZ пул має погану випадкову затримку записів у порівнянні з очікуваннями
Корінь проблеми: Накладні витрати паритету RAIDZ плюс малі блоки; невірний recordsize; невирівняний ashift; важке синхронне навантаження без відповідного дизайну.
Виправлення: Підтвердіть ashift. Вирівняйте recordsize під навантаження. Для важкого випадкового I/O віддавайте перевагу дзеркалам або змініть ширину vdev і шаблон навантаження.
Не «тюньте» паритет у бік небезпеки.
5) Симптом: Диск показує багато CRC-помилок, але без реаранжованих секторів
Корінь проблеми: Кабелі/бекплейн/HBA викликають корупцію на рівні лінку і повтори.
Виправлення: Замініть/переставте кабелі, поміняйте порти, перевірте бекплейн. Слідкуйте, чи CRC перестане інкрементуватись після фіксу.
6) Симптом: Заміна диска не допомогла; латентність все ще спайки
Корінь проблеми: Реальна проблема — шлях/контролер; або навантаження сильно синхронне; або throttling special vdev.
Виправлення: Використовуйте dmesg і телеметрію контролера. Перевірте sync/logbias і SLOG.
Перегляньте iostat special vdev і NVMe-термальні дані.
7) Симптом: «zpool iostat не показує нічого поганого», але аплікація все ще повільна
Корінь проблеми: Ви дивитесь на середні за весь час (без інтервалу), або інцидент переривчастий і ви його пропустили.
Або вузьке місце вище ZFS (CPU, пам’ять, мережа) або нижче (multipath, SAN, гіпервізор).
Виправлення: Завжди використовуйте режим з інтервалом. Захоплюйте під час події. Додайте легке постійне семплювання в моніторинг, щоб можна було відтворити момент.
Контрольні списки / покроковий план
Покроково: упіймайте повільний диск за менше ніж 10 хвилин
-
Запустіть статистику по інтервалах.
cr0x@server:~$ zpool iostat -v -y 1Рішення: Визначте будь-який leaf-пристрій, чий ops/пропускна здатність не відповідає сусідам.
-
Підтвердіть стан пулу і фонова активність.
cr0x@server:~$ zpool status -vРішення: Якщо scrub/resilver активні — вирішіть, чи варто їх поставити на паузу для пом’якшення інциденту.
-
Скорелюйте з блочним рівнем: черга і await.
cr0x@server:~$ iostat -x 1 3Рішення: Високий
awaitта черга на одному диску = дія. Не чекайте. -
Перегляньте логи на сброси/тайм-аути.
cr0x@server:~$ sudo dmesg | egrep -i "reset|timeout|I/O error|blk_update_request" | tail -n 30Рішення: Якщо є сброси лінку — підозрюйте кабелі/HBA/бекплейн навіть якщо SMART тихий.
-
Витягніть SMART/NVMe журнали підозрілого пристрою.
cr0x@server:~$ sudo smartctl -a /dev/sdXРішення: Pending/realloc/CRC/температура визначають: замінювати чи фіксити шлях.
-
Якщо надмірність дозволяє — офлайньте нападника, щоб відновити латентність.
cr0x@server:~$ sudo zpool offline tank sdXРішення: Використовуйте як екстрену міру пом’якшення, а не постійний спосіб життя.
-
Замініть за стабільними ідентифікаторами і моніторьте resilver.
cr0x@server:~$ sudo zpool replace tank /dev/disk/by-id/OLD /dev/disk/by-id/NEWРішення: Якщо iostat нового диска відрізняється від сусідів — зупиніться і перевірте апарат/фірмвар.
Контрольний список: що захопити для корисного постмортему
zpool iostat -v -y 1зразки під час вікна інциденту (навіть 60 секунд допомагає)zpool status -vвключно з лічильниками помилок і станом сканування- SMART/NVMe журнали для будь-якого підозрілого диска (включно з температурою і CRC)
iostat -xдля підтвердження черги/await/%util- Логи ядра навколо моменту спайку (сброси, тайм-аути)
- Що змінилось недавно (фірмвар, перестановка кабелів, зміни навантаження, налаштування dataset)
Контрольний список: рішення, які варто прийняти явно (не інтуїтивно)
- Проблема ізольована до одного диска, одного vdev чи системна?
- Чи маємо надмірність, щоб офлайнити зараз?
- Чи це проблема шляху (CRC/сброси) чи медіа (pending/realloc/uncorrectable)?
- Чи scrub/resilver підсилює проблему і чи його можна безпечно призупинити?
- Чи потрібно змінити архітектуру (дзеркала vs RAIDZ, розмір special vdev), а не тюнити?
FAQ
1) Чому один повільний диск шкодить всьому пулу?
Тому що ZFS адресує I/O конкретним vdev. Якщо блок знаходиться на повільному vdev (або потребує реконструкції з його участю), запит чекає.
Хвостова латентність визначається найгіршим учасником, а не середнім.
2) Чи показує zpool iostat латентність?
Зазвичай він показує ops і пропускну здатність, а не мілісекунди. Але латентність проявляється опосередковано як зменшення ops, нерівномірний розподіл і зріст черг,
що підтверджується через iostat -x або платформно-специфічні інструменти латентності.
3) Чому я завжди маю використовувати інтервал (наприклад zpool iostat -v 1)?
Без інтервалу ви дивитесь на середні з моменту імпорту/завантаження. Інциденти живуть в спайках і дельтах.
Режим інтервалу дає вам реальність за секунду (або за N секунд).
4) Я бачу, що одна сторона дзеркала робить майже всі читання. Це погано?
Не обов’язково. ZFS може віддавати перевагу швидшій стороні. Погано тоді, коли «ігнорована» сторона ігнорується через хворобу
(термальне тротлінг, тайм-аути, помилки). Перевірте телеметрію пристрою.
5) SMART каже PASSED. Чи може диск все одно бути проблемою?
Так. Загальний стан SMART грубий. Дивіться конкретні атрибути (pending sectors, reallocations, CRC errors, temperature)
і журнали помилок. Також дивіться логи ядра на зброси/тайм-аути.
6) Чи варто призупиняти scrub під час інциденту?
Якщо scrub конкурує з критичним продакшн I/O і потрібно відновити сервіс — пауза може бути розумним тимчасовим кроком.
Але перенесіть його і розберіться, чому scrub так боляче впливає — часто він виявляє слабкий диск або перенавантажену конструкцію.
7) Чи додає SLOG фіксує латентність?
Він може виправити латентність синхронних записів, коли навантаження дійсно sync-важке, і SLOG низьколатентний і захищений від втрати живлення.
Він нічого не робить для асинхронних записів або читань, а поганий SLOG може погіршити ситуацію.
8) Як зрозуміти, чи то кабель/бекплейн, а не диск?
Зростання UDMA_CRC_Error_Count на SATA-пристроях — сильний натяк, разом зі сбросами лінку в dmesg.
Помилки медіа (pending/realloc/uncorrectable) більше вказують на сам диск. Іноді буває й те, й інше; спочатку фіксуйте шлях, потім переоцініть.
9) Чому RAIDZ часто гірший для випадкової затримки записів, ніж дзеркала?
Паритет потребує додаткових читань/записів і координації між дисками; малі записи можуть перетворюватись на цикли read-modify-write.
Дзеркала роблять простіші записи. Якщо вам потрібні IOPS і низька хвостова латентність, дзеркала зазвичай простіший вибір.
10) Яке найшвидше «доведення», яке я можу показати не-сторедж-фолкам?
Короткий захват zpool iostat -v -y 1 плюс iostat -x 1, де один пристрій має драматично вищий await і чергу,
тоді як сусіди нормальні. Це візуально, повторюване і не вимагає віри в сторедж-фолк.
Висновок: що робити далі, сьогодні
Коли латентність ZFS йде вбік, не починайте з «тонування ZFS». Почніть з доведення, чи неправильно поводиться один диск або один vdev.
zpool iostat -v з інтервалом — ваш ліхтар; він швидко виявляє асиметрію.
Потім корелюйте з zpool status, SMART/NVMe журналами і повідомленнями ядра.
Практичні наступні кроки:
- Включіть
zpool iostat -v -y 1у ваш ранбук інцидентів, а не у власну пам’ять. - Під час наступного вікна scrub захопіть поведінку по-дисках і зробіть базову лінію. Нудні бази скорочують драму інцидентів.
- Якщо знаходите підозрілий пристрій — дійте швидко: фікс шляху, офлайн або заміна. Хвостова латентність рідко зціляється сама.
- Якщо архітектура не відповідає (синхронно-важка БД на широкому RAIDZ, undersized special vdev) — визнайте це і сплануйте редизайн замість поклоніння тюнам.
Один диск, що руйнує латентність, рідко буває тонким. Сутність тонка — це ми: ми продовжуємо дивитися на підсумки пулу і сподіватись, що середні розкажуть правду.
Вони не розкажуть. Дельти по-пристрою розкажуть.