Practical SRE & DevOps guides. Linux debugging. Lifestyle

RAID від A до Z: рівні, парність, mdadm, silent corruption і ZFS

Вступ: навіщо взагалі RAID у 2025?

Перш ніж розбирати рівні — важливо зрозуміти, що RAID не є заміною бекапу. Це мантра, яку треба вбити в голову перед будь-якою розмовою про RAID. RAID захищає від відмови одного або кількох дисків; він не захищає від:

RAID — це availability, а не durability у термінах CAP-теореми. Маючи RAID, ти отримуєш безперервність роботи при відмові диска. Бекап — це окрема історія.


Фундамент: що таке парність (parity)?

Перш ніж до рівнів, треба зрозуміти parity — ключову концепцію RAID 3/4/5/6.

XOR-магія. Для будь-яких двох бітів A і B діє:

A XOR B = P (parity)
A XOR P = B  (відновлення B)
B XOR P = A  (відновлення A)

Приклад на блоках:

Диск 1: 10110010
Диск 2: 11001101
Parity: 01111111  (XOR від D1 і D2)

Якщо Диск 2 згорів, відновлення: Диск 1 XOR Parity = 10110010 XOR 01111111 = 11001101 — ми отримали Диск 2 назад.

Контрольна сума (checksum) — це інший механізм: агрегатна функція від даних (MD5, SHA, CRC32, XXHash), що дозволяє виявити пошкодження. Сама по собі вона не відновлює дані — лише каже “щось зламалось”. У RAID parity = checksum + відновлення в одному.

Різниця між checksum і parity:

ВластивістьChecksumParity (XOR)
Виявлення помилки
Виправлення помилки✅ (для 1 диска)
Overheadмінімальний1/N дискового простору
Де використовуєтьсяZFS, btrfs, scrubRAID 3/4/5/6

RAID 0 — Striping без захисту

Як працює

Дані розбиваються на stripe chunks і записуються по черзі на всі диски:

Файл: [A1][A2][A3][A4][A5][A6]

Диск 1: [A1][A3][A5]
Диск 2: [A2][A4][A6]

Характеристики

ПараметрЗначення
Мінімум дисків2
Корисний обсяг100% (N × розмір диска)
Захист від відмов0 дисків
Read IOPS~N × IOPS одного диска
Write IOPS~N × IOPS одного диска

Коли використовувати

Каверзне питання: “RAID 0 з 10 дисків — яка ймовірність відмови?”

Якщо надійність одного диска = 99%, то RAID 0 з 10 дисків: 0.99^10 ≈ 90.4%. З 100 дисків: 0.99^100 ≈ 36.6%. RAID 0 масштабує ненадійність — кожен доданий диск підвищує шанс загальної відмови.


RAID 1 — Mirroring

Як працює

Кожен блок записується одночасно на всі диски (дзеркало):

Запис "Hello":
Диск 1: [Hello]
Диск 2: [Hello]

Характеристики

ПараметрЗначення
Мінімум дисків2
Корисний обсяг50% (1/N дискового простору)
Захист від відмовN-1 дисків
Read IOPSможе читати з обох (деякі контролери)
Write IOPSобмежений найповільнішим диском

Нюанс: read performance

Деякі RAID-контролери та mdadm реалізують read balancing — читання чергується між дзеркалами. Але це не завжди допомагає: якщо workload sequential, виграш мінімальний. Для random reads — відчутно краще.

Каверзне питання: “RAID 1 — це завжди 2 диски?”

Ні. RAID 1 може бути з 3, 4, і більше дисків (multi-mirror). mdadm підтримує це:

mdadm --create /dev/md0 --level=1 --raid-devices=3 /dev/sda /dev/sdb /dev/sdc

Але економічно доцільно лише у специфічних задачах (наприклад, boot-диск + hot spare без rebuild overhead).


RAID 2 — Bit-level striping з кодом Хеммінга

Як працює

Дані роздроблюються по одному біту (або байту) по дата-дисках, плюс кілька dedicated дисків під коди Хеммінга для виправлення помилок (ECC).

Для 4 дата-дисків потрібно 3 диски під parity (Hamming code)

Чому він мертвий

Сучасні жорсткі диски вже мають вбудований ECC на рівні диска (sectored ECC). RAID 2 вирішував проблему, яка вже не існує як архітектурна потреба. Він вимагає:

RAID 2 не використовується в production з 1990-х. Але він з’являється на технічних інтерв’ю саме для перевірки, чи знаєш ти його обмеження.


RAID 3 — Byte-level striping + dedicated parity

Як працює

Стриппінг на рівні байтів, один виділений диск для parity (XOR):

Диск 1 (data): [D1][D4][D7]
Диск 2 (data): [D2][D5][D8]
Диск 3 (data): [D3][D6][D9]
Диск 4 (parity): [P1][P2][P3]   P = D1 XOR D2 XOR D3

Проблема: parity disk bottleneck

Кожна операція запису вимагає оновлення parity-диска. Він стає hot spot і зношується значно швидше за дата-диски. Це архітектурний недолік, який RAID 5 вирішив через distributed parity.

Де RAID 3 має сенс

Лише при великих послідовних операціях (відеоредагування, наукові обчислення зі стримінгом). При random I/O parity disk задихається.


RAID 4 — Block-level striping + dedicated parity

Ідентичний RAID 3, але стриппінг на рівні блоків (не байтів). Та ж проблема bottleneck на parity-диску. Практично не використовується — його замінив RAID 5.

Каверзне питання: “Чим RAID 4 кращий за RAID 3?”

RAID 4 краще для random read: можна паралельно читати різні блоки з різних дисків без синхронізації. RAID 3 потребує синхронізованого читання (byte-level). Але обидва мають той самий bottleneck при записі.


RAID 5 — Distributed parity

Як працює

Parity розподілена по всіх дисках — немає dedicated parity disk:

           Диск 1    Диск 2    Диск 3    Диск 4
Stripe 1:  [D1]      [D2]      [D3]      [P1=D1^D2^D3]
Stripe 2:  [D4]      [D5]      [P2]      [D6]
Stripe 3:  [D7]      [P3]      [D8]      [D9]
Stripe 4:  [P4]      [D10]     [D11]     [D12]

Parity обертається (rotating parity) — кожен диск по черзі зберігає parity для певного stripe.

Характеристики

ПараметрЗначення
Мінімум дисків3
Корисний обсяг(N-1)/N
Захист від відмов1 диск
Read IOPSвідмінний (розпаралелено)
Write IOPSwrite penalty через parity calculation

Write penalty (RAID 5 write hole)

Кожен запис у RAID 5 — це насправді 4 I/O операції:

  1. Read старих даних (old data read)
  2. Read старого parity (old parity read)
  3. Розрахунок нового parity: new_parity = old_parity XOR old_data XOR new_data
  4. Write нових даних + нового parity

Це “RAID 5 write penalty” — при random writes RAID 5 повільніший за RAID 1.

RAID 5 Write Hole — критична небезпека

При раптовому відключенні живлення під час запису може виникнути RAID 5 write hole: дані записані, але parity — ні (або навпаки). Після відновлення parity стає невалідним, але RAID цього не знає. Якщо тепер помре диск — відновлення дасть корупцію замість правильних даних.

Рішення:

Каверзне питання: “RAID 5 з одним відмовленим диском — наскільки небезпечно?”

Критично небезпечно. Поки йде rebuild (годинами на терабайтах), RAID читає всі інші диски повністю. Це максимальне навантаження — саме в цей момент найбільша ймовірність відмови ще одного диска через stress. Якщо він відмовить — повна втрата даних.


RAID 6 — Double distributed parity

Як працює

Два незалежних parity-блоки на кожен stripe — P і Q. P = XOR (як у RAID 5), Q = Reed-Solomon код (більш складна математика, базована на полях Галуа GF(2^8)):

           Диск 1    Диск 2    Диск 3    Диск 4    Диск 5
Stripe 1:  [D1]      [D2]      [D3]      [P]       [Q]

Характеристики

ПараметрЗначення
Мінімум дисків4
Корисний обсяг(N-2)/N
Захист від відмов2 диски одночасно
Write penaltyще гірший ніж RAID 5 (6 I/O замість 4)

Reed-Solomon vs XOR

XOR (P) — простий, швидкий, відновлює один диск.
Reed-Solomon (Q) — складніший, повільніший, але дозволяє відновити другий диск навіть коли P вже “витрачений” на відновлення першого.

Комбінація P+Q дозволяє відновити будь-які два відмовлених диски, але не три.

Каверзне питання: “Чи може RAID 6 пережити 3 одночасних відмови?”

Ні. З 3 відмовленими дисками — повна втрата. Але якщо перший диск відмовив, rebuild завершився, а потім відмовив другий — RAID 6 це переживе (бо між відмовами надлишковість відновилась). RAID 6 захищає від двох одночасних (або concurrent) відмов.


RAID 10 (1+0) — Mirror + Stripe

Як працює

Спочатку дзеркала (RAID 1), потім стриппінг між ними (RAID 0):

        Mirror 1         Mirror 2
        /       \        /       \
      Disk1    Disk2   Disk3    Disk4

Дані стріпуються між Mirror1 і Mirror2

Характеристики

ПараметрЗначення
Мінімум дисків4
Корисний обсяг50%
Захист від відмов1 диск з кожної пари (worst case: 1, best case: N/2)
Read IOPSвідмінний (читання з обох дзеркал)
Write IOPSвідмінний (немає parity overhead)
Rebuild швидкістьдуже швидко (лише 1 дзеркало, не весь масив)

RAID 10 vs RAID 5: що краще?

Для production OLTP (бази даних, Postgres, MySQL) — RAID 10 майже завжди кращий:

RAID 5RAID 10
Write latencyвисока (parity overhead)низька
Rebuild time (4×2TB)6-12 годин30-60 хвилин
Ризик під час rebuildкритичнийпомірний
Цінадешевше (менше дисків)дорожче

Каверзне питання: “Скільки дисків може відмовити у RAID 10 з 8 дисків?”

Теоретично до 4 (якщо щастить і кожна відмова в різній парі). Практично гарантовано переживе 1. Якщо відмовлять обидва диски однієї пари — дані втрачені, незалежно від стану інших пар.


RAID 50 і RAID 60

RAID 50 = RAID 5 + RAID 0 (stripe across RAID 5 arrays).
RAID 60 = RAID 6 + RAID 0.

Використовуються на великих масивах (8+ дисків) для балансу між продуктивністю та надлишковістю. Складніші в управлінні, але дають кращу продуктивність ніж чистий RAID 5/6 при великій кількості дисків.


Апаратний RAID vs Програмний RAID

Апаратний RAID (Hardware RAID)

Окремий контролер (RAID card) з власним процесором і кеш-пам’яттю:

┌──────────────────────────────────┐
│          RAID Controller         │
│  ┌──────────┐  ┌──────────────┐  │
│  │   CPU    │  │  Cache RAM   │  │
│  │(XOR/RS)  │  │ (BBU/FBWC)  │  │
│  └──────────┘  └──────────────┘  │
└───────┬──────────────────────────┘
        │ SAS/SATA (HBA interface)
   ┌────┴────────────────┐
  Disk1  Disk2  Disk3  Disk4

Переваги:

Недоліки:

Програмний RAID (Software RAID / mdadm)

Реалізований у ядрі Linux, ОС повністю контролює масив:

# Створення RAID 5
mdadm --create /dev/md0 \
  --level=5 \
  --raid-devices=4 \
  /dev/sda /dev/sdb /dev/sdc /dev/sdd

# Статус масиву
mdadm --detail /dev/md0
cat /proc/mdstat

Переваги:

Недоліки:

Fake RAID (BIOS RAID / HostRAID)

Гібрид: конфігурація в BIOS/UEFI, але обробка — в драйвері ОС (dmraid). Найгірший варіант:

Рекомендація: уникай fake RAID. Вибирай або справжній hardware RAID controller, або mdadm/ZFS.


mdadm: практика

Основні команди

# Перегляд стану
cat /proc/mdstat
mdadm --detail /dev/md0

# Додати диск (hot spare)
mdadm /dev/md0 --add /dev/sde

# Замінити відмовлений диск
mdadm /dev/md0 --remove /dev/sdb   # якщо ще не виключений
mdadm /dev/md0 --add /dev/sdb_new

# Примусовий rebuild
mdadm /dev/md0 --re-add /dev/sdb

# Зберегти конфіг
mdadm --detail --scan >> /etc/mdadm/mdadm.conf

# Scrub (перевірка parity)
echo check > /sys/block/md0/md/sync_action
cat /sys/block/md0/md/mismatch_cnt  # кількість розбіжностей

Chunk size — важливий параметр

mdadm --create /dev/md0 --chunk=512 --level=5 ...

Chunk size (stripe unit) впливає на:

Для баз даних: 64-128KB. Для відео/sequential: 256KB-1MB.

Важливий нюанс: bitmap

mdadm --create /dev/md0 --level=1 --bitmap=internal ...

Internal bitmap зберігає “dirty bits” — при crash rebuild починається лише для “брудних” регіонів, а не всього масиву. Суттєво скорочує час після несподіваного вимкнення.


Silent Corruption — найнебезпечніший ворог

Що це таке?

Silent corruption (також “bit rot”, “data rot”) — пошкодження даних на рівні зберігання без будь-яких помилок у логах. Ні ОС, ні RAID-контролер не повідомляють про проблему. Ти читаєш дані — і отримуєш пошкоджені дані, думаючи що вони правильні.

Причини

Апаратні:

Програмні/протокольні:

Чому традиційний RAID не захищає від silent corruption?

RAID 5 з 4 дисків: диск 2 має bit rot у секторі 1000. RAID не знає про це — диск відповідає “все ок” і повертає некоректні дані. Parity розрахована від правильних даних — навіть якщо зробити перевірку parity, вона покаже “inconsistency”, але RAID не знає, ЧИЙ блок неправильний (дати чи parity).

При rebuild після відмови ще одного диска — відновлення буде базуватися на corrupted блоці і результат буде невалідним.

URE під час rebuild: математика

Специфікація SATA HDD: 1 URE на 10^14 прочитаних біт.

Масив RAID 5 з 4 × 2TB дисків. При rebuild читається 3 × 2TB = 6TB = 6 × 10^12 байт = 4.8 × 10^13 біт.

Ймовірність хоча б одного URE:

P = 1 - (1 - 1/10^14)^(4.8×10^13) ≈ 1 - e^(-0.48) ≈ 38%

38% шанс неповного rebuild на 3×2TB масиві. З 4TB дисками — ймовірність ще вища.

Enterprise SAS диски мають URE spec 10^15 — на порядок кращий, але все одно не нульовий.

Детектування без ZFS

# Scrub mdadm (перевіряє parity consistency)
echo check > /sys/block/md0/md/sync_action

# Перевірка S.M.A.R.T. (але не end-to-end checksum)
smartctl -a /dev/sda | grep -i "reallocated\|pending\|uncorrectable"

# Перегляд результатів scrub
cat /sys/block/md0/md/mismatch_cnt

Але: mdadm scrub виявляє parity inconsistency, не знає який блок правильний. Якщо bit rot і parity обидва “стабільно неправильні” (parity була правильно розрахована від corrupted даних) — scrub нічого не покаже.


ZFS: файлова система, яка вирішує все вище

Архітектура ZFS

ZFS — це не просто файлова система. Це storage stack: volume manager + RAID + filesystem в одному, з end-to-end checksumming на кожному рівні.

┌─────────────────────────────────────────┐
│           ZFS Dataset / zvol            │ ← файлова система
├─────────────────────────────────────────┤
│              ZFS Pool (zpool)           │ ← volume manager
├─────────────────────────────────────────┤
│    vdev: mirror / raidz / stripe        │ ← RAID рівень
├─────────────────────────────────────────┤
│         Checksum layer (SHA-256)        │ ← кожен блок хешується
├─────────────────────────────────────────┤
│         Physical disks / SSDs           │
└─────────────────────────────────────────┘

Copy-on-Write (CoW)

ZFSніколи не перезаписує дані in-place. Кожен write:

  1. Пише нові дані в новий блок
  2. Оновлює метадані, що вказують на новий блок
  3. Старий блок звільняється (або зберігається як snapshot)

Наслідок: немає RAID write hole. Якщо живлення вимкнулось посередині запису — стара версія даних залишається консистентною. Нова версія просто не “закріплена” в дереві метаданих.

RAIDZ vs класичний RAID 5

RAIDZ1 ≈ RAID 5, RAIDZ2 ≈ RAID 6, RAIDZ3 — захист від 3 відмов.

Але є ключові відмінності:

RAID 5RAIDZ1
Write hole❌ Є✅ Немає (CoW)
Checksum❌ Немає✅ SHA-256/blake3 на кожному блоці
Stripe sizeфіксованийдинамічний (залежить від запиту)
Silent corruption detect✅ При кожному read
Self-healing✅ Автоматично при виявленні

Динамічний stripe в RAIDZ — важлива деталь. Класичний RAID 5 має фіксований chunk size, що призводить до read-modify-write навіть для малих записів. RAIDZ пише рівно стільки parity, скільки потрібно для конкретного запису.

ZFS Scrub

# Запустити перевірку
zpool scrub tank

# Перегляд статусу
zpool status tank

# Результат
  scan: scrub repaired 0B in 00:12:33 with 0 errors on ...

При scrub ZFS читає кожен блок, перевіряє контрольну суму і:

Рекомендується: weekly scrub для HDD, monthly для SSD.

ZFS Snapshots і захист від людської помилки

# Snapshot
zfs snapshot tank/data@2025-07-01

# Відновлення файлу
zfs rollback tank/data@2025-07-01
# або
cp /tank/data/.zfs/snapshot/2025-07-01/file.txt /tank/data/

# Автоматичні snapshot (zfs-auto-snapshot або sanoid)
sanoid --take-snapshots --verbose

Snapshots — O(1) операція (лише метадані), займають місце лише для змінених даних (CoW).

ARC (Adaptive Replacement Cache)

ZFS використовує RAM як кеш (ARC) — до 50% RAM за замовчуванням. Це дуже ефективно для hot data, але може конфліктувати з іншими додатками на сервері:

# Обмежити ARC до 8GB (в /etc/modprobe.d/zfs.conf або sysctl)
echo "options zfs zfs_arc_max=8589934592" >> /etc/modprobe.d/zfs.conf

# Поточний стан ARC
arc_summary
# або
cat /proc/spl/kstat/zfs/arcstats | grep -E "^size|^hits|^misses"

L2ARC і ZIL/SLOG

L2ARC — другий рівень кешу на SSD (для read):

zpool add tank cache /dev/nvme0n1

ZIL (ZFS Intent Log) — журнал для синхронних записів. За замовчуванням на тих же дисках. SLOG (Separate Intent Log) — виносимо на окремий fast SSD/NVMe:

zpool add tank log /dev/nvme1n1

SLOG критично важливий для NFS/iSCSI workloads з синхронними записами (бази даних, VMware datastores).

ECC RAM і ZFS

ZFS вимагає ECC RAM — не технічно, але практично. Ось чому:

ARC зберігає дані в RAM. Якщо RAM має bit error (без ECC) → ZFS запише corrupted дані на диск з “правильним” checksum (бо checksum рахується від corrupted даних вже в пам’яті). Після цього ZFS не зможе виявити corruption, бо checksum збігатиметься.

ECC RAM виявляє і виправляє single-bit errors та детектує double-bit errors — захищаючи весь pipeline.


Порівняльна таблиця RAID рівнів

РівеньДиски мінОбсягВідмовReadWriteUse case
RAID 02100%0⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐Тимчасові дані, ML scratch
RAID 1250%N-1⭐⭐⭐⭐⭐⭐OS, boot, невеликі БД
RAID 53(N-1)/N1⭐⭐⭐⭐⭐⭐Файлові сервери, архіви
RAID 64(N-2)/N2⭐⭐⭐⭐Великі масиви, cold storage
RAID 10450%1-N/2⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐OLTP, production БД
RAIDZ13(N-1)/N1⭐⭐⭐⭐⭐⭐⭐ZFS storage, NAS
RAIDZ24(N-2)/N2⭐⭐⭐⭐⭐⭐ZFS з підвищеним захистом

Каверзні питання для інтерв’ю: швидкий довідник

Q: RAID 5 vs RAID 6 — коли що обирати?
A: RAID 6 при дисках >2TB і масиві 6+ дисків. Час rebuild RAID 5 на 4TB диску — 8-16 годин при повному навантаженні. За цей час ймовірність другої відмови критично висока. RAID 6 дає буфер безпеки.

Q: Чому RAID 5 “мертвий” для великих дисків?
A: URE probability + rebuild time. На 8TB SATA при rebuild читається ~24TB (3×8TB). Ймовірність URE: >90%. Індустрія де-факто рекомендує RAID 6 або RAIDZ2 для дисків >2TB.

Q: Що станеться якщо у RAID 10 відмовлять Диск 1 і Диск 2 (одна пара)?
A: Повна втрата даних цієї пари, хоч інші пари живі.

Q: Чи можна змінити chunk size після створення масиву?
A: Ні, без перестворення. Це деструктивна операція для mdadm RAID.

Q: mdadm rebuild читає весь масив чи лише відмовлений диск?
A: Читає всі “живі” диски для відновлення даних на новий диск. Це і є причиною стресу на здорові диски під час rebuild.

Q: Що таке “degraded mode”?
A: RAID продовжує працювати після відмови диска (якщо в межах надлишковості), але без захисту. Статус: [UUU_] в /proc/mdstat де _ = відмовлений диск.

Q: ZFS дзеркало vs mdadm RAID 1 — в чому різниця?
A: ZFS mirror має end-to-end checksums, CoW (немає write hole), автоматичне self-healing при scrub. mdadm RAID 1 — простіший, без checksums, є write hole без BBU.

Q: Що таке “split-brain” у RAID 1?
A: При network partition (в distributed RAID або Ceph) обидва вузли думають що інший мертвий і починають писати незалежно. Результат — два дивергентних дзеркала. Вирішується через quorum/fencing.


Практичні рекомендації

Що використовувати в 2025

Для домашнього NAS/сервера: ZFS (TrueNAS, Proxmox ZFS). RAIDZ2 для 4-8 дисків.

Для production Linux-сервера (без ZFS): RAID 10 через mdadm для баз даних, RAID 6 для файлових сховищ.

Для Proxmox homelab: ZFS mirror або RAIDZ1 — отримуєш snapshots, checksums і простоту управління.

Ніколи в production:

Моніторинг health

# mdadm: перевіряти регулярно
cat /proc/mdstat
mdadm --detail /dev/md0 | grep -E "State|Rebuild|Failed"

# S.M.A.R.T. (встановити smartmontools)
smartctl -H /dev/sda  # quick health check
smartctl -t long /dev/sda  # запустити extended test

# ZFS
zpool status -v
zpool list

# Налаштувати автоматичний scrub (cron або systemd timer)
# ZFS: zpool scrub tank  — раз на тиждень
# mdadm: echo check > /sys/block/md0/md/sync_action  — раз на місяць

Нагадування про 3-2-1 backup

RAID — це не backup. Правило 3-2-1:

RAID рахується як одна копія.


Висновок

RAID — це зрілий стек технологій з 35-річною історією, але нові виклики (більші диски, NVMe, silent corruption) змінили best practices. Ключові висновки:

  1. RAID 5 на великих HDD — небезпечний. Rebuild time + URE probability = реальний ризик втрати даних.
  2. Silent corruption реальна. Без end-to-end checksums (ZFS/btrfs) ти можеш роками зберігати corrupted дані, не знаючи про це.
  3. ZFS вирішує більшість проблем класичного RAID: write hole, silent corruption, людська помилка (snapshots). Але потребує ECC RAM і правильного налаштування.
  4. mdadm — відмінний вибір для Linux, якщо розумієш його обмеження і додаєш моніторинг + regular scrub.
  5. Hardware RAID controller ≠ кращий. Без доступу до S.M.A.R.T. і з vendor lock-in він може бути гіршим за software RAID для більшості use cases.

Найкращий RAID — той, стан якого ти моніториш щодня.

#Linux