Настройка ZFS: создание пула, томов и оптимизация под нагрузку | AdminWiki

Настройка ZFS: создание пула, томов и оптимизация под нагрузку

22 июля 2026 8 мин. чтения

Быстрый старт: создание первого пула ZFS

ZFS объединяет функции файловой системы и менеджера томов. Пул (zpool) - это базовый строительный блок, который агрегирует физические диски в единое пространство хранения. Перед созданием пула определитесь с уровнем избыточности: от него зависит скорость, доступная ёмкость и устойчивость к отказу дисков. Параметр ashift задаёт размер сектора и критически важен для производительности. Для современных дисков с 4K-секторами (включая SSD) всегда устанавливайте ashift=12. Используйте идентификаторы дисков из /dev/disk/by-id/, чтобы избежать проблем при смене порядка устройств после перезагрузки. Операция создания пула необратима - все данные на указанных дисках будут уничтожены.

Stripe (без избыточности): максимальная скорость и ёмкость

Страйп распределяет данные полосами по всем дискам без какой-либо защиты. Выход из строя одного накопителя уничтожает весь пул. Используйте эту конфигурацию только для временных данных, кэша или тестовых сред, где потеря информации допустима. Суммарная ёмкость равна сумме объёмов всех дисков, скорость чтения и записи линейно растёт с их количеством.

zpool create -o ashift=12 fastpool /dev/disk/by-id/ata-DISK1 /dev/disk/by-id/ata-DISK2

Mirror: простое зеркалирование

Зеркало хранит идентичные копии данных на каждом диске в группе. Конфигурация выдерживает отказ N-1 накопителей в одном vdev. Производительность чтения высокая, так как ZFS может читать с разных дисков параллельно. Скорость записи ограничена самым медленным диском в зеркале. Добавить второе зеркало в существующий пул можно командой zpool attach, расширяя ёмкость без пересоздания структуры.

zpool create -o ashift=12 securepool mirror /dev/disk/by-id/ata-DISK1 /dev/disk/by-id/ata-DISK2

Добавление ещё одного зеркального vdev для расширения:

zpool add securepool mirror /dev/disk/by-id/ata-DISK3 /dev/disk/by-id/ata-DISK4

RAID-Z: компромисс между ёмкостью и надёжностью

RAID-Z использует распределённую чётность для защиты данных. RAID-Z1 выдерживает отказ одного диска, RAID-Z2 - двух, RAID-Z3 - трёх. Для массивов из 4-6 дисков оптимален RAID-Z2: он даёт достаточную избыточность при приемлемой потере ёмкости. Не используйте RAID-Z1 для дисков объёмом более 2 ТБ - процесс восстановления (resilver) создаёт высокую нагрузку, и вероятность второго отказа до его завершения значительна. Подробнее архитектура vdev и распределение данных разобраны в статье об архитектуре ZFS.

# RAID-Z1 из трёх дисков
zpool create -o ashift=12 tank raidz /dev/disk/by-id/ata-DISK1 /dev/disk/by-id/ata-DISK2 /dev/disk/by-id/ata-DISK3

# RAID-Z2 из шести дисков
zpool create -o ashift=12 tank raidz2 /dev/disk/by-id/ata-DISK1 /dev/disk/by-id/ata-DISK2 /dev/disk/by-id/ata-DISK3 /dev/disk/by-id/ata-DISK4 /dev/disk/by-id/ata-DISK5 /dev/disk/by-id/ata-DISK6

Создание датасетов и включение сжатия

Датасет - это логическая единица внутри пула, для которой задаются индивидуальные политики хранения. В отличие от разделов в традиционных системах, датасеты не требуют предварительного выделения места и динамически используют свободное пространство пула. Сжатие на ZFS - обязательная практика. Современные процессоры обрабатывают алгоритм lz4 с пренебрежимо малой задержкой, а экономия места для типовых данных достигает 30-50%. Создайте датасет и включите сжатие одной командой:

zfs create tank/data
zfs set compression=lz4 tank/data

Проверьте коэффициент сжатия после записи данных:

zfs get compressratio tank/data

Выбор алгоритма сжатия под нагрузку

Алгоритм lz4 - стандарт для большинства сценариев. Он обеспечивает высокую скорость при среднем коэффициенте сжатия и практически не нагружает CPU. gzip-9 даёт максимальную степень сжатия, но кратно увеличивает задержку и потребление процессора. Применяйте его только для архивных данных, к которым редко обращаются. zle сжимает только последовательности нулей и подходит для датасетов с разреженными файлами или неинициализированными блоками виртуальных машин. Для логов и текстовых данных рассмотрите zstd - он превосходит lz4 по степени сжатия при сопоставимой скорости.

# Архивный датасет с максимальным сжатием
zfs create tank/archive
zfs set compression=gzip-9 tank/archive

# Датасет для разреженных файлов
zfs create tank/sparse
zfs set compression=zle tank/sparse

Дедупликация: когда она оправдана и как включить

Дедупликация исключает хранение одинаковых блоков данных. Механизм работает на уровне блоков: ZFS вычисляет хеш каждого блока и сохраняет только уникальные экземпляры. За это приходится платить оперативной памятью. Таблица дедупликации (DDT) требует примерно 5 ГБ RAM на каждый терабайт уникальных данных. Если DDT не помещается в ARC, производительность падает катастрофически - система начинает читать таблицу с диска при каждой операции записи. Включайте дедупликацию осознанно и только после расчёта необходимого объёма памяти. Детальный разбор с тестами и алгоритмом расчёта памяти приведён в статье о дедупликации в ZFS.

zfs set dedup=on tank/vms

Сценарии, где дедупликация окупается: десятки однотипных виртуальных машин (VDI), контейнеры Docker с общими базовыми образами, системы резервного копирования с малым количеством изменений между версиями. Для логов, медиафайлов и баз данных с уникальным контентом дедупликация не даёт выигрыша - используйте сжатие lz4 или zstd.

Тюнинг производительности под разные сценарии

ZFS предоставляет параметры, которые напрямую влияют на поведение подсистемы ввода-вывода. Ключевые из них: recordsize - размер блока данных для файлов в датасете, sync - режим обработки синхронных запросов записи, primarycache - политика кэширования в ARC, secondarycache - использование L2ARC. Правильная комбинация этих параметров под конкретную нагрузку даёт прирост производительности в разы. Ошибочная - приводит к деградации. Ниже приведены готовые профили для трёх типовых сценариев. Если вы работаете с TrueNAS, настройка виртуальных машин и ZFS-хранилищ описана в руководстве по TrueNAS SCALE.

Профиль для баз данных (PostgreSQL, MySQL)

СУБД оперируют мелкими случайными чтениями и записями блоками по 8 КБ. Установите recordsize=8K, чтобы размер блока ZFS совпадал со страницей базы данных - это исключает дорогостоящие операции read-modify-write. Для транзакционных нагрузок критична целостность: sync=standard оставляет решение за приложением, но для максимальной надёжности используйте отдельное устройство SLOG на NVMe с высокой стойкостью к износу. Кэширование данных в ARC отключите (primarycache=metadata) - СУБД эффективнее управляет своим буферным пулом сама.

zfs create tank/postgres
zfs set recordsize=8K tank/postgres
zfs set primarycache=metadata tank/postgres
zfs set sync=standard tank/postgres
# Добавление SLOG на NVMe
zpool add tank log /dev/disk/by-id/nvme-INTEL_SSD_1

Профиль для виртуальных машин (KVM, VMware)

Образы виртуальных машин генерируют смешанную нагрузку. Для файловых образов (qcow2, raw) на датасете установите recordsize=64K - компромисс между случайным и последовательным доступом. Для zvol (блочных устройств) аналогом выступает volblocksize=64K. Параметр sync=always гарантирует, что каждый запрос записи от гостевой ОС будет подтверждён только после фиксации на постоянном хранилище - это снижает производительность, но исключает потерю данных при сбое питания.

zfs create tank/vmdata
zfs set recordsize=64K tank/vmdata
zfs set sync=always tank/vmdata
# Для zvol
zfs create -V 100G -o volblocksize=64K tank/vmdisk

Профиль для медиафайлов и бэкапов

Последовательный доступ большими блоками - основная характеристика этой нагрузки. Увеличьте recordsize=1M для максимальной пропускной способности и минимальных метаданных. Весь ARC отдайте под данные: primarycache=all. Сжатие lz4 снижает объём записываемых данных без заметного влияния на скорость. Для некритичных данных, где допустима потеря последних нескольких секунд записи при сбое, отключите синхронные подтверждения - это кратно повышает скорость записи.

zfs create tank/media
zfs set recordsize=1M tank/media
zfs set primarycache=all tank/media
zfs set compression=lz4 tank/media
zfs set sync=disabled tank/media

Автоматические снэпшоты и ротация

Снэпшот ZFS - это мгновенный снимок состояния датасета, который не занимает места до тех пор, пока данные не начнут изменяться. Регулярные снэпшоты защищают от случайного удаления, шифровальщиков и ошибок конфигурации. Автоматизируйте их создание через cron - это базовая практика, которая не требует внешних инструментов. Скрипт ниже создаёт снэпшот с меткой даты и удаляет копии старше 7 дней.

#!/bin/bash
# Создание снэпшота
zfs snapshot tank/data@$(date +%Y-%m-%d)

# Удаление снэпшотов старше 7 дней
zfs list -H -o name -t snapshot tank/data | sort | head -n -7 | xargs -r zfs destroy

Добавьте запуск в cron ежедневно в 2 часа ночи:

0 2 * * * /usr/local/bin/zfs-snapshot.sh

Для репликации на другой сервер используйте связку zfs send и zfs receive. Инкрементальные отправки передают только изменившиеся блоки, что эффективно для резервного копирования по сети.

# Первичная отправка
zfs send tank/data@2026-07-22 | ssh backup-server zfs receive backuppool/data

# Инкрементальная
zfs send -i tank/data@2026-07-22 tank/data@2026-07-23 | ssh backup-server zfs receive backuppool/data

Мониторинг состояния пула и замена дисков

Регулярный мониторинг - обязательная часть эксплуатации ZFS. Команда zpool status -v показывает состояние всех vdev, ошибки чтения/записи/контрольной суммы и статус восстановления. Запускайте её при каждом входе в систему или настройте автоматическую отправку вывода в систему мониторинга. zpool iostat отображает текущую пропускную способность и IOPS по каждому vdev - используйте для выявления узких мест. Не полагайтесь только на ZFS: мониторинг SMART-параметров дисков через smartctl позволяет предсказать отказ до того, как ZFS зафиксирует ошибки.

Плановая проверка целостности: scrub

Scrub - это фоновая операция, которая читает все данные в пуле и сверяет их с контрольными суммами. Обнаруженные ошибки автоматически исправляются за счёт избыточности (зеркала или чётности). Запускайте scrub ежемесячно для дисков потребительского класса и ежеквартально для корпоративных накопителей. Настройте автоматический запуск через cron в период минимальной нагрузки. Длительность операции зависит от объёма данных и может занимать часы или дни - это нормально.

# Ручной запуск
zpool scrub tank

# Проверка статуса
zpool status tank | grep scrub

# Автоматический scrub 1-го числа каждого месяца в 3:00
0 3 1 * * zpool scrub tank

Замена отказавшего диска в пуле

При отказе диска ZFS переводит пул в состояние DEGRADED и продолжает работу за счёт избыточности. Не перезагружайте сервер без необходимости - идентификаторы дисков могут измениться. Определите отказавшее устройство по выводу zpool status, физически замените накопитель и выполните команду замены. Если новый диск подключается в тот же слот, используйте zpool replace без указания старого устройства. Процесс восстановления (resilver) начнётся автоматически и не требует прерывания работы. Для критичных систем добавьте hot spare - диск, который ZFS автоматически введёт в строй при обнаружении отказа.

# Определение сбойного диска
zpool status -v tank

# Замена с указанием старого и нового диска
zpool replace tank /dev/disk/by-id/ata-FAILED_DISK /dev/disk/by-id/ata-NEW_DISK

# Добавление hot spare
zpool add tank spare /dev/disk/by-id/ata-SPARE_DISK

Если пул не импортируется автоматически после переноса дисков на другую систему, используйте принудительный импорт с ключом -f. Перед этим убедитесь, что пул не используется на исходном сервере - одновременный доступ с двух систем разрушит данные. Для серверов, развёрнутых в облаке, рассмотрите облачную инфраструктуру Timeweb Cloud с готовыми шаблонами и масштабируемым хранилищем, где задачи физической замены дисков берёт на себя провайдер.

Поделиться:
Сохранить гайд? В закладки браузера