OpenZFS: снапшоты и репликация для 100 ТБ медиахранилища

Задача: 100 ТБ видео без права на потерю

Студия видеопродакшена «ВидеоПро» обратилась к нам с проблемой: у них накопилось 100 ТБ RAW-видеоматериалов на массиве из 24 дисков по 8 ТБ под аппаратным RAID-6. Система работала, но с критическими рисками:

  • Нет offsite-копии — единственный экземпляр данных находился в офисе. Пожар или кража = потеря всего архива.
  • RAID rebuild 3+ дня — при выходе диска из строя пересборка массива занимала 72 часа, в течение которых система работала в деградированном режиме и один сбой мог уничтожить данные.
  • Нет версионирования — монтажёры периодически перезаписывали финальные версии проектов. Откат невозможен.
  • Silent data corruption — аппаратный RAID не проверяет целостность данных на уровне блоков. Битые кадры обнаруживались только при монтаже — иногда через месяцы после повреждения.

Мы предложили миграцию на OpenZFS — файловую систему, которая решает все эти проблемы на уровне архитектуры, а не костылей поверх.

Почему ZFS: Copy-on-Write и самовосстановление

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

Copy-on-Write (CoW): ZFS никогда не перезаписывает данные на месте. Новые блоки записываются в свободное пространство, а указатели обновляются атомарно. Это означает:

  • Невозможность частичной записи (write hole) — главная уязвимость аппаратного RAID-5/6
  • Мгновенные снапшоты без копирования данных
  • Атомарные транзакции — данные либо записаны полностью, либо не записаны вообще

Контрольные суммы (Merkle Tree): ZFS считает хеш каждого блока данных и хранит его в родительском блоке метаданных. Хеши вычисляются иерархически — от данных до корневого UberBlock. При чтении ZFS автоматически проверяет целостность и при обнаружении расхождения восстанавливает блок из зеркала или parity.

# Проверяем настройки контрольных сумм (по умолчанию — fletcher4)
zfs get checksum mediapool
# NAME       PROPERTY   VALUE      SOURCE
# mediapool  checksum   on         default

# Для максимальной надёжности включаем SHA-256
zfs set checksum=sha256 mediapool/archive

Самовосстановление: при обнаружении повреждённого блока ZFS автоматически берёт корректную копию из избыточного хранилища (mirror или RAIDZ) и перезаписывает испорченный блок. Администратор получает уведомление через zpool status, но пользователь даже не замечает проблемы.

Встроенная компрессия LZ4 работает со скоростью свыше 800 МБ/с на сжатие и 4.5 ГБ/с на декомпрессию, что практически бесплатно по CPU и экономит 15-30% пространства даже для видеоматериалов.

Создание ZFS-пула: RAIDZ2 для видеохранилища

Мы собрали новый сервер с 24 дисками по 10 ТБ (Seagate Exos) и HBA-контроллером LSI 9300-16i в режиме IT (passthrough — диски видны ОС напрямую, без аппаратного RAID).

Конфигурация пула — 3 RAIDZ2 vdev по 8 дисков:

# Создаём пул из 3 RAIDZ2 групп
zpool create -o ashift=12 -O compression=lz4 -O atime=off \
  -O recordsize=1M -O xattr=sa -O dnodesize=auto \
  mediapool \
  raidz2 /dev/disk/by-id/scsi-ST10000NM001G_{a..h} \
  raidz2 /dev/disk/by-id/scsi-ST10000NM001G_{i..p} \
  raidz2 /dev/disk/by-id/scsi-ST10000NM001G_{q..x}

# Результат: 24 диска по 10 ТБ
# Полезная ёмкость: ~180 ТБ (3 группы × 6 дисков данных × 10 ТБ)
# Может пережить до 2 отказов дисков в каждой группе
# (итого до 6 дисков одновременно, если по 2 в каждой группе)

Пояснение параметров:

  • ashift=12 — размер сектора 4096 байт (для современных дисков)
  • compression=lz4 — прозрачная компрессия с минимальной нагрузкой на CPU
  • atime=off — отключаем обновление времени доступа (экономим IOPS)
  • recordsize=1M — большой размер блока для последовательного чтения видео
  • xattr=sa — расширенные атрибуты хранятся в dnode (быстрее для Samba)

Создаём датасеты с разными свойствами для разных типов данных:

# Активные проекты — максимальная производительность
zfs create -o recordsize=1M -o compression=lz4 \
  -o quota=30T mediapool/projects

# Архив готовых проектов — максимальная компрессия
zfs create -o recordsize=1M -o compression=zstd-6 \
  -o quota=120T mediapool/archive

# Промежуточные рендеры — без компрессии для скорости
zfs create -o recordsize=1M -o compression=off \
  -o quota=20T mediapool/renders

# Базы данных приложений — маленький recordsize
zfs create -o recordsize=16K -o compression=lz4 \
  -o logbias=latency mediapool/databases

Автоматические снапшоты: sanoid

Снапшоты в ZFS — практически бесплатная операция благодаря CoW: снапшот просто «замораживает» текущие указатели, а новые записи уходят в новые блоки. Создание снапшота 100 ТБ датасета занимает менее секунды.

Для автоматического управления снапшотами мы используем sanoid:

# /etc/sanoid/sanoid.conf
[mediapool/projects]
  use_template = production
  recursive = yes

[mediapool/archive]
  use_template = archive
  recursive = yes

[mediapool/renders]
  use_template = temporary
  recursive = yes

[template_production]
  frequently = 4          # каждые 15 минут, хранить 4
  hourly = 24             # каждый час, хранить 24
  daily = 30              # каждый день, хранить 30
  monthly = 6             # каждый месяц, хранить 6
  yearly = 1              # каждый год, хранить 1
  autosnap = yes
  autoprune = yes

[template_archive]
  hourly = 0
  daily = 7
  monthly = 12
  yearly = 5              # 5 лет хранения годовых снапшотов
  autosnap = yes
  autoprune = yes

[template_temporary]
  frequently = 0
  hourly = 6
  daily = 3
  monthly = 0
  yearly = 0
  autosnap = yes
  autoprune = yes
# Установка sanoid
sudo apt install debhelper libcapture-tiny-perl \
  libconfig-inifiles-perl pv lzop mbuffer
git clone https://github.com/jimsalterjrs/sanoid.git
cd sanoid && sudo make install

# Добавляем в cron (каждые 15 минут)
echo "*/15 * * * * root /usr/local/sbin/sanoid --cron" | \
  sudo tee /etc/cron.d/sanoid

# Проверяем созданные снапшоты
zfs list -t snapshot -o name,creation,used -s creation
# NAME                                        CREATION             USED
# mediapool/projects@autosnap_2026-04-05_10:00  Sat Apr  5 10:00  0B
# mediapool/projects@autosnap_2026-04-05_10:15  Sat Apr  5 10:15  256M
# mediapool/projects@autosnap_2026-04-05_10:30  Sat Apr  5 10:30  1.2G

Восстановление файла, случайно удалённого монтажёром:

# Находим файл в снапшотах
find /mediapool/projects/.zfs/snapshot/ -name "final_cut_v3.mp4"

# Восстанавливаем из ближайшего снапшота
cp /mediapool/projects/.zfs/snapshot/autosnap_2026-04-05_10:15/project42/final_cut_v3.mp4 \
   /mediapool/projects/project42/final_cut_v3.mp4

За первый месяц работы монтажёры воспользовались восстановлением из снапшотов 14 раз. Раньше каждый такой случай означал потерю нескольких часов работы.

Offsite-репликация: syncoid и zfs send/receive

Для offsite-резервирования мы установили второй, менее мощный сервер в дата-центре с 24 дисками по 10 ТБ в конфигурации RAIDZ3 (тройная чётность — максимальная надёжность для архива).

Репликация через syncoid (часть пакета sanoid) использует встроенный механизм zfs send/receive:

# Первая полная репликация (может занять дни)
syncoid --recursive --no-privilege-escalation \
  mediapool/archive \
  backup@dc-server:backuppool/archive

# Инкрементальная репликация (только изменения с последнего снапшота)
# Занимает минуты, даже для 100 ТБ пула
syncoid --recursive --no-privilege-escalation \
  --sendoptions="Lce" \
  mediapool/archive \
  backup@dc-server:backuppool/archive

Параметры --sendoptions="Lce":

  • L — Large blocks (recordsize > 128K передаётся как есть)
  • c — Compressed send (данные передаются в сжатом виде, без распаковки)
  • e — Embed data (маленькие файлы встраиваются в метаданные)

Автоматизация через systemd timer:

# /etc/systemd/system/syncoid-archive.service
[Unit]
Description=ZFS offsite replication
After=network-online.target

[Service]
Type=oneshot
User=root
ExecStart=/usr/local/sbin/syncoid --recursive --no-privilege-escalation \
  --sendoptions="Lce" \
  mediapool/archive backup@dc-server:backuppool/archive
ExecStart=/usr/local/sbin/syncoid --recursive --no-privilege-escalation \
  --sendoptions="Lce" \
  mediapool/projects backup@dc-server:backuppool/projects
TimeoutStartSec=86400

# /etc/systemd/system/syncoid-archive.timer
[Unit]
Description=Run ZFS replication every 6 hours

[Timer]
OnCalendar=*-*-* 00,06,12,18:00:00
Persistent=true

[Install]
WantedBy=timers.target
# Включаем таймер
sudo systemctl enable --now syncoid-archive.timer

# Проверяем статус последней репликации
systemctl status syncoid-archive.service
journalctl -u syncoid-archive.service --since today

Инкрементальная репликация 100 ТБ пула передаёт только изменённые блоки. В среднем за 6 часов в «ВидеоПро» меняется 50-200 ГБ данных — репликация завершается за 15-40 минут по гигабитному каналу.

Шифрование и special vdev для метаданных

Часть проектов «ВидеоПро» — корпоративные ролики с NDA. Данные на offsite-сервере в дата-центре должны быть зашифрованы:

# Создаём зашифрованный датасет
zfs create -o encryption=aes-256-gcm \
  -o keyformat=passphrase \
  -o keylocation=file:///root/.zfs-keys/archive.key \
  backuppool/archive-encrypted

# Генерируем ключ
openssl rand -hex 32 > /root/.zfs-keys/archive.key
chmod 400 /root/.zfs-keys/archive.key

# Автоматическая загрузка ключа при загрузке
# /etc/systemd/system/zfs-load-key.service
[Unit]
Description=Load ZFS encryption keys
Before=zfs-mount.service
After=zfs-import.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/sbin/zfs load-key -a

[Install]
WantedBy=zfs-mount.service

Шифрование добавляет ~5% overhead по CPU при использовании AES-NI (поддерживается всеми современными серверными CPU).

Special vdev — отдельная группа быстрых дисков (SSD/NVMe) для хранения метаданных ZFS. Это драматически ускоряет операции ls, find, обход дерева каталогов — что критично при 100+ ТБ с миллионами файлов:

# Добавляем special vdev из двух NVMe в зеркале
zpool add mediapool special mirror \
  /dev/disk/by-id/nvme-Samsung_980_PRO_1TB_A \
  /dev/disk/by-id/nvme-Samsung_980_PRO_1TB_B

# Настраиваем, какие блоки попадают на special vdev
zfs set special_small_blocks=64K mediapool
# Все блоки <= 64K (метаданные, маленькие файлы) будут храниться на NVMe

# Результат: ls по каталогу с 50 000 файлами
# До special vdev: 12 секунд
# После special vdev: 0.3 секунды

Для ARC-кеша (Adaptive Replacement Cache) мы выделили 64 ГБ RAM из 128 ГБ:

# /etc/modprobe.d/zfs.conf
options zfs zfs_arc_max=68719476736   # 64 ГБ
options zfs zfs_arc_min=17179869184   # 16 ГБ минимум

# Проверяем статистику ARC
arcstat -f hits,misses,hit%,size
# ARC hits:  94.2%
# ARC size:  61.3 GiB

Clone и zvol: тестирование и iSCSI

ZFS clone — мгновенная копия датасета на основе снапшота. Клон не занимает места до тех пор, пока в него не вносятся изменения (благодаря CoW).

Сценарий в «ВидеоПро»: монтажёр хочет попробовать экспериментальную цветокоррекцию на проекте весом 2 ТБ, не рискуя оригиналом:

# Создаём снапшот текущего состояния
zfs snapshot mediapool/projects/project42@before-experiment

# Клонируем — мгновенно, 0 байт занято
zfs clone mediapool/projects/project42@before-experiment \
  mediapool/experiments/project42-colorgrade

# Монтажёр работает с клоном как с обычной папкой
ls /mediapool/experiments/project42-colorgrade/

# Если результат понравился — продвигаем клон
zfs promote mediapool/experiments/project42-colorgrade

# Если нет — удаляем клон за секунду
zfs destroy mediapool/experiments/project42-colorgrade

zvol — блочное устройство поверх ZFS. Мы использовали его для iSCSI-таргета, к которому подключаются рабочие станции монтажёров по 10GbE:

# Создаём zvol на 5 ТБ для рабочей станции монтажёра
zfs create -V 5T -o volblocksize=64K mediapool/iscsi/workstation01

# Настраиваем iSCSI через targetcli
sudo apt install targetcli-fb
sudo targetcli

/> /backstores/block create ws01 /dev/zvol/mediapool/iscsi/workstation01
/> /iscsi create iqn.2026-04.ru.videopro:ws01
/> /iscsi/iqn.2026-04.ru.videopro:ws01/tpg1/luns create /backstores/block/ws01
/> /iscsi/iqn.2026-04.ru.videopro:ws01/tpg1/acls create iqn.2026-04.ru.videopro:initiator01
/> saveconfig
/> exit

Монтажёры получают блочное устройство с производительностью локального SSD, но с преимуществами ZFS: снапшоты, компрессия, проверка целостности.

Результаты и планирование ёмкости

Итоги проекта для «ВидеоПро» после 3 месяцев эксплуатации:

МетрикаДо (RAID-6)После (ZFS RAIDZ2)
Обнаружение bitrotНевозможноАвтоматически (scrub)
Восстановление файлаНевозможно< 1 минуты (снапшот)
Offsite-бэкапОтсутствуетКаждые 6 часов
Время rebuild диска72 часа18 часов (resilver)
ls по 50K файлам8 секунд0.3 секунды
Эффективная ёмкость140 ТБ180 ТБ (+компрессия ~15%)

Планирование ёмкости: ZFS рекомендует держать заполненность пула ниже 80% для оптимальной производительности CoW. При текущих 100 ТБ данных и ёмкости 180 ТБ запас составляет 44%. При росте 2-3 ТБ в месяц этого хватит на 2+ года.

# Мониторинг ёмкости
zpool list -o name,size,alloc,free,frag,cap,health
# NAME       SIZE   ALLOC   FREE   FRAG  CAP  HEALTH
# mediapool  218T   103T    115T    8%   47%  ONLINE

# Еженедельный scrub для проверки целостности
# /etc/cron.d/zfs-scrub
0 2 * * 0 root zpool scrub mediapool

# Проверяем результат scrub
zpool status mediapool | grep -A5 scan
#   scan: scrub repaired 0B in 18:42:33
#         with 0 errors on Sun Apr  5 20:42:33 2026

Если вашему бизнесу нужно надёжное хранилище больших объёмов данных с защитой от потерь — обращайтесь к нам на itfresh.ru. Мы спроектируем и внедрим ZFS-решение под ваши задачи.

Часто задаваемые вопросы

ZFS надёжнее благодаря контрольным суммам на каждый блок данных. Аппаратный RAID не знает о содержимом — он гарантирует только что данные записаны, но не что они корректны. ZFS обнаруживает и автоматически исправляет bitrot (тихое повреждение данных). Единственное преимущество аппаратного RAID — BBU (Battery Backup Unit) для кеша записи, но это решается ZFS SLOG.
Правило: 1 ГБ RAM на каждый 1 ТБ данных — минимум для комфортной работы ARC-кеша. Для 100 ТБ мы рекомендуем 128 ГБ RAM с выделением 64 ГБ под ARC. При использовании дедупликации потребность растёт в 3-5 раз, поэтому мы рекомендуем дедупликацию отключать и использовать вместо неё компрессию.
Да, но с ограничениями. Можно добавить новую RAIDZ-группу (vdev) к существующему пулу — это увеличивает и ёмкость, и производительность. Нельзя добавить отдельный диск в существующую RAIDZ-группу (начиная с OpenZFS 2.3 можно через RAIDZ Expansion, но это экспериментальная функция). Планируйте ёмкость заранее.
Scrub — это фоновая проверка целостности всех данных в пуле. ZFS читает каждый блок, проверяет контрольную сумму и автоматически восстанавливает повреждённые блоки из parity. Рекомендуем запускать раз в неделю для активных данных и раз в месяц для архивов. Scrub 100 ТБ занимает 18-24 часа и не мешает обычной работе.
Полностью без простоя — только при наличии свободного оборудования. Поднимаете ZFS-пул на новых дисках, монтируете параллельно с RAID, копируете данные через rsync с ключом --partial --progress. По завершении переключаете Samba/NFS шары на новые пути. Финальное переключение занимает 5-10 минут даунтайма.

Нужна помощь с проектом?

Специалисты АйТи Фреш помогут с архитектурой, DevOps, безопасностью и разработкой — 15+ лет опыта

📞 Связаться с нами
#openzfs#zfs#snapshots#replication#sanoid#syncoid#zvol#encryption
Комментарии 0

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

загрузка...