Послідовне відновлення (resilver) у ZFS: чому швидкість відновлення — це не лише «MB/s диска»

Було корисно?

Ви замінюєте зіпсований диск, запускаєте 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).
  • Операційний бюджет: скільки латентності ви готові терпіти в продукції під час роботи.

Цікаві факти та трохи історичного контексту

  1. ZFS популяризував «відновлення лише виділених даних» як ключову ідею дизайну, уникаючи класичної поведінки RAID-контролерів «скануй весь диск».
  2. Scrub та resilver використовують одну й ту ж машину, але resilver мусить ще й писати та оновлювати стан, що змінює шаблони конкуренції в I/O-пайплайні.
  3. Resilver у RAIDZ має внутрішнє підсилення читань, бо реконструкція блоку часто вимагає читання кількох колонок; дзеркала частіше можуть читати з однієї сторони.
  4. Контрольні суми вказівників блоків критичні: ZFS читає й перевіряє дані наскрізь, тож «швидка, але тиха корупція» не проходить.
  5. Вибір ashift став болючішим з часом, коли диски перейшли на фізичні сектора 4K; невідповідність вирівнювання може перетворити «послідовну» роботу на додаткові цикли читання-модифікації-запису.
  6. Space map-и еволюціонували, щоб краще відстежувати вільні/виділені діапазони, і ця бухгалтерія безпосередньо впливає на ефективність обходу виділеного простору під час відновлення.
  7. Покращення видалення пристрою та послідовного resilver у OpenZFS зробили відновлення менш болісним, ніж ранні підходи «сканувати все» — якщо макет пулу співпрацює.
  8. 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% заповнення нормою.

Чеклісти / покроковий план

Покроково: як обробити відмову диска з мінімальним драмом

  1. Зупиніться і зафіксуйте картину: зробіть zpool status -v, zpool iostat -v 1 (30 секунд), iostat -x 1 (30 секунд). Це ваші докази «до/після».
  2. Підтвердьте домен відмови: це диск, кабель, відсік чи expander-ланка? Перевірте SMART CRC і kernel-логи.
  3. Замініть пристрій правильно: використовуйте zpool replace і підтвердіть відповідність GUID/пристрою. Людські помилки люблять відсіки дисків.
  4. Визначте операційний режим: «закінчити швидко» чи «захистити латентність». Запишіть це в тікеті. Відповідайте за рішення.
  5. Спочатку моніторте здоров’я: чи зростають READ/WRITE/CKSUM? Якщо так — припиніть оптимізацію швидкості і стабілізуйте апарат.
  6. Моніторте вузькі місця: завантаження та await по дисках; якщо старі диски вичавлені — перестаньте вдавати, що новий диск важливий.
  7. Захистіть користувачів: якщо латентність критична, зменшіть агресивність resilver в пікові вікна замість форсування пропускної здатності.
  8. Після відновлення: запустіть scrub (або переконайтесь, що наступний запланований scrub відбудеться скоро), щоб підтвердити відсутність прихованих проблем.
  9. Постмортем причини: не просто «диск помер», а «чому він помер і що ще в цьому домені відмов?»
  10. Дії щодо ємності/фрагментації: якщо ви були >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:

  1. Запустіть zpool status -v, zpool iostat -v 1 і iostat -x 1. Визначте, чи ви обмежені IOPS, CPU чи маєте апаратну патологію.
  2. Перевірте dmesg і лічильники SMART CRC. Якщо лінки флапають — виправте апарат перед тим, як торкатися налаштувань.
  3. Виберіть мету: найшвидше завершення або стабільна продукція. Обмежте/підсиліть resilver відповідно і задокументуйте рішення.

Якщо ви проєктуєте на наступну відмову (правильний час піклуватися):

  1. Перестаньте переповнювати пули. Запас — це страхування продуктивності й надійності.
  2. Вибирайте vdev відповідно до churn. Дзеркала коштують ємності; вони купують вам розумне відновлення.
  3. Інвестуйте в спостережуваність: латентність по диску, лічильники помилок ZFS і чіткий мапінг відсіків до ідентифікаторів пристроїв.

Найкращий resilver — це той, який ви закінчите, поки ніхто не помітить. Це не магія. Це проєктування, вимірювання та відмова трактувати «MB/s диска» як план.

← Попередня
Proxmox VM не запускається після зміни типу CPU: робочі кроки відновлення
Наступна →
Debian 13 Kdump: налаштування та перевірка захоплення аварійних дампів (випадок №17)

Залишити коментар