Ви замінюєте зіпсований диск, запускаєте resilver і очікуєте бачити рівний потік сотень MB/s. Натомість відновлення починається швидко, потім повільніє, потім коливається, ніби його регулює невидимий комітет. Тим часом латентність ваших додатків йде вбік, а менеджмент питає, чому «новий диск повільний».
Неприємна правда така: швидкість resilver — це системна проблема. Resilver у ZFS не відбувається в ізольованому середовищі. Він конкурує з реальним навантаженням, обходить реальні метадані й обмежується геометрією vdev, історією алокацій і фізикою дрібних випадкових читань — навіть коли сторона запису виглядає «послідовною».
Що насправді означає «послідовний resilver» (і чого це не означає)
Коли люди кажуть «послідовний resilver», зазвичай мають на увазі: «ZFS відновить, читаючи великі сусідні фрагменти зі здорових дисків і записуючи великі сусідні фрагменти на заміну». Це мрія. І іноді так і відбувається.
Але послідовне відновлення — це не обіцянка того, що базовий патерн I/O скрізь і завжди чисто послідовний. Це стратегія: пріоритетний обхід space map-ів і метаданих алокації, щоб відновити лише те, що виділено, і робити це так, щоб групувати роботу й мінімізувати переміщення голівок.
Що це таке:
- Метод відновлення саме виділених даних, а не всього адресного простору пристрою (на відміну від старих RAID-скриптів).
- Найкраща зусилля спрямована на мінімізацію випадкових I/O шляхом обходу metaslab-ів і дерев алокацій у порядку, дружньому до локальності.
- Навантаження, яке часто є обмеженим читаннями за стороною виживших пристроїв і обходом метаданих, навіть якщо записи на новий диск виглядають послідовними.
Чого це не є:
- Не «копіювати весь диск від LBA 0 і вгору». ZFS не відновлює вільний простір і не зобов’язаний цього робити.
- Не «одна нитка, один потік». Resilver конвеєрний і конкурентний: читання, перевірка контрольних сум, декомпресія, реконструкція парності (RAIDZ) і записи працюють одночасно.
- Не «нечутливе до фрагментації». ZFS може бути послідовним «на папері», але змушений робити розкидані читання, бо дані фізично розкидані.
Час resilver — це час, потрібний, щоб знайти важливі блоки, прочитати їх надійно, реконструювати правильно й записати так, щоб пул лишався консистентним. «MB/s диска» — лише одна змінна, і рідко вона є визначальною, коли ситуація погіршується.
Чому «MB/s диска» — невірна одиниця для планування resilver
Тести послідовної пропускної здатності припускають, що ви робите щось на кшталт dd по чистому пристрою. Resilver ближчий до суміші операцій:
- керований метаданими пошук (space maps, вказівники блоків, непрямі блоки)
- читання різних розмірів (records, часткові записи, дрібні блоки метаданих)
- перевірка контрольної суми для кожного прочитаного блоку
- опційна декомпресія (шлях читання) і компресія (шлях запису)
- паритетні обчислення RAIDZ (CPU + пропускна здатність пам’яті)
- черговість і планування між учасниками vdev
- алокація запису й оновлення metaslab на цільовому диску
Ось чому два пули, побудовані з ідентичних дисків, можуть відновлюватися з радикально різною швидкістю:
- Пул A: заповнений на 40%, низька фрагментація, recordsize підігнано під навантаження, широкі дзеркала, достатній запас IOPS. Resilver виглядає «послідовним».
- Пул B: заповнений на 85%, роки циклів записів, безліч дрібних блоків, RAIDZ із патологічним підсиленням читань і важке фонова навантаження. Resilver виглядає як криваве місце подій.
Навіть в одному пулі швидкість resilver може змінюватися від години до години, бо вузьке місце переміщується: спочатку читаєте великі екстенти швидко, потім натрапляєте на метадані й раптом обмежені IOPS. Індикатор прогресу рухається, але ваші очікування не повинні бути сталими.
Жарт №1: Якщо ви вважаєте, що швидкість resilver — це «просто MB/s диска», у мене є масив, який бенчмаркується на 10 GB/s — до того моменту, як ним реально користуються.
Отже, на що планувати замість MB/s? Думайте про обмеження:
- Ліміт читальних IOPS у виживших членів vdev (часто саме він обмежує).
- Поведінка з дрібними блоками (метадані, таблиці dedup, влучення/промахи special vdev).
- Історія алокацій (фрагментація, розподіл вільного простору, розміри metaslab).
- Паралельність (нитки resilver, конвеєр ZIO, поведінка ARC).
- Операційний бюджет: скільки латентності ви готові терпіти в продукції під час роботи.
Цікаві факти та трохи історичного контексту
- ZFS популяризував «відновлення лише виділених даних» як ключову ідею дизайну, уникаючи класичної поведінки RAID-контролерів «скануй весь диск».
- Scrub та resilver використовують одну й ту ж машину, але resilver мусить ще й писати та оновлювати стан, що змінює шаблони конкуренції в I/O-пайплайні.
- Resilver у RAIDZ має внутрішнє підсилення читань, бо реконструкція блоку часто вимагає читання кількох колонок; дзеркала частіше можуть читати з однієї сторони.
- Контрольні суми вказівників блоків критичні: ZFS читає й перевіряє дані наскрізь, тож «швидка, але тиха корупція» не проходить.
- Вибір ashift став болючішим з часом, коли диски перейшли на фізичні сектора 4K; невідповідність вирівнювання може перетворити «послідовну» роботу на додаткові цикли читання-модифікації-запису.
- Space map-и еволюціонували, щоб краще відстежувати вільні/виділені діапазони, і ця бухгалтерія безпосередньо впливає на ефективність обходу виділеного простору під час відновлення.
- Покращення видалення пристрою та послідовного resilver у OpenZFS зробили відновлення менш болісним, ніж ранні підходи «сканувати все» — якщо макет пулу співпрацює.
- Special vdev змінили гру для пулів з інтенсивними метаданими: швидкість resilver може значно покращитися, якщо метадані обслуговуються швидко, але лише якщо special vdev здоровий і розмір підібрано правильно.
Справжні вузькі місця: де фактично витрачається час при resilver
1) Виживші диски роблять важку частину
Зазвичай замінний диск не є обмежувальним фактором. Під час resilver пул має читати всі блоки, які належали збоювшому диску, з виживших членів. Ці читання часто:
- розкидані по адресному простору vdev (фрагментація)
- різного розміру, включно з численними дрібними читаннями метаданих
- конкурують з вашим продукційним навантаженням
Тому ви можете поставити новий швидкий диск, і це не допоможе, бо старі диски шукають по платівках наче повернулися у 2007 рік.
2) RAIDZ-паритетна реконструкція підсилює читання
У дзеркал часто достатньо однієї доброї копії для відновлення блоку. У RAIDZ реконструкція блоку зазвичай вимагає читання інших колонок у стріпі. Ось чому «одні й ті ж сирі TB на тих самих дисках» не означають «один і той самий час resilver». RAIDZ жертвує ефективністю ємності заради складнішої поведінки при відновленні, і саме тут ви платите цю ціну.
3) Фрагментація перетворює послідовний намір на випадкову реальність
Послідовний resilver намагається обходити алокації по порядку, але якщо ваші дані писалися з інтенсивним перемішуванням (образи VM, бази даних з частими перезаписами, об’єктні сховища з видаленнями), «наступний блок» може бути зовсім не поруч із попереднім на диску.
Два практичні наслідки:
- Ваші читання стають обмежені IOPS, а не пропускною здатністю.
- Пул може показувати «низькі MB/s», але бути все ще насиченим (високе завантаження, висока латентність).
4) Метадані можуть домінувати в хвості
Перша половина resilver часто виглядає швидше, бо копіюються великі, більш суміжні екстенти. Наприкінці стається дивина: дрібні блоки, непрямі блоки, dnode-и, spill-блоки, оновлення space map-ів. Саме тоді відсоток прогресу рухається повільно, і всі починають звинувачувати диски.
5) Компресія, контрольні суми та CPU — не безкоштовні
На сучасних CPU витрати на контрольні суми та компресію зазвичай керовані, доки не стають такими. Якщо ви виконуєте обчислення парності RAIDZ плюс високу компресію на завантаженій машині, CPU може стати вузьким місцем. Це проявляється як:
- диски не повністю завантажені (низький %util), а resilver повільний
- високе системне CPU, час у kernel або softirq залежно від платформи
- тиск на ARC, що призводить до додаткових читань з диска
6) Пул — це спільний ресурс; resilver конкурує
Якщо дозволити resilver працювати «на повну» в пікові години, пул може стати I/O-захопником. ZFS намагається бути справедливим, але справедливість — не те саме, що «ваша база даних залишається щасливою». Ви повинні вирішити, що оптимізуєте: найшвидше відновлення чи прийнятну латентність у продукції. Намагатися отримати обидва без вимірювань — це якраз шлях до нічого з того.
Жарт №2: Resilver як дорожні роботи: його завжди планують на той час, коли ви вже спізнюєтеся.
Одна ідея про надійність, яку варто тримати на стіні
Сподівання — це не стратегія.
— James Cameron
Це не тільки про ZFS, але це болісно доречно: не сподівайтесь, що ваш resilver буде швидким. Вимірюйте, проєктуйте і практикуйте.
Швидкий план діагностики
Це маршрут тріажу, коли вам пишуть: «resilver повільний». Не починайте бездумно крутити налаштування. Знайдіть лімітатор.
Спочатку: підтвердьте, який саме тип повільності у вас
- Низькі MB/s, але високе завантаження диска? Ймовірно, ви обмежені IOPS/переміщеннями голівки (фрагментація, дрібні блоки, читання RAIDZ).
- Низькі MB/s і низьке завантаження диска? Ймовірно, ви обмежені CPU, блокуванням або чимось іншим (промахи ARC, special vdev, планувальник, налаштування).
- Великі сплески латентності у клієнтів? Resilver конкурує з продукцією; потрібно бюджетувати I/O.
По-друге: ізолюйте, що саме обмежує — читання чи запис
- Якщо здорові диски показують багато операцій читання і високу латентність: обмеження на боці читання.
- Якщо новий диск показує високу латентність запису або помилки: обмежує шлях запису цілі (поганий диск, кабелі, HBA, поведінка SMR).
По-третє: перевірте на патології
- Є помилки контрольних сум під час resilver? Перестаньте думати лише про «продуктивність». Може бути проблема надійності.
- Є SMR-диски, дивна прошивка або енергоменеджмент? Поведінка при відновленні може впасти під тривалим записом.
- Пул майже повний або сильно фрагментований? Очікуйте хвостової латентності й повільного завершення.
По-четверте: визначте операційну мету
- Мета A: закінчити resilver якнайшвидше (готові терпіти вплив на користувачів).
- Мета B: зберегти стабільність продукції (готові терпіти довший resilver).
Зробіть це рішення явно, потім налаштовуйте. Інакше ви будете коливатись між «занадто повільно» і «користувачі кричать» і вдавати, що це таємниця.
Практичні завдання: команди, виводи та рішення (12+)
Нижче — практичні завдання, які я використовую в продакшені. Кожне включає (1) команду, (2) що означає вивід, (3) рішення, яке ви приймаєте.
Завдання 1: Підтвердити стан resilver і швидкість сканування
cr0x@server:~$ zpool status -v tank
pool: tank
state: DEGRADED
status: One or more devices is currently being resilvered.
scan: resilver in progress since Tue Dec 24 11:02:12 2025
1.23T scanned at 410M/s, 612G issued at 204M/s, 3.10T total
148G resilvered, 19.11% done, 0 days 03:41:22 to go
config:
NAME STATE READ WRITE CKSUM
tank DEGRADED 0 0 0
raidz2-0 DEGRADED 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
sdg ONLINE 0 0 0
sdh ONLINE 0 0 0
sdi ONLINE 0 0 0
sdj ONLINE 0 0 0
sdk ONLINE 0 0 0
sdl ONLINE 0 0 0
sdm ONLINE 0 0 0
sdn ONLINE 0 0 0
sdo ONLINE 0 0 0
sdp ONLINE 0 0 0
sdq ONLINE 0 0 0
sdr ONLINE 0 0 0
sds ONLINE 0 0 0
sdt ONLINE 0 0 0
sdu ONLINE 0 0 0
sdv ONLINE 0 0 0
sdw ONLINE 0 0 0
sdx ONLINE 0 0 0
sdy ONLINE 0 0 0
sdz ONLINE 0 0 0
sdaa ONLINE 0 0 0
sdab ONLINE 0 0 0
sdac ONLINE 0 0 0
sdad ONLINE 0 0 0
sdae ONLINE 0 0 0
sdaf ONLINE 0 0 0
sdag ONLINE 0 0 0
sdah ONLINE 0 0 0
sdai ONLINE 0 0 0
sdaj ONLINE 0 0 0
sdak ONLINE 0 0 0
sdal ONLINE 0 0 0
sdam ONLINE 0 0 0
sdan ONLINE 0 0 0
sdao ONLINE 0 0 0
sdap ONLINE 0 0 0
sdaq ONLINE 0 0 0
sdar ONLINE 0 0 0
sdas ONLINE 0 0 0
sdat ONLINE 0 0 0
sdau ONLINE 0 0 0
sdav ONLINE 0 0 0
sdaw ONLINE 0 0 0
sdax ONLINE 0 0 0
sday ONLINE 0 0 0
sdaz ONLINE 0 0 0
sdbb ONLINE 0 0 0
sdbc ONLINE 0 0 0
sdbd ONLINE 0 0 0
sdbe ONLINE 0 0 0
sdbf ONLINE 0 0 0
sdbg ONLINE 0 0 0
sdbh ONLINE 0 0 0
sdbi ONLINE 0 0 0
sdbj ONLINE 0 0 0
sdbk ONLINE 0 0 0
sdbl ONLINE 0 0 0
sdbm ONLINE 0 0 0
sdbn ONLINE 0 0 0
sdbo ONLINE 0 0 0
sdbp ONLINE 0 0 0
sdbq ONLINE 0 0 0
sdbr ONLINE 0 0 0
sdbs ONLINE 0 0 0
sdbt ONLINE 0 0 0
sdbu ONLINE 0 0 0
sdbv ONLINE 0 0 0
sdbw ONLINE 0 0 0
sdbx ONLINE 0 0 0
sdby ONLINE 0 0 0
sdbz ONLINE 0 0 0
sdc0 ONLINE 0 0 0
sdc1 ONLINE 0 0 0
sdc2 ONLINE 0 0 0
sdc3 ONLINE 0 0 0
sdc4 ONLINE 0 0 0
sdc5 ONLINE 0 0 0
sdc6 ONLINE 0 0 0
sdc7 ONLINE 0 0 0
sdc8 ONLINE 0 0 0
sdc9 ONLINE 0 0 0
sdd0 ONLINE 0 0 0
sdd1 ONLINE 0 0 0
sdd2 ONLINE 0 0 0
sdd3 ONLINE 0 0 0
sdd4 ONLINE 0 0 0
sdd5 ONLINE 0 0 0
sdd6 ONLINE 0 0 0
sdd7 ONLINE 0 0 0
sdd8 ONLINE 0 0 0
sdd9 ONLINE 0 0 0
sde0 ONLINE 0 0 0
sde1 ONLINE 0 0 0
sde2 ONLINE 0 0 0
sde3 ONLINE 0 0 0
sde4 ONLINE 0 0 0
sde5 ONLINE 0 0 0
sde6 ONLINE 0 0 0
sde7 ONLINE 0 0 0
sde8 ONLINE 0 0 0
sde9 ONLINE 0 0 0
sdf0 ONLINE 0 0 0
sdf1 ONLINE 0 0 0
sdf2 ONLINE 0 0 0
sdf3 ONLINE 0 0 0
sdf4 ONLINE 0 0 0
sdf5 ONLINE 0 0 0
sdf6 ONLINE 0 0 0
sdf7 ONLINE 0 0 0
sdf8 ONLINE 0 0 0
sdf9 ONLINE 0 0 0
sdg0 ONLINE 0 0 0
sdg1 ONLINE 0 0 0
replacing-1 ONLINE 0 0 0
sdxX ONLINE 0 0 0
sdnew ONLINE 0 0 0
errors: No known data errors
Значення: «scanned» проти «issued» показує, скільки обходу метаданих відбувається проти фактичної реконструкції даних. Якщо scanned велике, а issued мале, багато часу йде на бухгалтерію та переміщення голівок.
Рішення: Якщо «issued» набагато нижчий, ніж диски можуть зробити, шукайте лімітери IOPS/латентності (фрагментація, дрібні блоки, RAIDZ). Якщо з’являються помилки, переключіться з режиму продуктивності на режим цілісності даних негайно.
Завдання 2: Стежити за I/O по vdev під час resilver
cr0x@server:~$ zpool iostat -v tank 1
capacity operations bandwidth
pool alloc free read write read write
-------------------------- ----- ----- ----- ----- ----- -----
tank 51.2T 13.8T 8.12K 1.90K 812M 162M
raidz2-0 51.2T 13.8T 8.12K 1.90K 812M 162M
sda - - 310 75 31.2M 6.1M
sdb - - 298 72 30.8M 6.0M
sdc - - 315 76 31.4M 6.2M
...
sdnew - - 12 980 1.1M 98.4M
-------------------------- ----- ----- ----- ----- ----- -----
Значення: Здорові диски виконують багато читань; новий диск в основному пише. Якщо операцій читання багато, а read MB/s на диск низькі — ви обмежені IOPS і шукаєте.
Рішення: Якщо read MB/s по диску мізерні, але ops високі, не чекайте лінійної швидкості. Розгляньте обмеження resilver для захисту латентності або планування в позапікові години; налаштування «щоб було швидше» не переможе фізику.
Завдання 3: Перевірити латентність і насичення на рівні диска
cr0x@server:~$ iostat -x 1 3
Device r/s w/s rkB/s wkB/s await aqu-sz %util
sda 310.0 70.0 32000 6200 28.4 8.2 99.0
sdb 295.0 68.0 30800 6000 30.1 8.5 98.7
sdnew 10.0 980.0 1100 102000 12.7 2.1 72.4
Значення: Старі диски навантажені ~99% з ~30ms await. Це класичне обмеження переміщеннями голівки / IOPS. Новий диск не насичений.
Рішення: Вузьке місце — читальні операції виживших дисків. Якщо латентність продукції важлива, обмежте агресивність resilver замість переслідування пропускної здатності нового диска.
Завдання 4: Перевірити стан пулу та лічильники помилок
cr0x@server:~$ zpool status tank
pool: tank
state: DEGRADED
scan: resilver in progress since Tue Dec 24 11:02:12 2025
config:
NAME STATE READ WRITE CKSUM
tank DEGRADED 0 0 0
raidz2-0 DEGRADED 0 0 0
sda ONLINE 0 0 0
sdb ONLINE 0 0 2
sdnew ONLINE 0 0 0
errors: No known data errors
Значення: CKSUM-помилки на вижившому диску під час resilver — тривожний сигнал. Навіть якщо ZFS може їх виправити, це дорого обходиться й несе ризик.
Рішення: Перевірте SMART, кабелі та логи HBA. Якщо помилки зростають, припиніть оптимізацію швидкості й почніть готуватися до можливої додаткової відмови й втрати даних.
Завдання 5: Перевірити SMART для заміни та навантажених виживших
cr0x@server:~$ sudo smartctl -a /dev/sdnew | sed -n '1,80p'
=== START OF INFORMATION SECTION ===
Device Model: ST18000NM000J
Firmware Version: SN05
User Capacity: 18,000,207,937,536 bytes
Sector Sizes: 512 bytes logical, 4096 bytes physical
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 - 0
197 Current_Pending_Sector 100 100 000 Old_age Always - 0
199 UDMA_CRC_Error_Count 200 200 000 Old_age Always - 12
Значення: CRC-помилки часто вказують на кабелювання/бэкплейн/HBA-шлях. Під час resilver флюктуації лінку можуть виглядати як «випадкова повільність».
Рішення: Якщо лічильники CRC ростуть під навантаженням, пересадіть/заміни кабелі або перемістіть у інший відсік. Не продовжуйте resilver через ненадійне з’єднання.
Завдання 6: Визначити ashift та топ-рівневу структуру vdev
cr0x@server:~$ zdb -C tank | egrep -A3 'ashift|vdev_tree|type'
vdev_tree:
type: 'root'
id: 0
ashift: 12
Значення: ashift=12 означає 4K сектори. Якщо це неправильно (наприклад, 9 на 4K-дисках), resilver може страждати від штрафів вирівнювання і зайвих I/O циклів.
Рішення: Якщо ashift неправильний, «виправлення» зазвичай означає міграцію або повторну побудову, а не просте налаштування. Плануйте це; не сперечайтеся з геометрією.
Завдання 7: Перевірити фрагментацію пулу та заповненість
cr0x@server:~$ zpool list -o name,size,alloc,free,frag,health tank
NAME SIZE ALLOC FREE FRAG HEALTH
tank 65.0T 51.2T 13.8T 42% DEGRADED
Значення: Висока фрагментація збільшує кількість «скакуючих» читань. Великий відсоток алокації зменшує доступний суміжний простір і може погіршити поведінку алокації під час записів.
Рішення: Якщо frag і alloc високі, очікуйте повільний хвіст resilver. Розгляньте додавання ємності або ребаланс довго до наступної відмови.
Завдання 8: Переглянути властивості dataset, що змінюють форму блоків
cr0x@server:~$ zfs get -o name,property,value -s local recordsize,compression,checksum tank/vmstore
NAME PROPERTY VALUE
tank/vmstore recordsize 128K
tank/vmstore compression lz4
tank/vmstore checksum on
Значення: recordsize впливає на кількість блоків і їхній розмір. Дрібні блоки збільшують метадані й потреби в IOPS; великі блоки можуть покращити послідовність для стрімінгових навантажень.
Рішення: Якщо dataset обслуговує дрібні випадкові I/O (VM, БД), recordsize може не відповідати; але змінити його «на ходу» не переписавши дані не вдасться. Плануйте міграцію або вікно перепису, якщо потрібний інший профіль блоків.
Завдання 9: Перевірити special vdev і його стан (прискорення метаданих)
cr0x@server:~$ zpool status tank | sed -n '1,80p'
pool: tank
state: DEGRADED
config:
NAME STATE READ WRITE CKSUM
tank DEGRADED 0 0 0
special ONLINE 0 0 0
nvme0n1p1 ONLINE 0 0 0
nvme1n1p1 ONLINE 0 0 0
raidz2-0 DEGRADED 0 0 0
...
Значення: Special vdev може радикально вплинути на продуктивність resilver, обслуговуючи метадані швидко. Якщо він відсутній або нездоровий, запити метаданих повертаються на HDD, і хвіст стає жорстким.
Рішення: Якщо ваше навантаження важке на метадані і у вас немає special vdev, розгляньте його проєктування при наступному апгрейді. Якщо він є — захищайте його як виробничу таємницю.
Завдання 10: Підтвердити тиск ARC і запас пам’яті
cr0x@server:~$ arcstat 1 3
time read miss miss% dmis dm% pmis pm% mmis mm% arcsz c
11:10:01 6120 1480 24 820 55 60 4 600 41 112G 128G
11:10:02 5988 1622 27 910 56 72 4 640 39 112G 128G
11:10:03 6210 1588 25 880 55 55 3 653 41 112G 128G
Значення: Високі коефіцієнти пропусків під час resilver можуть примусити додаткові читання з диска. Це уповільнює resilver і підвищує латентність для всього іншого.
Рішення: Якщо ARC занадто малий для робочого набору, ви не зможете «налаштувати» це назавжди. Додайте пам’ять, зменшіть зміну даних або перенесіть метадані на швидші пристрої.
Завдання 11: Стежити за насиченням CPU і часом у kernel
cr0x@server:~$ mpstat -P ALL 1 2
Linux 6.8.0 (server) 12/24/2025 _x86_64_ (32 CPU)
Average: CPU %usr %sys %iowait %idle
Average: all 18.2 42.7 6.1 33.0
Average: 0 21.0 55.0 3.0 21.0
Average: 1 16.0 51.0 4.0 29.0
Значення: Високий %sys під час RAIDZ-resilver може вказувати на накладні витрати на парність/контрольні суми та I/O-стек. Якщо диски не насичені, але %sys високий — підозрівайте CPU.
Рішення: Розгляньте зниження паралельності resilver, щоб полегшити CPU, якщо продукція страждає, або плануйте періоди інтенсивного відновлення, коли CPU вільний.
Завдання 12: Переглянути zed-події та kernel-логи на предмет скидань лінків
cr0x@server:~$ sudo dmesg -T | tail -n 20
[Tue Dec 24 11:22:14 2025] ata12: hard resetting link
[Tue Dec 24 11:22:15 2025] ata12: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
[Tue Dec 24 11:22:15 2025] sd 11:0:0:0: [sdb] tag#18 timing out command, waited 180s
[Tue Dec 24 11:22:15 2025] blk_update_request: I/O error, dev sdb, sector 1987654321 op 0x0:(READ)
Значення: Скидання лінків і тайм-аути команд — це не «продуктивність». Це події надійності, які проявляються у вигляді колапсу продуктивності.
Рішення: Замініть кабелі/бэкплейн/порт HBA, можливо диск. Не продовжуйте resilver з флапаючим шляхом, якщо вам не подобається ризик.
Завдання 13: Підтвердити tunables scrub/resilver (Linux/OpenZFS)
cr0x@server:~$ sudo sysctl -a | egrep 'zfs_scan|resilver|scrub' | head
kstat.zfs.misc.scan.state = 2
kstat.zfs.misc.scan.pass = 1
kstat.zfs.misc.scan.start_time = 1735038132
Значення: Не всі системи показують однакові налаштування через sysctl, але ви все одно можете перевірити стан сканування і корелювати за часом. Якщо платформа використовує параметри модулів, перевірте їх наступними.
Рішення: Не змінюйте налаштування тільки тому, що якась стаття про це написала. Змінюйте їх лише коли знаєте, чи ви бюджетуєте латентність, чи оптимізуєте швидкість, і можете відкотитися.
Завдання 14: Виявити SMR-диски (тихий вбивця відновлення)
cr0x@server:~$ lsblk -d -o NAME,MODEL,ROTA
NAME MODEL ROTA
sda ST18000NM000J 1
sdb ST18000NM000J 1
sdnew ST18000NM000J 1
Значення: Це прямо не показує SMR проти CMR, але дає модель для перевірки. Якщо ви ненароком додали SMR, тривалі записи під час resilver можуть провалити процес.
Рішення: Ведіть список дозволених моделей для пулів. Якщо підозрюєте SMR — зупиніться і перевірте поведінку моделі; «працює більшість часу» не є стратегією зберігання.
Три міні-історії з корпоративного світу
Міні-історія 1: Інцидент через хибне припущення
Компанія запускала великий аналітичний кластер на ZFS поверх RAIDZ2. Коли диск впав, інженер on-call поміняв його і сказав, що пул буде здоровий «до обіду», бо кожен диск робить 250 MB/s послідовних записів. Це число взяли з даташиту вендора і швидкого бенчмарку на порожньому диску.
Resilver почався зі кількох сотень MB/s, що виглядало логічно. Потім він уповільнився до нервового 30–60 MB/s «issued», в той час як scanned залишався високим. Продуктивні запити почали таймаутитися, не тому що мережа була повільна, а через те, що латентність читань у пулі стрибнула. Користувачі почали писати тікети. Менеджмент почав розсилати зустрічі.
Хибне припущення було не в тому, що «ZFS повільний». Хибне припущення — що послідовна швидкість запису замінного диска визначає час відновлення. Пул був заповнений на 80% з роками перемішування. Реконструкція відсутної колонки вимагала розкиданих читань з усіх виживших дисків. Ці диски тепер виконували багато випадкових читань з високим IOPS одночасно з обслуговуванням живого навантаження.
Вирішення було нудним: обмежити resilver у робочий час, запускати агресивно вночі і додати політику, що пули не повинні жити вище визначеного порогу заповненості. Після цього обіцянки про обід припинилися. Пули не стали магічно швидшими, але бізнес перестав дивуватися.
Міні-історія 2: Оптимізація, що відкотилася
Інша команда хотіла швидших resilver, тож вони почали шукати налаштування. Вони підвищили паралельність сканування і зробили resilver «більш паралельним», очікуючи, що пул швидше перетравить роботу. На папері стало краще: більше I/O операцій за секунду.
У реальності латентність додатків подвоїлася. База даних не була обмежена пропускною здатністю; вона страждала від хвостової латентності. Збільшена паралельність resilver спричинила глибші черги на HDD. «Середня пропускна здатність» в дашборді виглядала краще, тоді як реальні користувацькі запити гальмували. Команда відреагувала додатковими повторними запитами додатку, що підвищило читальне навантаження і поглибило черги. Класика.
Вони відкочували налаштування і зробили крок, що здається принизливим: дозволили resilver працювати повільніше. Але вони встановили максимальну прийнятну латентність для бази даних і налаштували агресивність resilver так, щоб не перевищувати її. Відновлення зайняло довше, але бізнес перестав помічати.
Урок провалу: налаштування resilver — не безкоштовний обід. Якщо ваш пул обмежений переміщеннями головки, більше паралельності означає лише більше очікувань. Ви не отримаєте «швидше». Ви отримаєте «голосніше».
Міні-історія 3: Нудна, але правильна практика, що врятувала день
Фінансова платформа тримала ZFS-дзеркала для транзакційних даних і RAIDZ для холодного сховища. Нічого екзотичного. Їхня секретна зброя — набір нудних практик: планові scrubs, моніторинг SMART, і політика, що будь-який диск з ростом UDMA_CRC помилок переміщується в інший відсік перед поверненням у пул.
Одного тижня диск у дзеркалі відмовив під час пікового навантаження. Resilver почався і виглядав нормально. Через годину інший диск у тому ж шасі почав кидати CRC-помилки, і kernel залогував скидання лінків. Багато команд би «чекали і дивилися», молячись, щоб resilver встиг закінчитись першим.
Вони не чекали. Вони зупинили процес, перемістили підозрілий диск в відомо робочий слот, замінили кабель і відновили. Resilver закінчився без другої відмови. Система транзакцій залишилася в межах SLO латентності, бо команда також мала стандартну процедуру: у пікові години обмежувати вплив resilver; вночі дозволяти йому працювати агресивно.
Практика, що їх врятувала, не була чарівним налаштуванням. Це була дисциплінована гігієна та готовність трактувати нестабільні лінки як інциденти продукції, а не «дивну продуктивність».
Типові помилки: симптом → причина → виправлення
Помилка 1: «Resilver починається швидко, потім повільнішає до повного краху»
Симптом: Високий початковий MB/s, потім хвіст тягнеться вічно; диски показують високе завантаження, але низьку пропускну здатність.
Причина: Фрагментація + метадані в хвості; залишкова робота — багато дрібних розкиданих блоків, що обмежені IOPS.
Виправлення: Прийміть фізику; не шмагайтеся панічно налаштовувати. Тримайте пули нижче порогів високої заповненості, віддавайте перевагу дзеркалам для навантажень з високим циклом записів, і розгляньте special vdev для метаданих.
Помилка 2: «Новий диск швидкий, але resilver повільний»
Симптом: Запис на замінний диск помірний; виживші диски насичені читаннями.
Причина: Біч читання є лімітером (підсилення читань RAIDZ, шукаючі читання, конкуренція з навантаженням).
Виправлення: Діагностуйте латентність по диску; обмежте resilver щоб захистити продукцію; проєктуйте майбутні vdev з думкою про поведінку при відновленні (дзеркала проти ширини RAIDZ).
Помилка 3: «Швидкість resilver падає непередбачувано»
Симптом: Періодичні зупинки; величезні сплески латентності; kernel-логи показують скидання/тайм-аути.
Причина: Нестабільність лінку (кабелі, бэкплейн, expander, HBA) або маргінальний диск під тривалим навантаженням.
Виправлення: Трактуйте як інцидент апаратного забезпечення. Перевірте dmesg, SMART CRC, логи HBA; перемістіть відсік/порт; замініть підозрілі компоненти.
Помилка 4: «Налаштували resilver для швидкості; користувачі скаржаться»
Симптом: Resilver завершується швидше, але латентність застосунків і таймаути зростають.
Причина: Глибина черг і справедливість: більше паралельності resilver підвищує хвостову латентність і забирає IOPS у foreground.
Виправлення: Налаштовуйте під SLO, а не під секундомір. Обмежуйте агресивність resilver у пікові періоди, плануйте агресивні вікна в поза робочий час.
Помилка 5: «Під час resilver з’являються помилки контрольних сум; продуктивність падає»
Симптом: Лічильники CKSUM зростають; resilver сповільнюється; можливі повторні читання.
Причина: Проблеми медіа, погане кабелювання або другий диск на межі відмови; ZFS виправляє, якщо може, що забирає час.
Виправлення: Припиніть фокусуватися на швидкості. Стабілізуйте апарат, знайдіть домен відмови і розгляньте превентивну заміну підозрілого члена.
Помилка 6: «Пул заповнений на 90% і resilver жахливий»
Симптом: Resilver займає набагато більше часу, ніж раніше; алокація виглядає хаотично.
Причина: Вільний простір фрагментовано; metaslab-и мають менше суміжних екстентів; і читання, і записи стають менш ефективними.
Виправлення: Додайте ємність заздалегідь. Якщо не можете — мігруйте datasets, зменшіть churn і припиніть вважати 90% заповнення нормою.
Чеклісти / покроковий план
Покроково: як обробити відмову диска з мінімальним драмом
- Зупиніться і зафіксуйте картину: зробіть
zpool status -v,zpool iostat -v 1(30 секунд),iostat -x 1(30 секунд). Це ваші докази «до/після». - Підтвердьте домен відмови: це диск, кабель, відсік чи expander-ланка? Перевірте SMART CRC і kernel-логи.
- Замініть пристрій правильно: використовуйте
zpool replaceі підтвердіть відповідність GUID/пристрою. Людські помилки люблять відсіки дисків. - Визначте операційний режим: «закінчити швидко» чи «захистити латентність». Запишіть це в тікеті. Відповідайте за рішення.
- Спочатку моніторте здоров’я: чи зростають READ/WRITE/CKSUM? Якщо так — припиніть оптимізацію швидкості і стабілізуйте апарат.
- Моніторте вузькі місця: завантаження та await по дисках; якщо старі диски вичавлені — перестаньте вдавати, що новий диск важливий.
- Захистіть користувачів: якщо латентність критична, зменшіть агресивність resilver в пікові вікна замість форсування пропускної здатності.
- Після відновлення: запустіть scrub (або переконайтесь, що наступний запланований scrub відбудеться скоро), щоб підтвердити відсутність прихованих проблем.
- Постмортем причини: не просто «диск помер», а «чому він помер і що ще в цьому домені відмов?»
- Дії щодо ємності/фрагментації: якщо ви були >80% заповненості, розгляньте це як внесок до інциденту і плануйте вирішення.
Чекліст проєктування: будуйте пули, які не роблять resilver вашою кар’єрою
- Обирайте тип vdev відповідно до churn: дзеркала для високого циклу випадкових I/O; RAIDZ для холодніших, більш послідовних, менш часто переписуваних даних.
- Тримайте запас у пулах: не живіть у зоні 85–95% і не дивуйтеся, коли відновлення жахливі.
- Стандартизуйте моделі дисків: уникайте змішування невідомої SMR-поведінки в write-heavy пулах.
- Плануйте для метаданих: special vdev може допомогти, але лише якщо він дзеркалений, правильно спроєктований і під моніторингом.
- Тренуйте відмови: репетируйте процедури replace/resilver; документуйте мапінг імен пристроїв і відсіків; переконайтесь, що алерти працюють.
FAQ
1) Чи завжди resilver швидший за традиційне відновлення RAID?
Часто так, бо ZFS відновлює виділені блоки замість всього пристрою. Але якщо пул дуже заповнений і фрагментований, перевага зменшується, і хвіст усе ще може бути жорстким.
2) Чому «scanned» і «issued» відрізняються у zpool status?
«Scanned» — це скільки адресного простору/метаданих обійдено; «issued» — фактичний I/O, виданий для реконструкції. Великі розриви зазвичай означають багато роботи з метаданими або неефективні патерни доступу.
3) Дзеркала чи RAIDZ для швидших resilver?
Дзеркала зазвичай відновлюються швидше і з меншим підсиленням читань. RAIDZ може бути значно повільнішим, бо реконструкція часто вимагає читання кількох колонок для кожного блоку.
4) Чи можу я просто обмежити resilver, щоб зберегти продукцію?
Так, і зазвичай варто. Ризик — довший час у деградованому стані. Для сервісів з чутливою латентністю контрольований повільний resilver зазвичай безпечніший, ніж швидкий, що викликає таймаути і каскадні відмови.
5) Чи прискорить resilver додавання швидшого замінного диска?
Іноді так, але частіше ні. Обмежувальний фактор — читальні IOPS і латентність виживших дисків, а не пропускна здатність запису цілі.
6) Чому resilver уповільнюється наприкінці?
Хвіст містить більше дрібних блоків і метаданого-важкої роботи. Домінують дрібні випадкові читання, що руйнує пропускну здатність, хоча система «зайнята».
7) Фрагментація — це проблема dataset чи pool?
Обидві. Фрагментація визначається патернами алокації і розподілом вільного простору на рівні pool, але churn-датасети посилюють її. Пул платить за це під час resilver.
8) Чи нормальні помилки контрольних сум під час resilver?
Ні. ZFS може їх виправити за наявності надмірності, але вони вказують на реальну несправність: медіа, кабель, шлях HBA або інший пристрій у поганому стані. Трактуйте це як інцидент надійності.
9) Чи допомагає чи шкодить компресія швидкості resilver?
Вона може допомогти, якщо зменшує фізичні байти читання/запису, але може зашкодити, якщо CPU стає вузьким місцем або навантаження IOPS/метаданих домінує. Виміряйте CPU і завантаження дисків перед тим, як звинувачувати компресію.
10) Чи можна змусити «послідовний resilver»?
Не в тому сенсі, який багато хто має на увазі. ZFS використовує стратегії для зменшення випадкових I/O, але реальність на диску та макет vdev визначають, наскільки послідовним це може бути.
Практичні наступні кроки
Якщо ви сьогодні маєте повільний resilver:
- Запустіть
zpool status -v,zpool iostat -v 1іiostat -x 1. Визначте, чи ви обмежені IOPS, CPU чи маєте апаратну патологію. - Перевірте
dmesgі лічильники SMART CRC. Якщо лінки флапають — виправте апарат перед тим, як торкатися налаштувань. - Виберіть мету: найшвидше завершення або стабільна продукція. Обмежте/підсиліть resilver відповідно і задокументуйте рішення.
Якщо ви проєктуєте на наступну відмову (правильний час піклуватися):
- Перестаньте переповнювати пули. Запас — це страхування продуктивності й надійності.
- Вибирайте vdev відповідно до churn. Дзеркала коштують ємності; вони купують вам розумне відновлення.
- Інвестуйте в спостережуваність: латентність по диску, лічильники помилок ZFS і чіткий мапінг відсіків до ідентифікаторів пристроїв.
Найкращий resilver — це той, який ви закінчите, поки ніхто не помітить. Це не магія. Це проєктування, вимірювання та відмова трактувати «MB/s диска» як план.