RAID: что это такое, уровни 0, 1, 5, 6, 10 и как выбрать

RAID: что это такое, уровни 0, 1, 5, 6, 10 и как выбрать Полезное

RAID (Redundant Array of Independent Disks, избыточный массив независимых дисков) — это способ объединить несколько физических дисков в один логический том. Что именно вы получите — скорость, отказоустойчивость или объем — определяет уровень RAID: RAID 0 только ускоряет, RAID 1 зеркалирует, RAID 5 и 6 защищают данные с помощью четности, RAID 10 сочетает зеркала и чередование.

Сразу граница: RAID защищает от отказа диска, но не от удаления файлов, шифровальщика или ошибки администратора. Это не резервная копия. Ниже — таблица уровней, расчет емкости, механика четности на коде и базовые команды mdadm для Linux.

Три приема, из которых собраны все уровни

Уровни RAID — это комбинации трех приемов. Их легко спутать, поэтому разведу сразу:

  • Чередование (striping) — данные режутся на блоки и пишутся по очереди на разные диски. Диски работают параллельно, но копии нет: потеря одного диска ломает весь том.
  • Зеркалирование (mirroring) — одни и те же данные пишутся на два и более диска целиком.
  • Четность (parity) — вместо полной копии хранится контрольный блок, вычисленный из блоков данных (в RAID 5 — через XOR). По нему можно вычислить один потерянный блок. Четность — это не зеркало и не сочетание зеркала с чередованием.

Еще три термина пригодятся ниже. Degraded — массив работает, но уже без запаса (один диск выпал). Rebuild — восстановление избыточности на новый диск. Hot spare — заранее подключенный резервный диск, на который rebuild начинается автоматически.

Уровни RAID 0, 1, 5, 6, 10 в одной таблице

Обозначения: n — число дисков, C — объем самого маленького из них (массив использует столько места на каждом диске).

Уровень Прием Мин. дисков Полезный объем Переживет отказ Сильная сторона Слабая сторона
RAID 0 Чередование 2 n x C 0 дисков Скорость, весь объем Отказ любого диска = потеря всего
RAID 1 Зеркало 2 C n — 1 диск Простота, быстрый rebuild Половина объема и меньше
RAID 5 Чередование + 1 четность 3 (n — 1) x C 1 диск Экономия места Медленная случайная запись, риск на rebuild
RAID 6 Чередование + 2 четности 4 (n — 2) x C 2 любых диска Надежнее RAID 5 на больших дисках Еще медленнее запись
RAID 10 Чередование зеркал 4 n x C / 2 1 гарантированно, больше — если в разных парах Быстрая запись, быстрый rebuild 50% объема

Таблица описывает классические уровни. Реализации расширяют правила: например, RAID 10 в Linux md умеет работать с нечетным числом дисков. Скорость в таблице — качественная оценка: реальные цифры зависят от дисков, кеша контроллера и профиля нагрузки.

Остальные уровни встречаются редко. RAID 2, 3 и 4 практически вытеснены RAID 5 и 6. RAID 50 и 60 — это чередование нескольких групп RAID 5 или RAID 6 для больших полок. JBOD — просто склейка дисков без избыточности.

Считаем емкость и запас прочности

Формулы из таблицы удобно проверить на своем наборе дисков. Скрипт ниже проверен на Python 3.14.

def raid_summary(level, disks_tb):
    n = len(disks_tb)
    c = min(disks_tb)  # массив использует объем самого маленького диска
    rules = {
        "0":  (2, lambda: n * c,       "0"),
        "1":  (2, lambda: c,           f"{n - 1}"),
        "5":  (3, lambda: (n - 1) * c, "1"),
        "6":  (4, lambda: (n - 2) * c, "2"),
        "10": (4, lambda: n // 2 * c,  "1 гарантированно, до n/2 в разных парах"),
    }
    min_disks, usable, survives = rules[level]
    if n < min_disks:
        return f"RAID {level}: нужно минимум {min_disks} дисков, дано {n}"
    if level == "10" and n % 2:
        return "RAID 10 (классический): нужно четное число дисков"
    raw = sum(disks_tb)
    u = usable()
    return (f"RAID {level:>2}: полезно {u:>4} ТБ из {raw} ТБ "
            f"({u / raw:.0%}), переживет отказ дисков: {survives}")

four = [4, 4, 4, 4]
for lvl in ["0", "1", "5", "6", "10"]:
    print(raid_summary(lvl, four))
print(raid_summary("5", [4, 4, 2]))
print(raid_summary("6", [4, 4, 4]))

Вывод:

RAID  0: полезно   16 ТБ из 16 ТБ (100%), переживет отказ дисков: 0
RAID  1: полезно    4 ТБ из 16 ТБ (25%), переживет отказ дисков: 3
RAID  5: полезно   12 ТБ из 16 ТБ (75%), переживет отказ дисков: 1
RAID  6: полезно    8 ТБ из 16 ТБ (50%), переживет отказ дисков: 2
RAID 10: полезно    8 ТБ из 16 ТБ (50%), переживет отказ дисков: 1 гарантированно, до n/2 в разных парах
RAID  5: полезно    4 ТБ из 10 ТБ (40%), переживет отказ дисков: 1
RAID 6: нужно минимум 4 дисков, дано 3

Что видно из прогона. RAID 1 на четырех дисках — это четыре копии, поэтому объем одного диска. RAID 6 и RAID 10 на четырех дисках дают одинаковые 8 ТБ, но RAID 6 переживет отказ любых двух дисков, а RAID 10 — только если они в разных зеркальных парах. Смешанные диски (4, 4 и 2 ТБ) превращают RAID 5 в 4 ТБ: лишнее место больших дисков простаивает.

Как работает четность: восстановление блока на XOR

У XOR есть свойство: если P = D1 XOR D2, то D2 = D1 XOR P. На этом держится RAID 5. Ниже одна полоса массива из трех дисков: два блока данных и блок четности.

from functools import reduce

def xor_blocks(blocks):
    """Побайтовый XOR нескольких блоков одинаковой длины."""
    return bytes(reduce(lambda a, b: a ^ b, column) for column in zip(*blocks))

# Одна полоса (stripe) RAID 5 из трех дисков: два блока данных + четность
d1 = b"RAID"
d2 = b"five"
parity = xor_blocks([d1, d2])
print("parity :", parity.hex())

# Диск с блоком d2 отказал: восстанавливаем его из уцелевших блоков
restored = xor_blocks([d1, parity])
print("restore:", restored)
assert restored == d2

# Если отказали два диска из трех, данных для XOR не хватает
lost = [d1, d2]
print("выжил только parity, восстановить d1 и d2 нельзя:", len(lost), "неизвестных")

Вывод:

parity : 34283f21
restore: b'five'
выжил только parity, восстановить d1 и d2 нельзя: 2 неизвестных

Это упрощенная модель одной полосы. В реальном RAID 5 блок четности в каждой полосе лежит на другом диске, чтобы нагрузка распределялась равномерно. В RAID 6 вторая контрольная сумма считается не простым XOR, а кодом Рида — Соломона, поэтому он переживает два отказа.

Из этой механики следуют два практических свойства. Первое — штраф записи: чтобы изменить один маленький блок в RAID 5, контроллер читает старые данные и старую четность, затем пишет новые данные и новую четность. Это четыре операции вместо одной (в RAID 6 — шесть). Кеш и запись полными полосами штраф снижают, но для базы данных со случайной записью чаще выбирают RAID 10.

Второе — уязвимое окно rebuild. Пока RAID 5 в состоянии degraded, для восстановления нужно без ошибок прочитать все остальные диски целиком. На больших HDD это часы или сутки повышенной нагрузки, и нечитаемый сектор или второй отказ в это время означает потерю данных. Поэтому для массивов из больших дисков обычно берут RAID 6 или RAID 10.

RAID не бэкап

RAID отвечает на один вопрос: продолжит ли система работать, если сломается диск. Все остальные угрозы он не закрывает, а часть из них мгновенно копирует на все диски.

Угроза RAID 1/5/6/10 Резервная копия
Отказ одного диска Защищает Защищает, но с простоем на восстановление
Случайное удаление файла Нет, удаление сразу на всех дисках Да, если копия старше удаления
Шифровальщик Нет Да, если копия отключена или неизменяема
Сбой контроллера, ошибка ФС Нет Да, при наличии отдельной пригодной к восстановлению копии
Кража, пожар, потоп Нет Да, если копия в другом месте

Практичное правило 3-2-1: три копии данных, на двух разных носителях, одна — вне площадки. Копия считается рабочей, только если восстановление из нее проверено: регулярно разворачивайте ее на отдельный стенд и сверяйте, что данные открываются и актуальны. Во всех строках таблицы выше «Да» означает именно такую копию — независимую от сбойного массива, свежую и проверенную восстановлением. RAID сокращает простой, бэкап спасает данные.

Программный, аппаратный и fake RAID

Вариант Где работает Когда уместен Ограничение
Программный (Linux md/mdadm, ZFS, Windows Storage Spaces) В ОС, на CPU Серверы на Linux, NAS, домашние сборки Массив привязан к ОС и ее инструментам
Аппаратный контроллер Отдельная плата со своим процессором и кешем Серверы с высокой нагрузкой записи Цена; для замены нужен совместимый контроллер
Fake RAID (RAID в BIOS/UEFI материнской платы) Прошивка + драйвер ОС, вычисления на CPU Рабочие станции под Windows Меньше гибкости, чем у md; проблемы при переносе

На современном CPU программный RAID обычно не узкое место. Кеш аппаратного контроллера ускоряет запись, только если он защищен от потери питания (батарея или флеш-модуль).

Практика: RAID 5 в Linux через mdadm

Команда mdadm --create стирает метаданные и фактически данные на указанных устройствах, а mkfs.ext4 уничтожает то, что лежало на массиве. Поэтому стенд ниже запускайте только на изолированной учебной машине: одноразовой виртуальной машине без чужих массивов и ценных данных. Файлы-образы на loop-устройствах снижают риск, но сами по себе не гарантируют безопасность: если имя массива уже занято или переменная указывает не туда, форматирование уйдет не на стенд. Поэтому скрипт сначала проверяет среду и останавливается при любой ошибке до создания массива и mkfs.

Что делает скрипт по шагам:

  1. Предохранители: запуск от root, имя массива md100 не занято (нет в /proc/mdstat и в /sys/block), каждое устройство — именно loop, привязанное к своему образу во временном каталоге из mktemp -d, и на нем нет подписей ФС или RAID.
  2. Создание RAID 5 и ожидание первичной сборки, затем еще одна проверка: в массиве ровно наши loop-устройства.
  3. Файловая система и тестовый файл.
  4. Отказ одного устройства, чтение файла в degraded, возврат устройства и recovery.
  5. Уборка: размонтирование, mdadm --stop, losetup -d, удаление образов и каталога. Она срабатывает через trap при любом выходе, в том числе после ошибки.

Сохраните скрипт в файл raid-lab.sh и запустите sudo bash raid-lab.sh. Команды для Ubuntu/Debian (нужны пакеты mdadm и e2fsprogs).

#!/usr/bin/env bash
# Учебный стенд RAID 5 на loop-устройствах. Только для изолированной учебной ВМ, от root.
set -euo pipefail

MD=/dev/md100                                # имя массива стенда
LAB=$(mktemp -d /var/tmp/raid-lab.XXXXXX)    # уникальный каталог под образы
MNT="$LAB/mnt"
LOOPS=()
CREATED=0

die() { echo "СТОП: $*" >&2; exit 1; }

cleanup() {                                  # выполняется всегда: при успехе и при ошибке
  set +e
  mountpoint -q "$MNT" && umount "$MNT"
  [ "$CREATED" = 1 ] && mdadm --stop "$MD"
  for L in "${LOOPS[@]}"; do losetup -d "$L"; done
  rm -f "$LAB"/disk1.img "$LAB"/disk2.img "$LAB"/disk3.img
  rmdir "$MNT" "$LAB" 2>/dev/null
  echo "уборка завершена"
}
trap cleanup EXIT

# 1. Предохранители до любых изменений
[ "$(id -u)" = 0 ] || die "нужен root"
N=${MD#/dev/}
grep -q "^$N :" /proc/mdstat && die "массив $N уже есть в /proc/mdstat"
[ -e "/sys/block/$N" ] && die "устройство $N уже зарегистрировано в ядре"

for i in 1 2 3; do
  IMG="$LAB/disk$i.img"
  truncate -s 1G "$IMG"
  L=$(losetup --find --show "$IMG")
  LOOPS+=("$L")
  [[ "$L" =~ ^/dev/loop[0-9]+$ ]] || die "$L - не loop-устройство"
  BACK=$(losetup --list --noheadings --output BACK-FILE "$L" | xargs)
  [ "$BACK" = "$IMG" ] || die "$L привязан к '$BACK', ожидался $IMG"
  blkid "$L" >/dev/null && die "на $L уже есть подпись ФС или RAID"
done
echo "loop-устройства стенда: ${LOOPS[*]}"

# 2. Создать RAID 5 и дождаться первичной сборки
mdadm --create "$MD" --level=5 --raid-devices=3 "${LOOPS[@]}"
CREATED=1
mdadm --wait "$MD" || true                   # код 1 = ждать было нечего
for L in "${LOOPS[@]}"; do                   # mkfs только на массиве из наших loop
  mdadm --detail "$MD" | grep -q "$L\$" || die "$L не входит в $MD"
done
grep -A1 "^$N :" /proc/mdstat

# 3. Файловая система и тестовый файл
mkfs.ext4 -q "$MD"
mkdir "$MNT"
mount "$MD" "$MNT"
echo "hello raid" > "$MNT/test.txt"

# 4. Отказ диска, чтение в degraded, возврат диска
mdadm "$MD" --fail "${LOOPS[1]}"
grep -A1 "^$N :" /proc/mdstat
mdadm "$MD" --remove "${LOOPS[1]}"
cat "$MNT/test.txt"
mdadm "$MD" --add "${LOOPS[1]}"
mdadm --wait "$MD" || true
grep -A1 "^$N :" /proc/mdstat
# 5. Уборка: cleanup выше срабатывает при выходе из скрипта

Вывод (прогнано на Ubuntu 24.04, mdadm 4.3, ядро 6.8, loop-устройства; номера loop на вашей машине могут отличаться):

loop-устройства стенда: /dev/loop0 /dev/loop1 /dev/loop2
mdadm: Defaulting to version 1.2 metadata
mdadm: array /dev/md100 started.
md100 : active raid5 loop2[3] loop1[1] loop0[0]
      2093056 blocks super 1.2 level 5, 512k chunk, algorithm 2 [3/3] [UUU]
mdadm: set /dev/loop1 faulty in /dev/md100
md100 : active raid5 loop2[3] loop1[1](F) loop0[0]
      2093056 blocks super 1.2 level 5, 512k chunk, algorithm 2 [3/2] [U_U]
mdadm: hot removed /dev/loop1 from /dev/md100
hello raid
mdadm: added /dev/loop1
md100 : active raid5 loop1[4] loop2[3] loop0[0]
      2093056 blocks super 1.2 level 5, 512k chunk, algorithm 2 [3/3] [UUU]
mdadm: stopped /dev/md100
уборка завершена

Как читать вывод. Метка (F) и [U_U] — массив degraded, но файл hello raid читается. После --add идет recovery, и по окончании снова [UUU]. Ожидание mdadm --wait после создания обязательно: mdadm собирает RAID 5 из двух устройств и достраивает третье как запасное, поэтому сразу после create в /proc/mdstat видно [3/2] [UU_], третье устройство с пометкой (S) и затем строку recovery, а --fail в этот момент вернет ошибку mdadm: Cannot remove /dev/loop1 from /dev/md100, array will be failed.

Предохранители тоже проверены. Если имя md100 уже занято другим массивом, скрипт завершается с кодом 1 еще до создания образов и loop-устройств:

СТОП: массив md100 уже есть в /proc/mdstat
уборка завершена

Чужой массив при этом остается нетронутым. Если mdadm --create завершается ошибкой, скрипт не доходит до mkfs, освобождает loop-устройства и удаляет образы. После любого завершения cat /proc/mdstat и losetup -a не должны показывать следов стенда.

На реальном сервере добавляются шаги, которых нет на стенде. Перед созданием проверьте, что диски пустые: lsblk -f и wipefs --no-act /dev/sdX показывают существующие подписи, ничего не стирая. После создания сохраните описание массива, иначе после перезагрузки он может собраться под другим именем: mdadm --detail --scan >> /etc/mdadm/mdadm.conf и update-initramfs -u (в RHEL-семействе файл /etc/mdadm.conf, initramfs обновляет dracut). И обязательно включите уведомления: строка MAILADDR в mdadm.conf и служба мониторинга mdadm, иначе degraded-массив может неделями работать без запаса.

Если не получилось

  • Скрипт остановился со строкой СТОП: ... — сработал предохранитель, изменений на чужих устройствах нет. Прочитайте причину: если занято имя массива, поменяйте MD=/dev/md100 на свободное имя, а не удаляйте существующий массив.
  • mdadm: cannot open /dev/loopN: Device or resource busy — устройство уже в другом массиве или смонтировано: проверьте cat /proc/mdstat и lsblk.
  • После перезагрузки массив стал /dev/md127 — не сохранено описание в mdadm.conf или не обновлен initramfs.
  • В /proc/mdstat видно [U_U] — массив degraded: найдите сбойный диск в mdadm --detail и проверьте его SMART (smartctl -a).
  • Rebuild идет очень медленно — это нормально при нагрузке; скорость ограничивают параметры /proc/sys/dev/raid/speed_limit_min и speed_limit_max.

Как выбрать уровень RAID

Задача Что взять Когда иначе
Системный диск сервера, 2 диска RAID 1 —
База данных, виртуализация, много случайной записи RAID 10 Мало дисков и денег — RAID 1
Файловое хранилище, архив, большие HDD RAID 6 3-4 небольших SSD — RAID 5 допустим
Временные данные, кеш, рендер RAID 0 Данные нельзя потерять — любой уровень с избыточностью
Домашний NAS на 2 дисках RAID 1 + внешний бэкап —

Выводы

  • RAID объединяет диски в один том; уровень определяет баланс скорости, объема и отказоустойчивости.
  • RAID 0 не защищает ничего, RAID 1 и 10 зеркалируют, RAID 5 и 6 восстанавливают данные по четности и переживают один или два отказа.
  • Полезный объем считается по самому маленькому диску: RAID 5 — (n — 1) x C, RAID 6 — (n — 2) x C, RAID 10 — половина.
  • Для больших HDD RAID 5 рискован из-за долгого rebuild; чаще берут RAID 6 или RAID 10.
  • RAID не заменяет бэкап: удаление, шифровальщик и пожар он не переживает, а бэкап спасает, только если восстановление из него проверено.

Где применяется / связь с практикой

Освойте тему на практике

Настройка mdadm, разметка дисков, LVM поверх массива, мониторинг SMART и восстановление после отказа — повседневная работа Linux-администратора. Эти навыки вместе с управлением пакетами, службами и правами разбираются на курсе «Администратор Linux. Базовый уровень». Отдельные темы по администрированию и хранению данных можно посмотреть на бесплатных открытых уроках Otus.

FAQ

Можно ли собрать RAID из дисков разного объема?
Можно, но на каждом диске будет использован объем самого маленького. Остаток больших дисков либо простаивает, либо размечается отдельным разделом вне массива.

Можно ли расширить готовый массив mdadm?
Да, mdadm умеет добавлять диски и менять уровень через --grow (например, RAID 5 из трех дисков в четыре). Операция долгая и нагружает диски, поэтому перед ней нужна свежая резервная копия.

Есть ли смысл в RAID 1 из SSD?
Есть: зеркало защищает от отказа одного SSD. Но два одинаковых SSD с одинаковой нагрузкой изнашиваются синхронно, поэтому износ стоит отслеживать через SMART, а бэкап все равно нужен.

OTUS Журнал