Оба файловых стека умеют почти одно и то же на бумаге: снимки, контрольные суммы, сжатие, программный RAID. Но за одинаковым списком функций скрываются два совершенно разных инженерных подхода, и на домашнем сервере эта разница ощущается быстрее, чем кажется на первый взгляд. Разбираемся, откуда берутся расхождения и что из этого действительно важно для NAS с парой дисков дома, а не для серверной стойки в дата-центре.

Архитектурные различия, из которых вырастает всё остальное

Btrfs изначально писалась как часть ядра Linux и распространяется под лицензией GPL, поэтому она встроена в mainline-ядро и доступна из коробки практически в любом современном дистрибутиве. ZFS появилась в Sun Microsystems под лицензией CDDL, которая юридически несовместима с GPL, из-за чего в Linux она до сих пор поставляется как модуль OpenZFS, собираемый отдельно от ядра через DKMS. Это не просто формальность: любое обновление ядра теоретически может временно сломать сборку ZFS-модуля, пока разработчики OpenZFS не выпустят патч под новую версию, тогда как Btrfs обновляется синхронно с самим ядром. Другое фундаментальное отличие касается кеширования. ZFS использует собственный менеджер кеша ARC (Adaptive Replacement Cache), который живёт в оперативной памяти отдельно от стандартного page cache Linux и агрессивно резервирует под себя память, тогда как Btrfs полагается на обычный механизм кеширования страниц ядра и не требует отдельной настройки под объём RAM. Обе системы построены на модели copy-on-write, то есть при изменении данных они не перезаписывают существующие блоки на месте, а пишут новые и лишь потом переключают указатели, но реализована эта модель на очень разных внутренних структурах: Btrfs использует B-деревья с общими корнями для файлов и метаданных, а ZFS строит настоящее дерево Меркла, где любое повреждение блока моментально проявляется как несовпадение контрольной суммы на верхнем уровне иерархии. Ещё одно менее очевидное различие касается того, как обе системы переживают внезапное отключение питания. ZFS группирует все изменения в так называемые транзакционные группы и записывает их атомарно: если питание пропало посреди записи, система при следующей загрузке просто откатывается к последней полностью завершённой транзакционной группе, полностью игнорируя незавершённую, и файловая система остаётся в согласованном состоянии без отдельной процедуры проверки. Btrfs действует похожим образом на уровне отдельных операций записи метаданных, но исторически считается чуть менее предсказуемой именно в сценариях с внезапной потерей питания на RAID-массивах, о чём подробнее в разделе про RAID ниже.

Как устроены снимки в Btrfs на уровне subvolume

В Btrfs единицей, с которой работают снимки, является subvolume, то есть независимое поддерево файловой системы со своим собственным пространством имён. Команда для создания снимка выглядит просто:

btrfs subvolume snapshot -r /home /.snapshots/home-2026-08-18

Флаг -r делает снимок доступным только для чтения, что важно для последующей отправки через send и receive. Технически такой снимок это ещё один subvolume, который через механизм reflink-копий делит физические блоки данных с оригиналом: пока файлы не менялись, снимок не занимает почти никакого дополнительного места на диске, а по мере изменения исходных данных старые блоки остаются закреплены за снимком благодаря copy-on-write. У этой простоты есть обратная сторона. В Btrfs нет встроенного понятия отката файловой системы к состоянию снимка одной командой: чтобы вернуться к прежней версии данных, нужно вручную создать доступный для записи снимок от read-only снимка и подменить им текущий subvolume, либо использовать сторонние инструменты вроде snapper, которые автоматизируют эту последовательность действий. Иерархия subvolume в Btrfs также устроена менее строго, чем в ZFS: подтома не образуют такую же чёткую древовидную структуру с наследованием свойств, и утилиты вроде btrbk берут на себя часть той организационной работы, которую ZFS делает средствами самой файловой системы. Сжатие в Btrfs включается на уровне точки монтирования или конкретного каталога через опцию compress, например zstd, и применяется прозрачно ко всем новым записям, а дедупликация не встроена в реальном времени и обычно выполняется отдельной фоновой утилитой вроде duperemove или bees, что для домашнего сервера означает дополнительный процесс, который нужно будет настроить и запускать по расписанию, если экономия места действительно важна.

Как устроены снимки в ZFS на уровне датасета

В ZFS базовой единицей служит датасет, и снимок создаётся практически идентичной по смыслу командой:

zfs snapshot pool/home@2026-08-18

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

zfs rollback pool/home@2026-08-18

Она мгновенно возвращает весь датасет к состоянию снимка, без промежуточных шагов с созданием записываемых копий, хотя и с оговоркой, что все более поздние снимки на этом же датасете придётся удалить. Ещё одно практическое отличие: свойства датасета в ZFS, такие как квоты, сжатие или лимиты по количеству снимков, наследуются по иерархии автоматически, а в Btrfs subvolume такого встроенного наследования нет, и за него отвечают уже внешние инструменты. Для домашнего сервера это означает разный уровень контроля из коробки: ZFS сразу даёт строгую и предсказуемую структуру, а Btrfs требует больше ручной настройки или дополнительного пакета вроде snapper, но взамен интегрируется прямо в загрузчик через GRUB и systemd-boot, позволяя выбрать снимок для отката ещё на этапе загрузки системы, чем ZFS в Linux из коробки не умеет. Сжатие и дедупликация в ZFS настраиваются как обычные свойства датасета, например через команду zfs set compression=zstd pool/home, и в отличие от Btrfs дедупликация здесь может работать в реальном времени на уровне блоков, хотя для этого требуется заметно больше оперативной памяти под таблицу дедупликации, из-за чего на скромном домашнем железе с 8 или 16 гигабайтами RAM её обычно рекомендуют не включать и полагаться только на сжатие.

Реальная разница при отправке снимков и восстановлении данных

Обе системы умеют инкрементально пересылать разницу между снимками на другой диск или удалённый сервер, и синтаксис у них внешне похож:

btrfs send -p /.snapshots/home-day1 /.snapshots/home-day2 | btrfs receive /mnt/backup
zfs send -i pool/home@day1 pool/home@day2 | zfs receive backup/home

Но механика различается. В Btrfs send сравнивает деревья двух конкретных снимков и вычисляет разницу заново при каждой отправке, обходя структуру b-дерева; для непрерывной цепочки инкрементальных копий обязательно нужно, чтобы родительский снимок физически присутствовал и не был переименован ни на одной из сторон, иначе цепочка ломается и требуется повторная полная передача. В ZFS каждый снимок жёстко привязан к своей транзакционной группе, поэтому инкрементальная отправка опирается не на сравнение деревьев, а на разницу номеров транзакций, что делает процесс более предсказуемым при большом количестве накопленных снимков. Ключевое практическое отличие для домашнего использования проявляется при восстановлении отдельных файлов: в ZFS можно смонтировать снимок напрямую по скрытому пути вроде pool/home/.zfs/snapshot/2026-08-18 и скопировать оттуда нужный файл без дополнительных действий, а в Btrfs снимок subvolume тоже доступен для просмотра по своему пути в файловой системе, но из-за отсутствия единой точки монтирования вроде .zfs пользователю приходится помнить и находить точное расположение каждого снимка вручную или полагаться на настройку snapper.

RAID и защита данных на нескольких дисках

Для домашнего сервера с несколькими накопителями разница становится критичной. ZFS реализует собственные уровни RAIDZ1, RAIDZ2 и RAIDZ3 на уровне самой файловой системы, где контрольные суммы проверяются для каждого блока при каждом чтении, а восстановление после сбоя диска использует только реально записанные данные, а не весь объём тома, что заметно ускоряет ресинхронизацию на частично заполненном пуле. Встроенный в Btrfs RAID5 и RAID6 долгое время официально помечен разработчиками как нестабильный из-за так называемой проблемы write hole: при внезапном отключении питания во время записи чётность может рассинхронизироваться с данными, и без дополнительного журнала это способно привести к тихому повреждению информации при восстановлении после сбоя диска. Поэтому на практике для многодискового домашнего NAS с Btrfs чаще рекомендуют профиль RAID1 или RAID10 вместо RAID5/6, либо совмещать Btrfs с аппаратным или программным RAID более низкого уровня, тогда как ZFS можно без лишних ухищрений доверять RAIDZ прямо из коробки.

Требования к памяти и железу для домашнего сценария

ARC в ZFS по умолчанию стремится занять значительную часть оперативной памяти сервера, что заметно ускоряет повторные чтения, но на слабом домашнем NAS с 4 или 8 гигабайтами RAM требует ручного ограничения через параметр zfs_arc_max, иначе система может начать конкурировать за память с другими сервисами вроде контейнеров или медиасервера, запущенными на том же железе. Btrfs в этом смысле куда более гостеприимна к скромному железу, поскольку использует стандартный page cache и не нуждается в отдельной настройке под конкретный объём памяти. Вопрос ECC-памяти для обеих систем часто преподносят как обязательное требование, но на деле ECC снижает риск порчи данных ещё до того, как они попадут на диск, независимо от выбранной файловой системы, а не является специфическим требованием именно ZFS, как иногда ошибочно считают в сообществе. Для типичного домашнего сервера на потребительском железе без ECC обе системы одинаково полезны своими контрольными суммами именно потому, что обнаруживают повреждения, уже случившиеся на самом накопителе или в процессе передачи по шине. Стоит также учитывать нагрузку на сам накопитель: из-за постоянной перезаписи метаданных и природы copy-on-write обе файловые системы создают несколько больше операций записи на SSD по сравнению с классической ext4, что для домашнего сценария почти никогда не критично при современном ресурсе накопителей, но стоит держать в уме при выборе бюджетного SSD с невысоким заявленным ресурсом перезаписи под систему с частыми автоматическими снимками.

Какую систему выбрать под конкретный домашний сценарий

Если сервер собирается на дистрибутиве, где Btrfs уже стоит по умолчанию и глубоко интегрирована в систему, например на openSUSE Tumbleweed или на Fedora, разумно остаться на Btrfs хотя бы для корневого раздела: снимки перед обновлением пакетов и откат прямо из меню загрузчика закрывают львиную долю домашних сценариев с минимальной настройкой. Для выделенного хранилища с несколькими дисками под медиатеку, резервные копии или виртуальные машины ZFS предсказуемее ведёт себя под нагрузкой и надёжнее защищает данные при сбое одного из накопителей за счёт продуманного RAIDZ и честного отслеживания транзакций, поэтому её выбирают решения вроде TrueNAS и Proxmox VE, где ZFS доступна из коробки без танцев с DKMS. Ничего не мешает совмещать оба варианта на одном сервере: например, держать быструю Btrfs на системном разделе, где важна интеграция с загрузчиком, и вынести основной массив данных на ZFS, где решает предсказуемость под нагрузкой и надёжность многодискового RAID. Итоговый выбор чаще определяется не абстрактным превосходством одной системы над другой, а тем, что именно нужно чаще на конкретном домашнем сервере: быстрый откат системы после неудачного обновления или спокойствие за терабайты семейных фотографий и видео на нескольких дисках.