Выберите продукт

ZFS на VDS: snapshots, send/receive и сжатие lz4

Разбираем, как безопасно и эффективно применять ZFS на VDS: установка и базовая настройка, структура датасетов для веба и БД, стратегия snapshots и инкрементальной репликации send/receive, включение lz4. Также обсудим тюнинг под малую ОЗУ и I/O‑ограничения и практики резервного копирования.
ZFS на VDS: snapshots, send/receive и сжатие lz4

Если вы администрируете проекты на VDS и упёрлись в ограничения классических файловых систем, самое время посмотреть в сторону ZFS. Сильные стороны ZFS — контроль целостности, копирование при записи (CoW), мгновенные снимки, инкрементальная репликация и встроенное сжатие — особенно ценны на виртуальных серверах, где каждая операция ввода‑вывода и мегабайт переданного трафика стоят денег и времени.

В этой статье — практический разбор, как развернуть ZFS на VDS, рационально организовать структуру датасетов для веб‑проектов и БД, включить lz4, построить политику snapshots и репликации send/receive, а также избежать типичных ловушек: от неконтролируемого роста снапшотов до переполнения пула.

Когда ZFS на VDS имеет смысл

Даже с одним виртуальным диском ZFS приносит ощутимую пользу. Наиболее частые причины выбора:

  • Быстрые и почти бесплатные по времени snapshots, моментальные откаты и клоны для тестов.
  • Инкрементальные бэкапы через send/receive — экономия трафика и времени на резервирование.
  • Сжатие lz4: уменьшаем нагрузку на диск и сеть, повышаем эффективность на текстовых данных.
  • Проверка целостности и самовосстановление повреждённых блоков при наличии копий.

Что важно понимать: на VDS у вас часто один виртуальный диск без избыточности на уровне пула. Значит, отказоустойчивость достигается не зеркалированием в пределах пула, а регулярной репликацией на другой сервер или хранилище. ZFS в таком сценарии закрывает вопросы скорости и удобства бэкапа.

Ресурсы VDS: память, CPU и диск

ZFS использует ARC — кэш в памяти. На VDS с 2–4 ГБ ОЗУ имеет смысл ограничить ARC, чтобы процессам БД и PHP не было тесно. Типовые значения: 256–1024 МБ на небольших машинах. CPU‑накладные расходы lz4 близки к нулю для типичного веб‑нагрузочного профиля, а выигрыш по I/O и сети зачастую перекрывает издержки.

Хранилище на VDS чаще всего SSD‑бэкенд в облаке с virtio‑blk или virtio‑scsi внутри гостя. Важно создать пул с правильным выравниванием блоков. Для современных SSD выставляйте ashift=12 (4K‑секторы). Не забудьте включить автотрим на пуле, чтобы освобождённые блоки возвращались гипервизору.

Если выбираете размер машины под ZFS и БД, полезно ориентироваться на практику подбора ресурсов — смотрите разбор «Как выбрать план VDS по CPU и RAM» в материале подбора конфигурации VDS.

Установка ZFS и базовое включение

На Ubuntu и Debian достаточно штатных пакетов. После установки загрузите модуль и убедитесь, что всё работает.

sudo apt update
sudo apt install zfsutils-linux
sudo modprobe zfs
zpool version
zfs version

Если у вас один системный диск, а ZFS нужен для данных, имеет смысл выделить под пул отдельный дополнительный диск/том (например, /dev/vdb). Создание пула с полезными свойствами по умолчанию:

sudo zpool create -o ashift=12 -o autotrim=on -O compression=lz4 -O atime=off -O xattr=sa -O acltype=posixacl -O mountpoint=/srv zdata /dev/vdb
zpool status
zfs list

Ключевые моменты:

  • autotrim=on — регулярная передача TRIM гипервизору.
  • atime=off — не обновлять время доступа, уменьшаем лишние записи.
  • xattr=sa — хранить расширенные атрибуты эффективнее.
  • compression=lz4 — безопасное сжатие по умолчанию.

Если второй диск отсутствует, создавать пул из файла‑vdev не рекомендуется для продакшена. Лучше дождаться отдельного диска или мигрировать данные на отдельный том.

Структура датасетов под типичный стек

Разделяйте данные по профилю I/O: это позволяет гибко настраивать свойства и квоты, а также удобно делать выборочные снапшоты и репликацию.

# Корень данных проекта
sudo zfs create zdata/project

# Веб‑корень: большие файлы, кеши, статика
sudo zfs create -o recordsize=128K zdata/project/www

# Базы данных (MySQL/MariaDB): 16K блок
sudo zfs create -o recordsize=16K -o logbias=latency zdata/project/mysql

# PostgreSQL: обычно 8K или 16K, проверяйте PAGE_SIZE сборки
sudo zfs create -o recordsize=8K -o logbias=latency zdata/project/pg

# Логи: не всегда нужен snapshot, лучше ограничить рост
sudo zfs create -o recordsize=128K zdata/project/logs
sudo zfs set quota=5G zdata/project/logs

Зачем разные recordsize? ZFS с CoW хранит данные блоками. Чем ближе размер блока к реальному паттерну записи приложения, тем меньше лишних переписываний и фрагментации. Для InnoDB (обычно 16K) попадание по размеру критично; для статического контента выгоднее крупные блоки (128K).

Свойство logbias=latency помогает рабочим нагрузкам с синхронными записями (БД). Никогда не отключайте sync для баз в продакшене: это чревато потерей данных при сбоях.

Схема датасетов ZFS для веб‑проекта на VDS

Ограничение ARC на VDS с малой памятью

По умолчанию ARC может вырасти довольно заметно. На VDS в 2–4 ГБ стоит ограничить верхнюю границу:

echo 'options zfs zfs_arc_max=536870912' | sudo tee /etc/modprobe.d/zfs.conf
sudo update-initramfs -u
sudo reboot

Здесь zfs_arc_max установлен на 512 МБ. Подберите значение под свой проект, мониторьте потребление памяти и метрики ZFS.

Включаем и проверяем сжатие lz4

lz4 — дефолтный и лучший компромисс для VDS: минимальная нагрузка на CPU и хороший выигрыш на текстовых и JSON/PHP‑файлах, дампах БД, логах. Включать удобно на уровне пула или конкретного датасета:

zfs set compression=lz4 zdata
zfs get compression zdata/project/www
zfs get compressratio zdata/project/www

Следите за compressratio: реальный коэффициент сжатия покажет, есть ли профит. На статику и бэкапы в tar.gz рассчитывать не стоит — уже сжаты.

Snapshots: стратегия именования и ретеншн

Снапшоты создаются мгновенно и занимают место только за счёт дельты изменений. Простейшее правило — делать частые локальные снапшоты и удалять старые по политике. Например, почасовые за последние 24 часа, дневные — за 7–14 дней, недельные — за 4–8 недель.

Имя снапшота должно быть машинно‑сортируемым: @YYYYMMDD-HHMM. Рекурсивный снапшот корневого датасета проекта:

SNAP=$(date -u +%Y%m%d-%H%M)
sudo zfs snapshot -r zdata/project@${SNAP}
zfs list -t snapshot -r zdata/project

Для автоматизации используйте systemd‑таймеры или cron. В systemd‑подходе удобно вынести логику в скрипт и вызывать таймером разной периодичности, сохраняя единый формат имён и политику ретенции.

Пример: systemd‑юниты для почасовых снапшотов

sudo tee /usr/local/sbin/zfs-snapshot-hourly > /dev/null << 'EOF'
#!/usr/bin/env bash
set -euo pipefail
POOL_DATASET="zdata/project"
SNAP="$(date -u +%Y%m%d-%H%M)"
zfs snapshot -r "${POOL_DATASET}@${SNAP}"
# Удалить снапшоты старше 36 часов
zfs list -t snapshot -o name -s creation -r "${POOL_DATASET}" | grep "@" | head -n -24 | xargs -r -n 1 zfs destroy -r
EOF
sudo chmod +x /usr/local/sbin/zfs-snapshot-hourly

sudo tee /etc/systemd/system/zfs-snapshot-hourly.service > /dev/null << 'EOF'
[Unit]
Description=ZFS hourly snapshots

[Service]
Type=oneshot
ExecStart=/usr/local/sbin/zfs-snapshot-hourly
EOF

sudo tee /etc/systemd/system/zfs-snapshot-hourly.timer > /dev/null << 'EOF'
[Unit]
Description=Run ZFS hourly snapshots

[Timer] 
Persistent=true

[Install]
WantedBy=timers.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable --now zfs-snapshot-hourly.timer

Политику удаления подберите под собственный объём и RPO. Для датасетов со стремительным приростом (логи, кеши) снапшоты можно отключать или жёстко ограничивать через квоты.

send/receive: как устроить инкрементальные бэкапы

Основная сила ZFS в бэкапах — потоковые операции send/receive. Базовая идея: первый раз отправляем полный снапшот, далее — только дельты между последовательными снапшотами.

Локальная репликация

Если у вас на сервере есть второй пул (например, другой диск), можно делать локальную резервную копию:

# Первый полный перенос
zfs send -R zdata/project@20250101-0100 | zfs receive -F backup/project

# Инкрементальный перенос
zfs send -R -I 20250101-0100 zdata/project@20250101-0200 | zfs receive -F backup/project

Ключ -R переносит вместе со снапшотом все дочерние датасеты и свойства. Ключ -I отправляет цепочку инкрементов от указанной точки до целевого снапшота.

Репликация по SSH на удалённый сервер

Принцип тот же, но поток уходит через SSH. Перед первой отправкой оцените объём:

# Оценка размера потока
zfs send -nP -R zdata/project@20250101-0100

# Полный бэкап по SSH (пример)
zfs send -R zdata/project@20250101-0100 | ssh user@backup-host zfs receive -F backup/project

# Инкремент
zfs send -R -I 20250101-0100 zdata/project@20250101-0200 | ssh user@backup-host zfs receive -F backup/project

Для нестабильных каналов используйте возобновляемую передачу: флаг -s у send и аналогичная поддержка у receive. Также можно вставить буферизатор потока между send и receive для сглаживания пульсаций сети.

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

zfs hold keep zdata/project@20250101-0200
# ... репликация ...
zfs release keep zdata/project@20250101-0200

Схема репликации ZFS send/receive по SSH

Восстановление: rollback, clone и выборочная отдача

Откат к снапшоту моментален, но уничтожает изменения «сверху» текущей версии датасета. Используйте аккуратно на боевых датасетах БД.

# Мгновенный откат всего датасета
zfs rollback -r zdata/project@20250101-0200

Безопаснее — поднять клон для проверки, переключить сервисы и затем принять решение:

zfs clone zdata/project@20250101-0200 zdata/project-verify
# смонтировать, проверить, затем удалить клон
zfs destroy zdata/project-verify

Квоты и свободное место: не загоняйте пул в 100%

Заполнять пул под завязку в ZFS — плохая идея: растёт фрагментация и деградирует производительность, операции могут начать ошибаться из‑за нехватки места под метаданные. Держите 10–20% свободного. Для шумных датасетов (логи, кеши) задавайте quota/refquota и чистите регулярно.

zfs set quota=5G zdata/project/logs
zfs set refquota=2G zdata/project/www
zfs list -o name,used,available,refer,referenced,quota,refquota -r zdata/project

Обслуживание: scrub, мониторинг и уведомления

Периодически запускайте zpool scrub для проверки целостности. На VDS с одним диском scrub всё равно имеет смысл: он обнаружит немые повреждения и позволит ZFS восстановить данные, если настроены дополнительные копии на уровне датасета.

sudo zpool scrub zdata
zpool status -x
zpool iostat -v 1

Настройте системные уведомления по событиям ZFS (zed) и интеграцию с вашей системой мониторинга: статус пула, свободное место, частота ошибок ввода‑вывода, длительность транзакционных групп.

Опции, которые часто спрашивают

  • Сжатие gzip/zstd вместо lz4? zstd даёт больший коэффициент сжатия, но и выше CPU‑стоимость. На 1–2 vCPU VDS по умолчанию оставайтесь с lz4. Можно точечно включать zstd для архивных, редко изменяемых данных.
  • Собственный SLOG (журнал) на VDS? На виртуалке дополнительный реально отдельный низколатентный диск под SLOG обычно недоступен. Разносить журнал на тот же пул бессмысленно; лучше положиться на стандартный ZIL и корректный sync у приложений.
  • Encryption на уровне ZFS? Встроенное шифрование доступно и полезно, но учитывайте накладные расходы CPU и процедуру управления ключами. Тестируйте заранее.
  • copies=2 на одном диске? Может помочь от битых блоков, но увеличит запись в 2 раза. На VDS чаще выгоднее регулярная send/receive‑репликация на удалённый узел.

Типичный рабочий конвейер Dev/Prod

У веб‑проектов удобный паттерн выглядит так: в продакшене раз в час делается рекурсивный снапшот корневого датасета проекта, тут же уходит инкремент на бэкап‑сервер. Для тестовой среды вы по запросу берёте свежий снапшот продакшена и получаете клон на staging без копирования данных. Для миграций — сначала полный send, затем короткие инкременты до окна переключения, после которого выполняете финальный инкремент и атомарный запуск на новом сервере.

ZFS не только про «быстро откатиться». Это про воспроизводимые миграции и бэкапы, где дельты считаются файловой системой, а не утилитами общего назначения.

Проверочный чек‑лист перед запуском в продакшен

  • Пул создан с ashift=12, включены autotrim=on, atime=off, compression=lz4, xattr=sa.
  • Датасеты разделены по ролям: www, db, logs и др.; на БД задан recordsize 8K/16K и logbias=latency.
  • Ограничен ARC через zfs_arc_max для экономии ОЗУ на слабых VDS.
  • Настроены почасовые/дневные snapshots и ретеншн; снапшоты именуются @YYYYMMDD-HHMM.
  • Отлажен конвейер send/receive: полный первый бэкап и инкременты; есть hold‑марки до доставки.
  • Критичные шумные датасеты имеют квоты; пул не заполняется свыше 80–90%.
  • Раз в неделю/месяц запускается zpool scrub и мониторятся алерты.

Отладка производительности

На симптом «медленно» смотрим метрики: задержки I/O (zpool iostat -v), утилизация CPU и процент кэш‑попаданий (ARC hit/miss в экспозиции ZFS). Если база часто читает одно и то же, увеличьте ARC в разумных пределах. При высоком проценте синхронных записей проверьте конфигурации БД: режим fsync, размеры журналов, паттерны чекпоинтов. За деталями по СУБД смотрите практикум по оптимизации в статье тюнинг PostgreSQL.

Вывод

ZFS отлично чувствует себя на VDS и решает задачи, которые раньше требовали сложной комбинации rsync+tar+mysqldump+скриптов. Снимки за секунды, инкрементальная репликация, честные бэкапы на уровне блоков и прозрачное сжатие lz4 — это реальная экономия и повышение надёжности. Начните с аккуратной разметки датасетов, включите lz4, автоматизируйте snapshots и send/receive — и у вас будет простой, воспроизводимый и быстрый процесс резервного копирования и миграций.

Поделиться статьей

Вам будет интересно

Debian/Ubuntu: как исправить APT Hash Sum mismatch и File has unexpected size OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: как исправить APT Hash Sum mismatch и File has unexpected size

Ошибки APT Hash Sum mismatch, File has unexpected size и packages.gz mismatch обычно связаны не с поломкой apt, а с рассинхроном з ...
Debian/Ubuntu: как исправить apt update с ошибкой Release file changed OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: как исправить apt update с ошибкой Release file changed

Если при apt update появляется Release file changed, repository changed its suite или codename, это не всегда сбой. Разберём, как ...
Debian и Ubuntu: почему APT пишет kept back и held packages, и как это исправить OpenAI Статья написана AI (GPT 5)

Debian и Ubuntu: почему APT пишет kept back и held packages, и как это исправить

Сообщения APT вроде kept back и held packages в Debian и Ubuntu не всегда означают поломку. Часто это phased updates, ручной hold, ...