Найкращим тестом вашого проєктування зберігання є момент, коли диск відвалюється о 14:00 у вівторок і пул починає resilver під час того, як бізнес усе ще працює. Ви хочете, щоб відновлення завершилося швидко — адже ризик накопичується з кожною хвилиною у деградованому стані — але й не хочете, щоб бази даних відчувалися так, ніби працюють на флоппі-диску.
Пріоритет resilver у ZFS насправді — це набір регуляторів: планування, паралелізм, глибина черги та те, наскільки агресивно ZFS обробляє «брудні» області й метадані. Якщо зробити все правильно, resilver — це контрольоване «опалювання». Якщо помилитися — ви створите власний інцидент, м’яко кажучи, ізсередини.
Що насправді означає пріоритет resilver (і чого він не означає)
У термінах ZFS, resilver — це процес реконструкції надлишковості після заміни або повторного підключення пристрою, або після тимчасової відсутності й повернення пристрою. Це споріднене зі scrub, але не те саме завдання.
Говорять «підвищити пріоритет resilver», ніби існує один повзунок підписаний Make It Fast. Такого немає. Швидкість resilver і її вплив на продуктивність походять від:
- Чого ZFS вирішує копіювати: resilver зазвичай інкрементальний і керується метаданими ZFS про те, що потрібно відтворити, а не є сліпим повним клонуванням диска (хоча певні конфігурації й умови можуть наблизити його до такого).
- Скількох паралельних IO-запитів ZFS відправляє: занадто мало — ви недовикористовуєте диски; занадто багато — насичуєте черги і вбиваєте затримки.
- Де фактично вузьке місце: часто це не «швидкість диска», а випадковий IO-ампліфікація, конкуренція за метадані, фрагментація або один vdev, що зафіксований.
- Поведінка планувальника IO і черг в ОС: Linux і FreeBSD поводяться по-різному; сучасні планувальники, NVMe і віртуальні шари змінюють правила гри.
- Конкуруюча робота: scrubs, інтенсивні записи, синхронні навантаження та випадкові малі читання всі борються за ті самі шпинделі.
Пріоритет на практиці означає вирішити, хто має право дратувати: resilver чи ваші клієнти. Зазвичай можна знайти компроміс, де resilver залишається досить агресивним для зменшення ризику, а продукція тримає p99 затримки нижче «дзвінка CEO».
Цитата, яку варто тримати на екрані
Парафразована ідея (Werner Vogels, інженерія, орієнтована на надійність): «Все ламається, постійно — проектуйте й експлуатуйте з урахуванням цього.»
Факти і історія, що пояснюють сучасну поведінку
Поведінка resilver не довільна; вона результат проєктних рішень і декількох десятиліть шрамів. Ось кілька коротких конкретних фактів, що допоможуть вам розібратися в тому, що ви бачите.
- ZFS побудовано навколо цілісних контрольних сум і copy-on-write, що означає: «відновлення» — не наївне копіювання секторів; це реконструкція на основі того, що пул вважає живим і валідним.
- Традиційні RAID-відновлення історично були повним читанням пристрою, через що старші адміністратори досі вважають, що resilver має читати кожен сектор. ZFS часто може робити менше.
- Scrub передує епосі дешевих великих дисків; сучасні URE та багатотерабайтні диски перетворили «деградований день» на «деградований тиждень», якщо не налаштувати систему.
- Широкі RAIDZ стали популярні частково щоб заощадити відсіки; компроміс — довші часи відновлення і більший IO-тиск під час resilver, особливо під випадковими записами.
- «Послідовний resilver» і пов’язані покращення (реалізація залежить від платформи/версії) намагалися знизити штурми переміщень головки, видаючи IO в більш дружньому для диска порядку.
- ZFS має правильно відновлювати метадані, не лише блоки. Пули з великою часткою метаданих (малі файли, снапшоти, багато dataset) можуть resilver у шаблоні, що виглядає «випадково і повільно», навіть на швидких дисках.
- Спеціальні пристрої (для метаданих/малих блоків) можуть зробити пул голосним у нормальному стані — і інакше голосним у деградованому, бо критичні читання концентруються.
- Стиснення і вибір recordsize змінюють форму IO під час resilver. Великі записи й стиснений вміст можуть зменшити фізичні читання; малі записи перетворюють resilver у мільйон дрібних ран.
Жарт №1: resilver — як ліфт: якщо дивитися, він рухається повільніше. Якщо графікувати — ще повільніше.
Модель ризику: чому «найшвидше можливе» не завжди найбезпечніше
Швидкість resilver — це ручка управління ризиком. Ваш пул деградований; ще одна відмова може перетворитися на втрату даних (або принаймні примусове відновлення). Тож так, швидке завершення має значення. Але «швидко завершити» не означає «наситити все до падіння продуктивності».
Ось трикутник ризику, який ви балансуватимете:
- Час під ризиком: як довго ви працюєте з пониженою надлишковістю.
- Вплив на клієнтів: затримки та бюджет помилок під час відновлення.
- Навантаження на обладнання: агресивні відновлення можуть нагрівати диски й тримати їх на 100% завантаженні днями, підвищуючи ймовірність відмови — особливо на старих шпинделях.
Правильна позиція для більшості продакшн-середовищ: агресивно, але обмежено. Ви хочете, щоб resilver робив помітний прогрес навіть під навантаженням, але не доводив IO-wait і затримки до критичного стану.
Корисна ментальна модель: resilver — це фонове пакетне завдання з крайнім терміном безпеки. Ставтеся до нього як до пакетної роботи, якій можна тимчасово надати пріоритет — але не заради того, щоб система стала непридатною.
Швидкий план діагностики
Якщо ваш resilver повільний або додатки страждають, не починайте з перемикання регуляторів. Почніть із виявлення вузького місця. Це найкоротший шлях до правильного рішення.
Перше: підтвердіть, яку саме роботу ви виконуєте і в якому стані пул
- Чи це справді resilver, scrub чи обидва?
- Чи пул деградований через відсутній диск, faulted-диск або заміну в процесі?
- Чи новий диск повільніший (неочікуваний SMR, USB-міст, неправильна прошивка)?
Друге: визначте обмежувальний vdev і форму IO
- Який vdev виконує найбільше роботи?
- Чи ви обмежені випадковими читаннями, випадковими записами чи sync-записами?
- Чи домінують метадані (високий IOPS, низька пропускна здатність)?
Третє: перевіряйте черги і затримки, а не лише пропускну здатність
- Яка глибина черги диска і час очікування?
- Чи ви насичуєте один HBA-путь?
- Чи падає hit-rate ARC і все хитається на диск?
Четверте: вирішіть, який компроміс ви готові робити
- Чи вам потрібен найшвидший можливий resilver (високий бізнес-ризик, погана надлишковість), навіть якщо це болісно?
- Чи ви повинні захистити p99 затримки (системи для клієнтів), погодившись на довше відновлення?
Практичні завдання: команди, виводи, рішення (12+)
Це ті команди, які я фактично запускаю, коли пул деградований і всі раптово згадують про зберігання. Кожне завдання включає: команду, приклад виводу, що це означає й яке рішення прийняти.
Завдання 1: Перевірити, чи ви виконуєте resilver, scrub або обидва
cr0x@server:~$ zpool status -v tank
pool: tank
state: DEGRADED
status: One or more devices is currently being resilvered.
action: Wait for the resilver to complete.
scan: resilver in progress since Wed Dec 25 09:12:04 2025
1.24T scanned at 1.10G/s, 412G issued at 365M/s, 3.80T total
412G resilvered, 10.57% done, 0 days 02:31:18 to go
config:
NAME STATE READ WRITE CKSUM
tank DEGRADED 0 0 0
mirror-0 DEGRADED 0 0 0
ata-WDC_WD80... ONLINE 0 0 0
replacing-1 DEGRADED 0 0 0
ata-WDC_WD80... OFFLINE 0 0 0
ata-ST8000... ONLINE 0 0 0
errors: No known data errors
Значення: Це resilver, а не просто scrub. «Issued» — це фактично виконана робота; «scanned» може бути більшим, бо ZFS може обходити метадані швидше, ніж встигає реконструювати блоки.
Рішення: Якщо ETA розумний і продукція стабільна — нічого не чіпайте. Якщо затримки підскакують або «issued» повзе — продовжуйте діагностику.
Завдання 2: Перевірити, чи запускався scrub (і зупинити його при потребі)
cr0x@server:~$ zpool status tank | sed -n '1,25p'
pool: tank
state: DEGRADED
scan: resilver in progress since Wed Dec 25 09:12:04 2025
1.24T scanned at 1.10G/s, 412G issued at 365M/s, 3.80T total
Значення: Активний лише resilver. Якщо одночасно бачите «scrub in progress» (можливо у деяких послідовностях операцій), ви робите зайву роботу.
Рішення: Якщо scrub конкурує під час інциденту — зупиніть scrub і дозвольте завершитися resilver першому.
cr0x@server:~$ sudo zpool scrub -s tank
Завдання 3: Показати IO по vdev, щоб знайти «гарячу» точку
cr0x@server:~$ zpool iostat -v tank 2 3
capacity operations bandwidth
pool alloc free read write read write
---------- ----- ----- ----- ----- ----- -----
tank 22.1T 13.5T 18.2K 6.4K 520M 140M
mirror-0 7.40T 5.10T 12.1K 3.1K 340M 70M
sda - - 6.1K 1.6K 170M 35M
sdb - - 6.0K 1.5K 170M 35M
mirror-1 7.40T 4.90T 3.9K 1.7K 110M 40M
sdc - - 2.0K 850 55M 20M
sdd - - 1.9K 840 55M 20M
mirror-2 7.40T 3.50T 2.2K 1.6K 70M 30M
sde - - 1.1K 820 35M 15M
sdf - - 1.1K 810 35M 15M
Значення: mirror-0 виконує більшість читань. Ймовірно, це ваш resilver vdev або vdev з найбільшою кількістю посилань на блоки.
Рішення: Зосередьтеся на «гарячому» vdev. Налаштовувати «неправильний» vdev — це просто показуха продуктивності.
Завдання 4: Підтвердити, що замінний диск не повільний (або не SMR)
cr0x@server:~$ lsblk -o NAME,MODEL,SIZE,ROTA,TRAN,SERIAL
NAME MODEL SIZE ROTA TRAN SERIAL
sda WDC WD80... 7.3T 1 sata WD-AAA
sdb WDC WD80... 7.3T 1 sata WD-BBB
sdc WDC WD80... 7.3T 1 sata WD-CCC
sdd WDC WD80... 7.3T 1 sata WD-DDD
sde WDC WD80... 7.3T 1 sata WD-EEE
sdf ST8000DM004 7.3T 1 sata ZDHFFF
Значення: Один диск — іншої моделі. Це може бути нормально — або це може виявитися SMR-диском, який під час стійких записів перетворює відновлення на патоку.
Рішення: Якщо заміна — модель SMR у навантаженні з записами під час resilver, зупиніть і замініть її на CMR. Так, навіть якщо відділ закупівель буде незадоволений.
Завдання 5: Швидко перевірити стан диска (SMART)
cr0x@server:~$ sudo smartctl -H /dev/sdf
smartctl 7.4 2023-08-01 r5530 [x86_64-linux-6.8.0] (local build)
SMART overall-health self-assessment test result: PASSED
Значення: «PASSED» не означає «здоровий», це означає «неявно мертвий». Все одно перевірте лічильники помилок.
Рішення: Якщо SMART падає або атрибути виглядають погано (reallocated/pending сектора) — не довіряйте такому диску для завершення resilver. Замініть ще раз.
Завдання 6: Спостерігати затримки та глибину черги на рівні ОС під час resilver
cr0x@server:~$ iostat -x 2 3
Linux 6.8.0 (server) 12/25/2025 _x86_64_ (32 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
6.02 0.00 3.11 18.40 0.00 72.47
Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s %util aqu-sz await
sda 320.1 110.4 165000 42000 0.0 2.1 99.0 41.3 110.2
sdf 310.6 115.2 160000 45000 0.0 2.0 98.7 39.8 105.9
Значення: %util ≈99, глибина черги ≈40, await ≈100ms. На шпинделях це означає «ми їх насичуємо і все інше чекатиме».
Рішення: Якщо продукція страждає — треба зменшити паралельний IO або змінити його форму (налаштувати resilver, обмежити пропускну здатність або перемістити навантаження). Якщо у вас SSD/NVMe — 100ms це червона сирена.
Завдання 7: Перевірити навантаження на ARC (приховане джерело «усе стало повільно»)
cr0x@server:~$ grep -E 'c_max|c_min|size|arc_meta_used|hits|misses' /proc/spl/kstat/zfs/arcstats | head
c_max 4 25769803776
c_min 4 6442450944
size 4 24191070208
arc_meta_used 4 4246732800
hits 4 392004112
misses 4 48122103
Значення: ARC майже на c_max; використання метаданих високе. Під час resilver обходи метаданих можуть витісняти корисний кеш і збільшувати звертання на диск для продукції.
Рішення: Якщо ARC трешиться (misses зростають швидко) і у вас є запас RAM, подумайте про обережне підвищення ARC max або зменшення навантаження пам’яті в інших місцях. Якщо ні — потрібно налаштовувати IO, а не пам’ять.
Завдання 8: Підтвердити розклад пулу і ashift (час відновлення частково визначається геометрією)
cr0x@server:~$ zdb -C tank | grep -E 'vdev|ashift' -n | head -n 20
45: vdev_tree:
46: type: 'root'
47: id: 0
58: type: 'mirror'
59: ashift: 12
78: type: 'mirror'
79: ashift: 12
Значення: ashift=12 (4K сектори). Якщо у вас ashift=9 на 4K-нaтивних дисках, ви платите податок на писання завжди, і resilver буде гіршим.
Рішення: Якщо ashift неправильний — виправляйте шляхом перебудови пулу (так, болісно). Не намагайтеся «вилікувати» помилку геометрії налаштуваннями.
Завдання 9: Дізнатися, чи ви обмежені одним HBA або лінком
cr0x@server:~$ lsscsi -t
[0:0:0:0] disk ata:WDC_WD80... /dev/sda sata:0:0:0
[0:0:1:0] disk ata:WDC_WD80... /dev/sdb sata:0:0:1
[0:0:2:0] disk ata:WDC_WD80... /dev/sdc sata:0:0:2
[0:0:3:0] disk ata:WDC_WD80... /dev/sdd sata:0:0:3
[1:0:0:0] disk ata:WDC_WD80... /dev/sde sata:1:0:0
[1:0:1:0] disk ata:ST8000DM004 /dev/sdf sata:1:0:1
Значення: Диски розподілені по двох контролерах. Якщо всі на одному HBA (або одному expander-порту), ви можете його наситити під час resilver.
Рішення: Якщо знайдете єдине місце-горло — зменште паралелізм або заплануйте апаратний ремонт. Налаштування не створять додаткову пропускну здатність, якщо її немає фізично.
Завдання 10: Спостерігати внутрішні шаблони IO ZFS через zpool iostat з латентністю (залежить від OpenZFS)
cr0x@server:~$ zpool iostat -l -v tank 2 2
capacity operations bandwidth total_wait disk_wait
pool alloc free read write read write read write read write
----------------------- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
tank 22.1T 13.5T 18.0K 6.5K 510M 145M 12ms 18ms 8ms 15ms
mirror-0 7.40T 5.10T 12.0K 3.2K 335M 72M 14ms 21ms 10ms 18ms
sda - - 6.0K 1.6K 168M 36M 0ms 0ms 0ms 0ms
sdb - - 6.0K 1.6K 167M 36M 0ms 0ms 0ms 0ms
Значення: «total_wait» включає час очікування у ZFS; «disk_wait» — час на пристрої. Високий total_wait при низькому disk_wait вказує на вузьке місце всередині ZFS; високий disk_wait означає, що пристрої — стіна.
Рішення: Якщо домінує disk_wait — треба обмежувати. Якщо total_wait — дивіться CPU, конкуренцію за блокування або патологічні метадані-навантеження.
Завдання 11: Налаштувати агресивність resilver на Linux (параметри модуля)
У Linux OpenZFS поведінка resilver залежить від параметрів модуля, як-от zfs_resilver_delay і мін/макс часів для скану. Точна доступність залежить від версії; перевірте спочатку, потім змінюйте.
cr0x@server:~$ modinfo zfs | grep -E 'resilver|scan' | head -n 20
parm: zfs_resilver_delay:How long to delay resilvering next extent (int)
parm: zfs_scan_idle:Idle scan delay (int)
parm: zfs_scan_min_time_ms:Minimum scan time per txg (ulong)
parm: zfs_scan_max_time_ms:Maximum scan time per txg (ulong)
Значення: Регулятори на цьому сервері існують. Добре. Тепер ви можете налаштовувати свідомо, а не сліпо копіювати sysctl з допису у блозі з ери старих шпинделів.
Рішення: Якщо затримки продукції страждають — збільшіть затримки або зменшіть час сканування. Якщо resilver надто повільний і у вас є вільний IO — зробіть протилежне.
cr0x@server:~$ cat /sys/module/zfs/parameters/zfs_resilver_delay
2
Значення: Поточна затримка — 2 (одиниці залежать від реалізації; думайте «втримування між extent»). Менші значення примушують працювати агресивніше.
Рішення: Для денного продакшну тримайте ненульову затримку. У нічний час або у надзвичайній ситуації «зробіть усе зараз» — зменшуйте обережно, спостерігаючи за затримками.
Завдання 12: Тимчасово стримати сканування ZFS (Linux)
cr0x@server:~$ cat /sys/module/zfs/parameters/zfs_scan_max_time_ms
30000
Значення: ZFS може витрачати до 30 секунд на сканування за цикл транзакцій. Більше — агресивніше сканує/відновлює; менше — частіше поступається звичайному IO.
Рішення: Якщо продукція таймаутить — знижуйте це значення по невеликих кроках і перевіряйте метрики. Не кидайтесь з 30000 на 1000 і дивуйтеся, чому ETA resilver стало «якось колись у наступному кварталі».
cr0x@server:~$ echo 10000 | sudo tee /sys/module/zfs/parameters/zfs_scan_max_time_ms
10000
Завдання 13: Налаштувати стабільний, малошумний моніторинг прогресу
cr0x@server:~$ watch -n 10 'zpool status tank | sed -n "1,20p"'
Every 10.0s: zpool status tank
pool: tank
state: DEGRADED
scan: resilver in progress since Wed Dec 25 09:12:04 2025
1.46T scanned at 1.05G/s, 501G issued at 360M/s, 3.80T total
501G resilvered, 13.01% done, 0 days 02:12:03 to go
Значення: Ви відстежуєте issued і ETA, а не тільки scanned. Саме цей показник зазвичай корелює з «коли буде відновлено надлишковість».
Рішення: Якщо «scanned» рухається, а «issued» стоїть — ймовірно, ви заблоковані на реконструкції IO або маєте конкуренцію, а не проблема обходу метаданих.
Завдання 14: Переконатися, що ви не створюєте синхронний шторм
cr0x@server:~$ zfs get -o name,property,value -r sync tank | head
NAME PROPERTY VALUE
tank sync standard
tank/db sync standard
tank/vmstore sync always
Значення: Dataset з sync=always змусить більше синхронних записів. Під час resilver це може призвести до значних страждань шпинделів.
Рішення: Якщо sync=always встановлено з вагомих причин (бази даних без правильних бар’єрів, відповідність) — не «виправляйте» це зміною sync. Натомість: переконайтесь, що SLOG здоровий і швидкий, або перемістіть навантаження під час resilver.
Завдання 15: Перевірити, чи відсутній або повільний SLOG (і чи не робить він синхронні записи болючими)
cr0x@server:~$ zpool status tank | sed -n '1,120p'
pool: tank
state: DEGRADED
config:
NAME STATE READ WRITE CKSUM
tank DEGRADED 0 0 0
mirror-0 DEGRADED 0 0 0
sda ONLINE 0 0 0
sdb ONLINE 0 0 0
logs
nvme0n1p2 ONLINE 0 0 0
Значення: SLOG присутній і онлайн. Якщо б він був відсутній/faulted, синхронні навантаження перелилися б на основний пул, жорсткіше конкуруючи з resilver.
Рішення: Якщо SLOG деградований — виправте це в першу чергу для sync-важкої продукції. Швидкий resilver даремний, якщо ваш журнал транзакцій на межі.
Стратегія тюнінгу: швидко відновити без роздавлення затримок
Будьмо чесні: «кращий» пріоритет resilver залежить від того, що ви захищаєте. Для цільового бекапу можна йти на повну швидкість. Для основного пулу баз даних потрібні запобіжні засоби.
Почніть з операційних важелів, а не з регуляторів
Найчистіший тюнінг — той, що ви не робите в sysfs.
- Перемістіть або зменшіть навантаження: обмежте пакетні задачі, призупиніть перебудову індексів, перемістіть аналітику, відкладіть send/receive снапшотів.
- Зупиніть необов’язкову фонову роботу: scrubs, важкі видалення снапшотів, реплікацію, великі
zfs destroy. - Плануйте вікна для завершення resilver: якщо можливо, заміну дисків робіть вночі. Це не шахрайство; це дорослий підхід.
Зрозумійте, що ZFS оптимізує під час resilver
ZFS має зберегти коректність. Також воно намагається тримати пул придатним до використання. Деякі налаштування за замовчуванням консервативні, бо найгірший випадок — некрасивий: resilver може породити величезний випадковий IO, особливо на фрагментованих пулах з багатьма снапшотами.
Два практичні висновки:
- Пропускна здатність — не єдиний метрік. Можна бачити 800MB/s «scanned», тоді як продукція тоне через те, що це насправді багато малих випадкових операцій і чергування.
- Інкрементальність не завжди дешева. Якщо пул сильно фрагментований або має великий churn, стратегія «копіювати тільки живі блоки» все одно зачіпає багато розкиданих областей.
Виберіть політику: робочі години vs режим надзвичайної ситуації
Рекомендую визначити два режими і відпрацювати їх:
- Режим робочих годин: помірна агресивність resilver, прогнозована затримка, довший ETA.
- Режим надзвичайної ситуації: коли надлишковість критично низька (ще один диск показує помилки, RAIDZ під стресом або відома партія слабких дисків), ви погоджуєтеся на більший вплив, щоб завершити швидше.
Жарт №2: Тюнінг resilver як кофеїн — є продуктивна доза, а потім «чую кольори» і нічого не робиться.
Linux OpenZFS регулятори: що вони в реальному житті роблять
Точні імена параметрів і семантика залежать від версії OpenZFS, але загальні теми такі:
- Затримки (наприклад,
zfs_resilver_delay): вводять невелику паузу між чанками resilver IO. Це часто значно знижує хвостову латентність на HDD, бо ламає монополізацію черги. - Часові слайси (наприклад,
zfs_scan_min_time_ms,zfs_scan_max_time_ms): скільки часу за цикл ZFS віддає скану/resilver. Менші значення частіше поступаються звичайному IO. - Поведінка в стані простою (наприклад,
zfs_scan_idle): намагається виявити простій і нарощувати сканування, коли система тиха.
Чого уникати: піднімати паралелізм до рівня, коли дискова черга постійно повна. Так ви перетворите «повільний resilver» на «resilver, який ніколи не завершиться через таймаути й скиди».
Регулятори у FreeBSD і загальний підхід
У FreeBSD зазвичай використовують sysctl-контролі і покладаються на поведінку планувальника IO ядра. Філософія схожа: формувати роботу скану/resilver так, щоб вона поступалася foreground IO. Специфіка інша; робочий процес — той самий: вимірюйте, змінюйте одну річ, спостерігайте p99 затримку і issued rate.
Коли «швидше» насправді повільніше: пастка seek-storm
На HDD пулах resilver може стати генератором випадкового IO. Якщо підсилити агресивність, ви збільшуєте кількість незавершених IO і диск робить більше перемикань головки, що знижує ефективну пропускну здатність. Ви побачите, що «issued» вирівнюється, а await росте. Це знак, що ви вдарилися у «стіну перемикань».
На SSD/NVMe пастка інша: можна наситити контролерні черги і вкрасти IO-бюджет у заточених під латентність читань. Тут помірне обмеження може зберегти p99 затримки з невеликим втратою часу відновлення.
Scrub vs resilver: арбітраж і планування
Scrub читає дані і перевіряє контрольні суми; resilver реконструює надлишковість. Обидва — «завдання класу скану» у ZFS. Якщо запускати їх разом, ви по суті просите ті самі диски виконувати дві великі фонoві роботи і одночасно обслуговувати продукцію. Це не хоробрість. Це понаднормова робота для вашої IO-підсистеми без оплати.
Правила, яких я дотримуюсь
- Ніколи не запускайте scrub під час активного resilver, якщо у вас немає дуже специфічної причини (наприклад, розслідування прихованої корупції на пулі з відомо проблемним обладнанням) і ви не прийняли на себе падіння продуктивності.
- Після resilver подумайте про scrub, якщо ваша операційна політика цього вимагає, але заплануйте його на менш завантажений час.
- Не дозволяйте автоматизації накладати завдання: якщо у вас щотижневі scrubs, переконайтесь, що вони ставляться на паузу, коли пул деградований або триває resilver.
Чому ZFS може виглядати «завантаженим», навіть якщо пропускна здатність низька
Scrub/resilver може бути метаданево-залежним: багато малих IO, перевірка контрольних сум і облік. На фрагментованому пулі це може бути завданням з високим IOPS та невражаючим MB/s. Це нормально. Ненормально — дозволяти цьому позбавляти пріоритету ваші foreground-читання.
Три корпоративні міні-історії з практики
Міні-історія 1: Інцидент через неправильне припущення
Компанія мала мішаний парк: деякі вузли зберігання були mirror vdev на SSD, деякі — RAIDZ2 на HDD. Операції трактували їх як «однакова ZFS». Моніторинг навіть мав одну панель «resilver rate» для всіх вузлів. Було красиво. І брехливо через опущення.
Одного дня в HDD RAIDZ2 vdev відмовив диск. Інженер на чергуванні замінив його і вирішив «прискорити», застосувавши ті самі параметри resilver, що добре працювали на SSD-вузлах. Глибина черг зросла, але швидкість «scanned» виглядала фантастично, і всі заспокоїлись.
Через годину клієнтський API почав час від часу таймаутити. База даних не впала; вона просто стала достатньо повільною, щоб вмикати таймаути на верхньому рівні. Корінна причина не в пропускній здатності. Це був seek-storm. HDD були зафіксовані майже на постійній загрузці з високим await. Foreground-читання шикувалися за фоновим rebuild IO і малими sync-записами.
Неправильне припущення було тонким: «Якщо SSD любить більшу паралельність, HDD теж її полюбить.» HDD цього не любить. HDD любить послідовність, паузи й не просити робити 40 речей одночасно.
Виправлення було нудним: повернути консервативні ліміти скану, зупинити scrub, що також стартував по розкладу, і тимчасово перенести пакетну задачу на інший кластер. Resilver тривав довше, ніж у «швидкому режимі», але інцидент закінчився, бо p99 затримка повернулася під контроль.
Міні-історія 2: Оптимізація, що обернулася проти
Інша організація мала звичку: коли пул деградував, вони відразу «допомагали», призупиняючи нормальну обробку навантаження і дозволяючи resilver працювати максимально. Логіка: мінімізувати час під ризиком. На папері — слушно.
Потім вони стали хитріші. Побудували автоматизацію, яка при виявленні деградованого пулу підвищувала агресивність resilver і паралельно запускала очистку datasetів («звільнити місце, щоб ZFS легше працював»). Та очистка включала масові видалення снапшотів — багато метаданих і frees — у той час, як resilver обходив ті самі метадані-структури.
Результат — ідеальна буря: пул витрачав багато CPU на метадані, а диски були завалені випадковим IO. Швидкість issued resilver фактично впала, хоча система «виглядала завантаженою». Автоматизація тримала систему в цьому стані годинами, бо зупинялася тільки після завершення resilver.
Вони не спричинили втрати даних, але завдали непотрібного болю клієнтам і продовжили період деградації. Оптимізація обернулася проти, бо поєднала дві IO-інтенсивні, метаданево важкі операції в період, коли пул був найменш здатний це витримати.
Виправлення — політика: під час resilver не запускати видалення снапшотів, великі zfs destroy чи інші rebalancing-подібні роботи. Якщо треба звільнити місце — робіть це до деградації, а не під час.
Міні-історія 3: Нудна, але правильна практика, що врятувала ситуацію
Команда з фінансових послуг використовувала ZFS для зберігання VM. Їх SLO з простих: тримати затримку зберігання в вузьких межах під торговими годинами. Було також правило надійності: ніколи не тримати пул деградованим довше, ніж треба. Ці цілі конфліктували. Тому вони виписали це як явний операційний план.
Коли диск впав, на черговому виконали три речі автоматично. По-перше: підтвердити, чи це транзитна проблема шляху або реальна відмова диска. По-друге: почати заміну і resilver негайно. По-третє: переключити пул на «режим робочих годин» і заморозити неважливі пакетні роботи.
У них також був запис у runbook: якщо p99 затримка перетинає поріг більше 10 хвилин — зменшити scan max time по кроках і переоцінити. Все. Жодних подвигів. Жодного археологічного копирсання у sysctl о 2:00.
Resilver тривав довше, ніж у повно-агресивному режимі, але торгові системи залишались стабільними. Після години роботи вони перемкнулися в «режим надзвичайної ситуації» і дозволили більш агресивне завершення вночі.
Нудна практика була задокументована, відпрацьована переключення — і дисципліна не змінювати п’ять речей одночасно. Це врятувало їх від перетворення відмови обладнання на порушення SLA.
Поширені помилки: симптом → корінна причина → виправлення
Це не теоретично. Це способи, якими люди випадково підпалюють своє зберігання, а потім звинувачують вогонь у тому, що він гарячий.
1) Симптом: «Resilver застряг на 0% issued, але scanned продовжує рухатися»
- Корінна причина: обходи метаданих тривають, але фактичний реконструкційний IO блокується помилками пристрою, повільним замінним диском або екстремальною конкуренцією.
- Виправлення: перевірте
zpool status -vна помилки; перевірте стан замінного пристрою і зв’язку; погляньте наiostat -xawait; зменшіть агресивність скану й зупиніть конкуруючі роботи.
2) Симптом: «Додатки таймаутять; диски показують 99% util; здається, resilver дуже «швидкий»»
- Корінна причина: монополізація черги/seek-storm; метрика сканування вводить в оману; foreground IO чекає за rebuild IO.
- Виправлення: підвищте resilver delay / зменшіть scan max time; зупиніть scrub; зменшіть пакетні записи; дивіться p99 затримку, а не MB/s.
3) Симптом: «Замінний диск продовжує fault під час resilver»
- Корінна причина: поганий диск, проблемний кабель/бэкплейн або проблеми з живленням; resilver — перший тривалий стрес-тест для нього.
- Виправлення: замініть диск ще раз, поміняйте слот/кабель, перевірте SMART-логи помилок і логи контролера. Не пробуйте знову й знову з тим самим ненадійним шляхом.
4) Симптом: «Resilver надзвичайно повільний на майже заповненому пулі»
- Корінна причина: велика фрагментація і стрес аллокатора; ZFS має менше свободи розміщувати реконструйовані блоки ефективно; метадані зростають.
- Виправлення: тримайте пули нижче розумної заповненості (правило: уникайте життя вище ≈80% для багатьох навантажень); додавайте vdev до того, як стане критично; не починайте масових операцій з очищення під час resilver.
5) Симптом: «Швидкість resilver дико змінюється годину до години»
- Корінна причина: змінні шаблони навантаження (вікно бекапу, компакти, send снапшотів, чекпоїнти БД) і механізм виявлення простою ZFS.
- Виправлення: корелюйте зі розкладом навантаження; фіксуйте агресивність скану в робочі години; за бажанням підвищуйте агресивність у відомі спокійні вікна.
6) Симптом: «Resilver сповільнився після додавання спеціального пристрою»
- Корінна причина: спеціальний пристрій концентрує метадані/малі блоки; якщо він повільний, перевантажений або теж деградований — стає вузьким місцем.
- Виправлення: переконайтесь, що спеціальні пристрої надлишкові і швидкі; моніторьте їхню латентність окремо; не дозволяйте їм заповнюватись; ставтеся до них як до повноцінного сховища, а не «бонусного SSD».
7) Симптом: «Ми настроїли для швидкого resilver, але він зайняв більше часу»
- Корінна причина: надто агресивний паралелізм викликає треш; penalty seek на HDD; збільшення повторних спроб; конкуренція планувальника IO.
- Виправлення: відступіть від агресивності, поки issued rate не зросте, а await не впаде; вимірюйте, не вгадуйте.
Чеклісти / покроковий план
Покроковий план: коли диск відмовив у продакшні
- Підтвердіть режим відмови. Це реальний відмова диска чи проблема шляху/контролера? Перевірте
zpool status -vта логи ОС. - Замініть диск і почніть resilver. Не чекайте на збірку комітету для фізики.
- Зупиніть конкуруючі фонові задачі. Поставте на паузу scrubs, важку реплікацію, видалення снапшотів і масове обслуговування.
- Виміряйте вплив на продукцію. Використовуйте затримки додатків і disk await; не покладайтеся лише на MB/s resilver.
- Виберіть режим: тюнінг для робочих годин або режим надзвичайної ситуації, згідно з ризиком надлишковості й SLO клієнта.
- Змінюйте одну настройку за раз. Модифікуйте scan max time або resilver delay невеликими кроками; спостерігайте 10–15 хвилин.
- Перевірте прогрес. Issued і resilvered байти мають рухатися; лічильники помилок повинні бути тихими.
- Після завершення перевірте здоров’я. Пул має бути ONLINE, без нових помилок; заплануйте scrub, якщо політика цього вимагає.
Чекліст: режим робочих годин (захист затримки)
- Scrub зупинено або відкладено
- Пакетні задачі призупинені або обмежені за швидкістю
- Resilver delay ненульовий
- Scan max time помірно зменшено
- Спостерігайте p95/p99 затримки, disk await і issued rate
Чекліст: режим надзвичайної ситуації (швидке завершення)
- Підтвердити, що ризик надлишковості це виправдовує (кілька попереджень, RAIDZ під стресом або масові відмови)
- Збільшити scan max time і зменшити затримки
- За потреби тимчасово призупинити неважливі сервіси для прискорення завершення
- Перевірити охолодження; спостерігати температуру дисків і помилки контролера
Питання та відповіді
1) Чи завжди ZFS resilver інкрементальний?
Часто так: ZFS може відновлювати лише блоки, що мають значення, згідно з метаданими. Але макет пулу, фрагментація та спосіб вилучення пристрою можуть зробити його більш близьким до повного читання пристрою на практиці.
2) Чому «scanned» рухається швидше за «issued» під час resilver?
Сканування — це обхід метаданих; issued — фактичні реконструкційні IO. Якщо issued відстає, ви обмежені дисковим IO, конкуренцією або проблемами пристрою.
3) Чи варто призупиняти продукцію, щоб пришвидшити resilver?
Для систем, що обслуговують клієнтів, спершу краще сформувати форму resilver. Призупинення навантаження може допомогти, але це грубий інструмент. Використовуйте його, коли ризик надлишковості високий або ви можете безпечно знизити трафік.
4) Чи безпечно налаштовувати zfs_scan_max_time_ms та zfs_resilver_delay вживу?
Зазвичай так у Linux через sysfs-параметри модуля, але ставтеся до цього як до управління змінами: невеликі кроки, вимірювання впливу й запис змін, щоб можна було відкотитися.
5) Чому resilver став повільнішим, коли пул заповнений понад 80%?
Гнучкість аллокатора падає і фрагментація зростає, що породжує випадковий IO і метаданеві накладні витрати. Це не моральний провал; це геометрія і ентропія.
6) Чи зеркала (mirrors) відновлюються швидше за RAIDZ?
Зазвичай так. Mirrors мають простішу реконструкцію і часто кращу паралельність. RAIDZ може потребувати більше паритетних обчислень і створювати більшу IO-ампліфікацію, залежно від навантаження і фрагментації.
7) Чи варто запускати scrub одразу після завершення resilver?
Якщо ваша операційна політика вимагає періодичних scrub, заплануйте його — просто не одразу, якщо система ще гаряча і продукція висока. Дайте пулу час відпочити.
8) Який єдиний найкращий метрік для спостереження?
Для ризику: час до відновлення надлишковості (прогрес issued/resilvered). Для впливу на клієнтів: p99 затримка і disk await/глибина черги.
9) Чи можна зробити resilver швидшим додаванням L2ARC?
Не надійно. L2ARC допомагає кешувати читання, але може додати записів і накладних метаданих. Під час resilver вузьке місце зазвичай — disk IO і реконструкція, а не «більше кешу».
10) Чи робить SLOG resilver швидшим?
Опосередковано. Хороший SLOG може захистити латентність sync-записів, тож продукція страждатиме менше, що дозволяє вам тримати resilver агресивнішим без шкоди для додатків. Він не пришвидшить сам перебіг реконструкції магічно.
Висновок: наступні кроки, які можна зробити цього тижня
Пріоритет resilver — не магічна настройка; це операції з обмеженням швидкості. Мета проста: відновити надлишковість досить швидко, щоб зменшити ризик, але тримати продукційні IO передбачуваними, щоб інцидент не породив сиквел.
Наступні кроки, що дають негайний ефект:
- Запишіть два режими (робочі години проти надзвичайного) з вибраними налаштуваннями scan/resilver і правилами їх застосування.
- Додайте моніторинг, що графує прогрес issued/resilvered поруч із p99 затримкою й disk await.
- Аудитуйте парк на предмет неочікуваних SMR-моделей, майже заповнених пулів і розкладів scrub, що ігнорують деградований стан.
- Потренуйтеся раз на некритичному пулі: замініть диск, спостерігайте поведінку, змініть один регулятор і зафіксуйте результати.