Ubuntu zfs что это
Файловая система ZFS
В одной из предыдущих статей мы рассматривали файловую систему Btrfs. В нашей сегодняшней статье мы остановимся на ZFS, эти файловые системы похожи по своему применению и назначению, но имеют некоторые отличия. Мы рассмотрим как установить эту файловую систему в вашем дистрибутиве, настроить ее и использовать для решения повседневных задач.
Что такое ZFS?
Файловая система ZFS имеет обычные для таких файловых систем возможности. Это просто огромный размер одного раздела, и размер файла, поддерживается возможность хранения файлов на нескольких устройствах, проверка контрольных сумм для данных и шифрование на лету, а также запись новых данных в режиме COW, когда данные не переписываются, а пишутся в новое место, что позволяет делать мгновенные снапшоты.
Возможности очень похожи на Btrfs, но есть кое-какие отличия. В Btrfs можно посмотреть все файлы, измененные с момента последнего снапшота. Второе отличие, это отсутствие в Btrfs логических блоков zvol.
Установка ZFS
В последних версиях Ubuntu файловая система ZFS была добавлена в официальный репозиторий и в установочный диск. Поэтому для того, чтобы ее установить будет достаточно выполнить несколько команд:
В других дистрибутивах. например, CentOS или Fedora ситуация немного сложнее, сначала вам придется добавить официальный репозиторий, а затем установка zfs и самого набора утилит и модулей ядра:
sudo yum install http://download.zfsonlinux.org/epel/zfs-release.el7_3.noarch.rpm
$ sudo yum install zfs
Затем осталось включить загрузить модуль ядра с поддержкой этой файловой системы:
Теперь файловая система установлена и готова к использованию. Дальше нам нужно выбрать разделы и создать на них файловые системы. Для настройки zfs используется утилита zpool, но для начала давайте рассмотрим ее синтаксис и возможности. Файловая система может быть расположена на нескольких разделах или жестких дисках, поэтому на уровне ядра формируется общий пул (куча), а к нему уже подключаются разделы. Тут можно провести аналогию с группой томов LVM.
Команда zpool
Это основной инструмент управления разделами и функциональными возможностями ZFS, поэтому вам важно его освоить. Общий синтаксис команды достаточно прост, но у нее есть множество подкоманд, которые имеют свой синтаксис и параметры:
$ zpool команда параметры опции устройства
Как я уже сказал, параметры и опции для каждой команды свои, а в качестве устройства может указываться пул или физический раздел на жестком диске. Теперь рассмотрим основные команды и их предназначение, чтобы вы могли немного ориентироваться, а более детальные параметры разберем уже на примерах:
Это были все основные опции команды, которые мы будем использовать. Теперь рассмотрим примеры настройки zfs и управления разделами.
Как пользоваться ZFS
Настройка ZFS не очень сильно отличается от Btrfs, все базовые действия выполняются очень просто, вы сами в этом убедитесь.
Создание файловой системы
Сначала посмотрим есть ли уже созданные пулы ZFS. Для этого выполните такую команду:
Если вы устанавливаете эту файловую систему в первый раз, то здесь будет пустой список. Теперь создадим пул на основе существующего раздела, мы будем использовать раздел /dev/sda6
Хотя вы можете использовать не только раздел, а целый диск. Теперь смотрим еще раз список пулов:
Затем смотрим состояние нашего пула с помощью команды status, здесь выводится больше подробной информации. Если у вас есть несколько дисков, вы можете настроить RAID массив, чтобы данные хранились не на одном разделе, а синхронно копировались на несколько, это может в несколько раз увеличить производительность.
sudo zpool create pool0 zraid /dev/sda /dev/sdb /dev/sdc
Обратите внимание, что диски должны иметь одинаковый раздел. Если вам не нужен RAID, вы можете настроить обычное зеркалирование на второй диск. Это увеличивает надежность хранения данных:
sudo zpool create pool0 mirror sda sdb
Теперь данные будут писаться на оба диска. Такую же вещь можно проделать с разделами, но здесь нет смысла, поскольку если жесткий диск накроется, то данные вы потеряете, а прироста производительности не увидите. Вы можете использовать даже файлы, для создания файловых систем.
Вы можете добавить новый жесткий диск или раздел к пулу:
sudo zpool attach pool0 /dev/sdd
Или удалить устройство из пула:
sudo zpool detach pool0 /dev/sdd
Чтобы удалить пул используйте команду destroy:
sudo zpool destroy pool0
Для проверки раздела на ошибки используйте команду scrub:
sudo zpool scrub pool0
Статистику использования пула можно посмотреть с помощью команды iostat:
sudo zpool iostat pool0
Файловые системы ZFS
Теперь нужно создать файловые системы на только что созданном пуле. Создадим три файловые системы, data, files и media. Для этого используется команда zfs:
sudo zfs create pool0/data
$ sudo zfs create pool0/files
$ sudo zfs create pool0/media
Файловые системы готовы, дальше рассмотрим монтирование zfs.
Монтирование ZFS
Точка монтирования для пула и для каждой созданной в нем файловой системы создается в корневом каталоге. Например, в нашем случае точки монтирования выглядят так:
Или можно использовать такую команду:
Чтобы размонтировать файловую систему для одного из созданных разделов используйте команду zfs umount:
sudo zfs umount /pool0/data
Затем можно ее обратно примонтировать:
sudo zfs mount pool0/data
Параметры файловой системы
Кроме всего прочего, вы можете настроить различные параметры файловой системы ZFS, например, можно изменить точку монтирования или способ сжатия. Вы можете посмотреть все текущие параметры для файловой системы или пула с помощью команды:
sudo zfs get all pool0/files
Сначала включим сжатие:
sudo zfs set compression=gzip pool0/files
Затем отключим проверку контрольных сумм:
sudo zfs set checksum=off pool0/files
Смотрим точку монтирования:
sudo zfs get mountpoint pool0/files
Затем установим свою:
sudo zfs set mountpoint=/mnt pool0/files
Теперь раздел будет монтироваться в /mnt, настройки можно изменить для каждого из разделов.
Снимки состояния ZFS
Снапшоты zfs или снимки состояния могут использоваться восстановления данных. Благодаря особенностям файловой системы снимки можно создавать мгновенно. Для создания снимка просто наберите:
sudo zfs snapshot pool0/files pool0/files@shot1
Для восстановления используйте:
sudo zfs rollback pool0/files@shot1
Посмотреть список снимков вы можете командой:
А удалить ненужный снимок:
sudo zfs destory pool0/files@shot1
Выводы
В этой статье мы рассмотрели как работает файловая система zfs, как выполняется настройка zfs и как ее использовать. Это очень перспективная файловая система, с огромным набором функций, которая способна сравняться, а в некоторых областях и обойти Btrfs. Надеюсь, эта информация была полезной для вас, если у вас остались вопросы, спрашивайте в комментариях!
Что такое ZFS? И почему люди от неё без ума?
Сейчас мы обсудим ZFS, продвинутую файловою систему. Мы обсудим как она появилась, что из себя представляет, и почему так популярна в технических кругах и предприятиях.
Хотя я из США, я предпочитаю произносить ZedFS вместо ZeeFS, потому что это звучит круче. Вы же можете выбрать вариант произношения для себя.
Заметка: В этой статье вы увидите, что ZFS повторяется очень много раз. Когда я буду говорить об особенностях и установке, я имею в виду OpenZFS. Пути ZFS (разработанная Oracle) и OpenZFS разошлись, с того момента как Oracle закрыла проект OpenSolaris. (Подробнее дальше в статье.)
История ZFS
Файловая система Z (ZFS) была создана Меттью Ареном и Джефом Бонвиком в 2001. ZFS была разработана, для того чтобы стать следующим поколением файловых систем OpenSolaris от Sun Microsystems. В 2008 ZFS была портирована на FreeBSD. В этом же году началось портирование ZFS на Linux. Однако, с того момента как ZFS начала выпускаться под лицензией CDDL, которая несовместима с GNU GPL, она не может быть добавлена к ядру Linux. Что бы обойти это ограничение, большинство дистрибутивов предлагают методы установки ZFS.
В скоре после того, как Oracle купила Sun Microsystems, код OpenSolaris стал закрыт. Вся последующая разработка ZFS стала закрытой тоже. Большое количество разработчиков ZFS разочаровалось из-за таких изменений. Две трети важных разработчиков ZFS, включая Аренса и Бонвика, покинули Oracle вследствие этого решения. Они присоединились к другим компаниям и создали проект OpenZFS в сентябре 2013. Проект возглавил открытую разработку ZFS.
Вернемся же к проблеме с лицензиями упомянутой выше. С того момента как OpenZFS отделился от Oracle, кому-то может быть интересно, почему они не изменили лицензию совместимую с GPL, так, чтобы включить файловую систему в ядро Linux. Согласно сайту OpenZFS, изменение лицензии влечёт за собой контакт разработчиков которые вносили изменения в релиз OpenZFS (включая тех, кто начал этот проект и код ZFS до OpenSolaris) и получить их разрешение. Это уже почти невозможно (возможно кто-то из них уже умер или их не так легко найти), они решили оставить все как есть.
Что такое ZFS? Чем она особенна?
Как я сказал ранее, ZFS это продвинутая файловая система. Как таковая, она имеет некоторые интересные особенности. Такие, как:
Объединённое хранилище
В отличие от других файловых систем, ZFS совмещает возможности файловой системы и менеджера дисков. Это означает что ZFS может создать файловую систему охватив все диски. Но не только это, можно также добавить хранилище в систему дисков. ZFS займется разделением и форматированием дисков.
Copy-on-write
Copy-on-write это другая интересная особенность. Но большинстве файловых систем, если информация перезаписана, она утрачена навсегда. В ZFS новая информация записывается в отдельный блок. Как только запись завершена, метаданные файловой системы обновляются к точке новой информации. Это гарантирует что если файловая система сломается (или случится что-либо подобное) во время записи, старая информация будет фиксирована. Это означает что системе не нужно запускать fsck после сбоя.
Снапшоты
Copy-on-write приводит к другой интересной вещи в ZFS: снапшоты. ZFS использует снимки, для того чтобы следить за изменениями в файловой системе. Снимок хранит оригинальную версию файловой системы и текущую, в которой все изменения с момента создания снимка. Никакого дополнительного места не используется. Как только новая информация записывается в текущую файловую систему, новые блоки распределяются для её хранения. Если же файл был удален, упоминание о нём из снимка исчезает. Снимки разработаны для слежки за изменениями, но не являются дополнением и не создают файлов.
Снимки могут быть смонтированы в формате read-only для восстановления старой версии файла. Также можно откатить систему к предыдущему снимку. Все изменения сделанные после снимка будут утрачены.
Проверка цельности информации и автоматическая починка
Всякий раз когда новая информация записывается в ZFS, создается чек-сумма (контрольная сумма) для этой информации. Когда информация прочитана, чек-сумма подтверждается. Если чек-суммы не совпадают, ZFS замечает ошибку и попытается её исправить.
RAID-Z
ZFS может поднять RAID без вспомогательного софта. Не удивительно, что ZFS предоставляет свою реализацию RAID: RAID-Z. RAID-Z это по сути вариация RAID-5. Тем не менее RAID-Z разработан так, что бы превзойти RAID-5 в плане ошибки, «все данные и информация о контроле по чётности становится несовместимой после непредвиденной перезагрузки.» Чтобы использовать базовый уровень (RAID-Z1) вам необходимо минимум два диска для хранения и один для контроля по чётности. RAID-Z2 нужно как минимум два диска для хранения и два для контроля по чётности. RAID-Z3 требует два диска для хранения и три для контроля по чётности. Как только диски добавлены к группам RAID-Z они должны быть кратны двум.
Огромные возможности хранилища
Когда ZFS была создана, она была спроектирована, чтобы стать лучшей в своем роде. Во время когда большинство файловых систем были 64-битными, создатели ZFS решили сделать её 128-битной, для будущего подтверждения этого. Это означает, что ZFS предоставляет емкость 16 миллионов миллионов 32 или 64-битных систем. К тому же, Джеф Бонвик (один из создателей) сказал что энергоснабжение полностью заполненного 128-битного пула памяти будет буквально требовать больше энергии чем для вскипания океанов.
Как установить ZFS
Если вы хотите использовать ZFS из коробки, то необходимо установить либо FreeBSD, либо ОС, которая использует illumos-ядро. Illumos это форк ядра OpenSolaris.
На самом деле, поддержка ZFS и для ZFS это главный аспект, почему некоторые опытные пользователи Linux останавливают свой выбор на BSD.
Если вы хотите использовать ZFS на Linux, вы сможете её использовать как файловую систему только для хранения. Насколько мне известно, никакой из дистрибутивов не даёт возможности установить ZFS, так, чтобы она работала сразу. Если вы заинтересованы и хотите попробовать, есть проект ZFS on Linux, который предоставляет несколько туториалов.
Напоследок
В этой статье я рассказал о плюсах ZFS. И сейчас о маленькой проблеме. Использование RAID-Z может дорого обойтись из-за количества дисков нужных для него.
А вы когда-то использовали ZFS? И как она вам? Расскажите об этом в комментариях.
ZFS: архитектура, особенности и отличия от других файловых систем
Я, Георгий Меликов, являюсь контрибьютором проектов OpenZFS и ZFS on Linux. Также я занимаюсь разработкой IaaS в команде облачной платформы Mail.ru Cloud Solutions. Хотя в продакшене нашего подразделения мы и не используем ZFS, но хозяева подкаста SDCast пригласили меня рассказать именно о нём. Из выпуска и родилась эта статья, а вот тут можно послушать аудиоверсию.
Итак, сегодня я рассказываю про ZFS. Как устроена файловая система ZFS, из каких компонентов она состоит и как работает, а также про новые фичи, которые появились или скоро появятся в последних релизах.
ZFS и ее отличия от других решений на примере Linux
ZFS — это симбиоз файловой системы и менеджера томов, которая предоставляет инструменты для простого управления дисковым массивом.
Любая файловая система — это абстракция для удобного хранения данных. Каждая файловая система разрабатывалась под определенные требования: сколько у нее будет дисков, какая система хранения под капотом и так далее. Например, семейство EXT — очень простая система, вдохновлённая UFS, XFS — система с упором на параллельный доступ, а ZFS стремится быть системой, включающей в себя всё нужное для создания больших локальных хранилищ, в частности это отражается и на удобстве эксплуатации.
В Linux как де-факто стандарт используется менеджер логических томов (Logical Volume Manager, LVM), который также предлагает некоторые абстракции над нижележащим блочным устройством — можно создавать абстракции в виде Physical Volume, Logical Volume и так далее. По сути, можно делать то же самое, что с ZFS, но другими методами, добавив ещё кучу слоёв к LVM.
Плюсы ZFS в том, что он знает, что и где лежит, группирует это и дает некоторые другие фишки, в частности безопасное хранение данных — эта файловая система сделана с упором на целостность. Сейчас это (на мой скромный взгляд) лучшее из опенсорсных кроссплатформенных предложений на рынке. Конечно, можно собрать хранилище и без ZFS, но это будет хуже по производительности, т. к. для достижения хотя бы отдалённого паритета по функциональности придётся использовать много слоёв (LVM, mdadm, dm-integrity, что-то для дедупликации и компрессии). К сожалению, каждый слой даёт немалое пенальти.
Основы ZFS
ZFS — это copy-on-write файловая система, она никогда не перезаписывает данные. Мы всегда оперируем новым блоком, для обеспечения консистентности данных не нужен журнал, как в большинстве других файловых систем.
У баз данных типа MySQL и PostgreSQL есть так называемый WAL-лог. По умолчанию все данные пишутся в виде лога, потом записываются в блок данных на диске, получается двойная запись. При этом надо ждать, когда файловая система подтвердит, что данные на диске.
Copy-on-write дает следующее преимущество: старые данные не меняются, можно не вести журнал и восстановить данные, записанные ранее. Мы не боимся повреждения данных, так как их нельзя повредить, новый вариант блока запишется в новое место, не затирая старый.
Сам copy-on-write процесс не гарантирует консистентность данных, но если рассматривать ZFS, то в основе его работы лежит дерево Меркла, или Хэш-дерево. У ZFS всегда консистентное состояние за счет того, что он использует атомарные транзакции. Есть дерево блоков, для каждого из них с самого нижнего блока подсчитывается хеш-сумма и так доходит до самого верхнего блока. Хеш-сумма верхнего блока (uberblock) позволяет валидировать состояние всей файловой системы на момент транзакции.
Визуализация дерева блоков. Источник: https://ritlug.com/talks/slides/2019-spring-w08-zfs.pdf
Однако из-за того, что copy-on-write система никогда не пишет в одно и то же место появляется проблема фрагментации данных. Также надо решать вопрос чтения и его эффективности. С SSD эта проблема по большей части решается, но она ощутима при работе на жестких дисках.
ZFS, как и любой copy-on-write системе, нужно иметь на дисках запас свободного места, чтобы было куда записывать данные, которые всегда пишутся в новое место. К этому добавляется проблема порядка записи, следующие блоки одного файла будут записаны в другое место на диске, то есть в наличии непростая задача по эффективному аллоцированию данных. Однако и в классических файловых системах фрагментации можно избежать, только переалоцировав последовательно отрезок и работая только с ним. По факту мы так возвращаемся к прибиванию сущностей программы к конкретному диску, а это менее удобно (а любая ФС, как мы говорили раньше, стремится облегчить жизнь разработчику).
Преимущества ZFS
Давайте же поговорим о плюсах, зачем вообще стоит выбирать ZFS:
Целостность и консистентность — ZFS сделан для максимальной надежности. По умолчанию на все данные подсчитываются контрольные суммы, а для метаданных записывается минимум по две копии в разных местах диска. Есть такой миф, что для ZFS нужна ЕСС-память, на самом деле — она нужна для любой файловой системы для исключения записи некорректных данных, просто в ZFS об этом честно говорят.
Сжатие на лету. К примеру, используя алгоритм сжатия LZ4 система без проблем выдает 800 Мбайт в секунду на одно ядро на запись и до 4.5 Гбайт в секунду — на чтение. Соответственно, если мы говорим про многопоточную нагрузку, то при наличии свободного процессорного времени его можно эффективно утилизировать. В таком случае можно сэкономить не только место на диске, но и IOPS жесткого диска взамен ресурсов процессора за счет меньшего количества операций к диску. Есть интересные кейсы, к примеру использование MySQL, когда при этом под нами не очень дорогой SSD или простой HDD — тогда, включив LZ4, можно хорошо выиграть по многопоточной производительности, немного увеличив latency каждого потока.
Атомарность. В ZFS все атомарно за счет того, что в основе лежит дерево Меркла. Если наша файловая система всегда атомарна, то можно отказаться от WAL-лога в приложениях, потому что целостность блоков гарантируется транзакционностью файловой системы. Тут есть нюансы: нужно уметь говорить с файловой системой на ее языке, манипулировать транзакциями. Отдельный вопрос, что эти логи некоторые базы данных используют для репликации. Но в целом — можно так экономить на ресурсах.
Этот нюанс может быть и минусом: работа через дерево Меркла не бесплатна — чтобы приобрести консистентное состояние, нужно провести все манипуляции по подсчету хеш-сумм. Это дорого в первую очередь относительно процессора. Со стороны доступа к данным — что-то требует больше ресурсов по сравнению с классическими файловыми системами, а что-то меньше, например, мы экономим на том же журнале.
«Бесплатные» снапшоты. Создание снапшота в ZFS по времени константно и не накладывает дополнительных расходов на работу с этими данными. Снапшоты удобно передавать, в том числе инкрементально, Те, кто пользуется бэкапами через Rsync или другие инструменты, сталкиваются с такой проблемой — нужно проверять, какая часть данных изменилась. А здесь можно отправить снапшот инкрементально, целостность будет проверена и подтверждена на другой стороне.
Снапшот, по сути, тег, то есть ссылка на некую версию, всех данных всех блоков, из которых она состоит, начиная от корневого блока. Это специально помеченный самый верхний корневой блок, с которого начинается дерево. За этот счёт получение инкрементального среза изменённых данных равнозначно получению блоков из транзакции, на которую и указывает снапшот, то есть не требуется проверка какие блоки изменились, у нас уже есть ссылка только на модифицированные. Как пример использования снапшотов можно привести быстрое развертывание разных версий для тестирования дампов баз данных, того же PostgreSQL.
Архитектура ZFS
Посмотрим, как устроена ZFS изнутри. Есть набор дисков, над ним появляется абстракция в виде виртуального устройства (device). В терминологии ZFS — это Vdev, сокращение от virtual device. Есть разные реализации Vdev: Mirror (зеркало), который дублирует как есть информацию на два диска, RAID-Z, похожий по логике работы на классические RAID 5, 6 или 7. Также на подходе новый dRAID, о котором поговорим позже.
Составные части пула. Источник: https://forums.lawrencesystems.com/t/freenas-zfs-pools-raidz-raidz2-raidz3-capacity-integrity-and-performance/3569
Как конкретно мы храним и резервируем данные — с упором на производительность или на объём полезного пространства — это ответственность Vdev. Из набора Vdev’ов мы составляем общий пул. Если перевернуть на классическое понимание того же mdadm, чтобы собрать RAID 10, то есть набор мирроров, нужно сделать несколько Vdev Mirror и объединить их в один пул. Каждый Vdev — это, по сути, stripe, то есть отдельная виртуальная единица хранения. В рамках пула каждый уникальный блок данных будет храниться только на одном Vdev.
Логически элементы ZFS делятся на 3 подсистемы:
SPA (Storage Pool Allocator) — отвечает непосредственно за нарезку на диски, хранение данных на диске. Этот элемент отвечает за то, куда кладется конкретный блок данных, но с абстракцией от диска. Когда мы к нему обращаемся, то видим единое пространство, вне зависимости от набора конкретных Vdev’ов.
DMU (Data Management Unit) — на этом уровне ZFS представляется обычным объектным хранилищем. Есть реализации, когда ее так и используют с некоторыми модификациями. К примеру, распределённая файловая система Lustre реализует свой слой поверх DMU ZFS.
Следующий уровень DSL (Data and Snapshot Layer) пользуется этим объектным хранилищем. Этот компонент занимается непосредственно файловыми системами, снапшотами, то есть логикой, которая реализует POSIX-совместимую файловую систему (в него входит слой ZPL — ZFS POSIX layer).
Сравнение интерфейсов классических ФС и ZFS. Источник: https://slideplayer.com/slide/11350106/
Также в ZFS есть другие подсистемы, которые нужны для эффективной совместной работы всех этих слоёв.
ARC (Adaptive Replacement Cache). Его разработали, чтобы решить проблему с чтением. ARC примечателен тем, что делает упор не только на трекинг тех объектов, что были использованы последними (LRU-cache), но и на трекинг частоиспользуемых объектов, которые он и кэширует (MFU-cache).
У классического page cache Linux’а есть проблема вымывания: если прочесть файл, размер которого превышает объем оперативной памяти, то старые данные из кэша вымоются, так как по умолчанию файл будет загружен в page cache.
ARC — это умная замена page cache. Когда создавался ZFS, часто использовали жесткие диски, а у них маленькие IOPS. Чтение copy-on-write данных — по умолчанию случайная операция, чтобы её ускорить, используют разные ухищрения, например, аккумулируют данные, записывают большим блоком и так далее, но эти оптимизации не всегда срабатывают. На этот случай нужно умное кеширование. Нормально, если при штатной работе 99% запросов чтения попадает в кэш, если меньше, значит, что-то не так, стоит добавить оперативной памяти.
Если ARC не всегда полностью помещается в память, есть варианты вынести кэш на более быстрый отдельный SSD — это называется L2ARC (Layer 2 ARC).
ZIL (ZFS intent log). Мы пишем данные в ZFS транзакциями, это набор дорогостоящих операций: подсчет хэш-сумм, построение дерева, запись метаданных, которые пишутся для безопасности несколько раз в разные места дисков. Поэтому мы стараемся набить каждую транзакцию максимальным количеством данных. Тут (сюрприз) появляется определенного вида журнал, без которого не обойтись, если нужна быстрая синхронная запись и критична задержка. Только здесь он вынесен как сущность, что позволяет использовать разные решения для персистентного хранения кусочка синхронной записи. Этот журнал обычно очень маленький, его записью и занимается ZIL (ZFS intent log).
ARC и ZIL — хотя это и необязательные с технической стороны компоненты, но они нужны для обеспечения высокой производительности хранилища, без них система будет работать медленнее. ZFS в продакшене чаще применяют для крупных инсталляций хранилища данных. Архитектура подразумевает эффективную утилизацию большого количества HDD, SSD, RAM, CPU.
Паттерны использования ZFS и типовые конфигурации
ZFS — это локальное хранилище, когда мы говорим про него, то по умолчанию подразумеваем хранилище в рамках одного хоста. У него огромный спектр применения:
ZFS подходит для домашнего использования, где не самое дорогое оборудование и не самые быстрые диски, можно использовать процессор на дополнительные вычисления (т.к. он обычно простаивает). Плюсы ZFS в том, что это удобный конструктор. Необязательно задействовать отдельные SSD, можно создать пул даже прямо на файлике, что удобно для тестов.
Другой классический вариант — NFS-хранилище, там больше дисков, начинаем задумываться о синхронной записи, кэше и тут можно подставить дополнительные блоки в виде SSD.
Также ZFS можно использовать в качестве крупного хранилища, когда в рамках одного пула более ста дисков, все это должно работать и восстанавливаться, если диски вылетели, а это проблема любого большого хранилища.
Блоки типа ARC, ZIL и так далее — это не диски, которые мы можем использовать, это понятия виртуальные, они всегда есть в ZFS. У нас есть возможность вынести их на более быстрые отдельные носители.
ZIL можно вынести на так называемый Slog, которому не нужно быть большим, так как синхронная запись обычно идет мелким блоком и быстро сбрасывается на основное хранилище. То есть важно как можно быстрее записать конкретный блок данных и отрапортовать клиенту об успешной записи, а не записать как можно больше данных (привет, СУБД!). Slog нужен на чтение только при сбое питания.
ARC можно дополнить одним или более SSD и выгружать на него определенный вид данных, например, кэшировать только метаданные или данные, которые последовательно или случайно прочитались с основного хранилища.
Есть много вариаций настройки ZFS. Можно оптимизировать любой профиль нагрузки, начиная от размера блока, которым мы оперируем. Например, когда мы хотим оптимизировать copy-on-write, то можем писать бо́льшим блоком, чем в классических файловых системах, для ZFS по умолчанию принят объем в 128 КБайт на блок.
Плюсы и минусы ZFS по сравнению с аппаратными решениями
У аппаратного решения есть плюсы: мы переносим определенную вычислительную нагрузку на его процессор, надеясь, что он с ней справится. Также можно использовать аппаратный RAID-контроллер с энергонезависимой памятью или кэшем, переложить ответственность за проблему с синхронной записью на него.
С ZFS мы используем процессор, нужно решать вопрос синхронной записи отдельно, однако, мы не завязаны на железо, можем работать где угодно. ZFS не надо указывать порядок дисков, достаточно указывать директорию, в которой они находятся, и система сама из них соберет пул.
Минусы аппаратного решения в том, что в случае выхода из строя нужно искать полный аналог. Аппаратный RAID ничего не знает про данные, только про блоки, следовательно, не может как-то оптимизироваться под конкретную ситуацию.
И есть еще момент, который редко упоминается: в случае аппаратных и других софтверных решений — мы настраиваем их единожды, то есть у нас есть общие настройки: один размер блока, такие-то страйпы и так далее. После настройки есть том, с которым можно эффективно работать только с заданными настройками. Отсюда еще один плюс ZFS — возможность настроить один пул под разные нагрузки через создание отдельных датасетов с различными настройками.
Имея один пул, можно настраивать под конкретную операцию хоть каждый датасет. Мы максимально подстраиваемся под приложения. То есть ZFS — очень гибкое софтверное решение.
В случае ZFS все метаданные об ФС пишутся условно в заголовок диска. Если сломался сервер, можно просто вытащить диски и перенести на другой сервер. Если там совместимая версия ZFS, то система их просканирует и снова соберет тот же самый пул.
Любое софтверное решение позволяет так делать, так как рядом с данными хранится информация о строении этого массива. Но ZFS хранит эту информацию на каждом диске — даже не надо указывать порядок, достаточно указать, что где-то есть пул, его надо импортировать. Система либо соберет его, либо покажет, что пошло не так. Также состояние пула можно откатить на несколько транзакций назад, если в них была ошибка.
Особенности работы ZFS
Фрагментация данных
В copy-on-write системе постоянно появляются новые блоки, а старые не всегда пригодны к удалению. Часто возникают ситуации, когда старый блок не полностью записан, какие-то блоки не нужны, появились «дырки» (пустые пространства небольшого размера) и так далее.
В ZFS пространство разрезано на так называемые metaslabs, которые ведут трекинг того, какие сектора свободны, а какие заняты. Это происходит на уровне SPA — слоя, который работает с дисками.
В рамках этих пространств мы при каждом аллоцировании пытаемся найти наиболее подходящее по определенному алгоритму. Когда в пуле много места, то выбираем пространство с самым большим объемом свободного места, куда будет лучше записать данные с точки зрения дальнейшей фрагментации. Например, если у нас 1 Мбайт данных, мы ищем свободный блок в 1 Мбайт и можем туда цельно записать данные.
Когда места становится мало, включается другой режим аллокации — он дороже с точки зрения производительности и приводит к росту фрагментации, в этом режиме просто ищется первое попавшееся подходящее место. В худшем случае, когда под блок уже нет безразрывного отрезка, он будет разбит и записан кусками (что тоже не идёт на пользу производительности).
По умолчанию на каждый Vdev создается
200 meta-slabs. Если что-то изменилось, то надо метаданные по этим 200 meta-slabs записывать каждый раз для каждого Vdev. Сейчас это пишется постоянно на каждый Vdev, но уже перед релизом патч, который записывает информацию об изменениях в meta-slabs в виде лога на один из Vdev, а потом регулярно применяет этот лог. Это чем-то похоже на WAL-лог базы данных. Соответственно, уменьшается нагрузка на запись на диск информации о metaslabs.
Конечно, при заполнении всего места возникает проблема, но на эту ситуацию любая copy-on-write файловая система (да и традиционная тоже) закладывает какой-то процент зарезервированного места для работы, без этого с динамической аллокацией никак.
Запись данных
По умолчанию чтение данных в ZFS практически всегда является случайным, но так как мы пишем каждый раз в новое место, то можем превращать случайную запись в практически последовательную. Если нужна система хранения под запись и редкое чтение, то любая copy-on-write система, в том числе ZFS, будет отличным решением. Данные пишутся группами транзакций (txg, сокращённое от transaction groups), можно агрегировать информацию в рамках этой группы.
Тут есть особенность: существует Write Throttling — мы можем использовать неограниченное количество оперативной памяти для подготовки txg-группы и за счет этого переживать резкие скачки записи, буферизируя все в оперативную память. Естественно, речь про асинхронную запись, когда мы можем себе это позволить. Потом можно последовательно и очень эффективно сложить данные на диск.
Если синхронная запись и ее целостность не важна, например, у вас не большая и дорогостоящая PostgreSQL, а сервер на одного пользователя, то синхронную запись можно отключить одной настройкой, она станет равняться асинхронной ( zfs set sync=disabled ).
Зависимость скорости работы ZFS от количества дисков
Один блок данных всегда приходит на один Vdev. Если мы делим файл на небольшие блоки по 128 KB каждый, то такой блок будет на одном Vdev. Далее мы резервируем данные с помощью Mirror или как-то еще. Набив пул сотней Vdev, мы в один поток будем писать только на один из них.
Если дать многопоточную нагрузку, например в 1 000 клиентов, то они могут использовать сразу много Vdev параллельно, нагрузка распределится. При добавлении дисков мы, конечно, не получим полностью линейного роста, но параллельная нагрузка эффективно размажется по Vdev’ам.
Обработка запросов на запись
ZFS учитывает, какой Vdev был перегружен, где нагрузка меньше, где какая была задержка доступа к носителям. Если какой-то диск начинает умирать, у него высокая задержка, то система в итоге отреагирует на это, например выводом его из использования. Если мы используем Mirror, то ZFS пытается распределять нагрузку и параллельно считывать с обоих Vdev разные блоки.
Как появились OpenZFS и ZFS on Linux и проблемы с версионированием
ZFS изначально создана в Sun Microsystems для проприетарной операционной системы Solaris. Она появилась в качестве замены UFS, которая должна была покрыть любые надобности от файловой системы на долгое время (характерно само название ZFS — Zettabyte File System, намёк на недостижимые объёмы). После продукт стал распространяться с открытым кодом под лицензией CDDL и названием OpenSolaris. Затем Oracle купили Sun Microsystems, и проект перевели обратно в разряд проприетарных. До этого FreeBSD успел притянуть к себе код, были наработки у Apple, они даже встроили реализацию в штатную поставку, но отказались от нее, в конечном итоге внедрив свой аналог AFS. Тогда же появился форк, который превратился в OpenZFS. Сначала желающие работали на OpenSolaris, а потом создали OpenZFS, под которым собрали все усилия в рамках Illumos (форк OpenSolaris).
Кстати, сейчас ZFS — одна из наиболее кроссплатформенных файловых систем, доступная почти на любой операционной системе (даже ведётся портирование под Windows).
У ZFS on Linux другая история. В Ливерморской национальной лаборатории США в качестве распределённой файловой системы для суперкомпьютеров использовали Lustre FS. Ее особенность в том, что на каждой ноде под ней используется еще одна локальная файловая система Ldiskfs — это патченный Ext3, наработки которой послужили основой для Ext4. У Ldiskfs был ряд недостатков, и ZFS должен был заменить эту файловую систему, так и появился проект ZFS on Linux.
В OpenZFS возникла проблема версионирования. Есть ZFS от Oracle и есть OpenZFS, последний не может повторять проприетарную версию, как и банально получать её исходный код. Изначально и у пула и у датасета в ZFS была версия, при обновлении Solaris можно было просто поднимать соответствующую версию. После обновления пул может не импортироваться в старом коде вообще или импортироваться в режиме только для чтения.
На тот момент в проекте OpenZFS уже было много реализаций: FreeBSD, Linux, Solaris, Macos, нужно было связать все наработки. Для этого придумали feature flags, т. н. функциональные флаги. Например, взводишь флажок, что пул поддерживает LZ4 сжатие и в дальнейшем смотришь на него из кода — поддерживается/не поддерживается фича (т. е. можно ли импортировать пул).
У каждого флага есть подпись — можно ли импортировать пул с ним в режиме только на чтение, так как многие вещи важны только при изменениях данных на носителях. Каждая реализация стала обрастать своими feature flags, и платформы переносили их между друг другом через backports.
ZFS не включен в ядро Linux, а другие файловые системы в Linux идут из коробки, т.е. есть в ядре. Вопрос включения в ядро — проблема лицензии, это вопрос сложный. Однако есть отдельный модуль ядра, его можно без проблем обновлять вне зависимости от версии ядра.
В Linux для этого есть два механизма:
DKMS — динамическая сборка из исходников. К новому ядру автоматически ставим headers, которые нужны для сборки модуля, он приезжает и автоматически собирается с нужными параметрами. В худшем случае, если не проверена совместимость, DKMS ничего не соберет и отрапортует об этом, но риск такого очень мал, к тому же сопровождающие репозитории пакетов конкретных дистрибутивов могут проверять совместимость пакетов с доступными версиями ядра.
KMOD — модуль ядра приезжает из репозитория в бинарном виде, конкретная сборка совместима с определённой версией ABI ядра. Отсутствует риск проблем при сборке модуля, характерные для DKMS, но сопровождающие пакета с модулем должны оперативно предоставлять новые версии при появлении свежих ядер.
Разница в том, что приедет из пакета: исходный код как в DKMS или сразу бинарный файл как в KMOD.
Что нового в последних релизах
В версии 0.8 появилось нативное шифрование. Есть американская компания Datto, которая занимается бэкапами данных и базируется на ZFS. Они предложили реализацию нативного шифрования.
Ее плюс в том, что шифруются только данные и то, что связано с ними, а информация о датасетах и большая часть метаданных не шифруются. То есть информация на уровне DSL, о директориях и так далее, шифруется, а то, что ниже — DMU и SPA, нет. Что это дает? Можно зашифровать данные на стороне клиента и, не отдавая ключ, отправить их сначала полностью, потом регулярно обновлять инкрементально, принять на стороне сервера также инкрементально без расшифровки и проверить целостность.
Если шифрование идет на низком уровне (к примеру, LUKS) и у нас большие объемы данных, то теряется информация о том, что там есть, нужно передавать все целиком, так как изменение одного байта меняет весь блок. Чтобы проверить целостность данных в этом случае, нужно их расшифровать — это дорого и долго.
Еще одно обновление — это Special Allocation Class. Предположим, что есть большое количество медленных жестких дисков плюс используется реализация Vdev RAIDZ, особенность которого в том, что он не заточен на большие IOPS. Так обеспечивается целостность, он всегда атомарен (не страшна проблема потери массива при т. н. raid write hole), но у этого есть минусы в части производительности. Читать метаданные и мелкие блоки с RAIDZ дорого.
Special Allocation Class — это специальный Vdev, куда пишутся метаданные или блоки данных меньше 4 килобайт (запись данных конфигурируется). Получается, что под большие блоки данных можно использовать медленное, но дешевое HDD-хранилище, а рядом поставить SSD-диски, хранящие его по блоки метаданных и блоки данных небольших размеров.
Планы по развитию ZFS
ZFS — файловая система, которая может работать с большинством операционных систем. Скоро появится полнофункциональная версия даже под MS Windows.
В настоящий момент в планах на развитие идет упор на производительность, к примеру на оптимизацию для NVMe. Они дорогие, хочется выжать из них максимум. ARC в данном случае не даёт сильного выигрыша, так как это дополнительные операции по копированию данных в ОЗУ. Сейчас, если поставить 5 — 10 NVMe, мы быстро упремся в производительность ОЗУ и ЦПУ. Специально для этого случая ведутся работы по поддержке direct io с целью исключения лишних операций в ARC.
Другие направления — больше удобства для конечных пользователей-частных лиц. При использовании ZFS дома есть проблема в том, что объем наращивается либо установкой нового Vdev, либо заменой всех дисков в Vdev на бо́льшие (ZFS видит, что диски увеличились и может использовать дополнительное пространство). То есть собрав один RAIDZ, мы не можем добавить к нему на ходу еще один диск. Уже в альфе патч, который позволяет это делать.
Еще одна интересная наработка, которая готовится к релизу, это новый тип Vdev — dRAID. В больших инсталляциях, где диски измеряются сотнями, а пространство — петабайтами, при вылете одного диска сложно быстро восстановить избыточность данных.
Проблема в том, что жесткие диски, наращивая объем в 20 ТБ и более, не сильно наращивают производительность с точки зрения пропускной способности. У любого диска есть количество ошибок на каждый терабайт чтения, официально заявленное производителем (URE — unrecoverable read error rate). И любой RAID 5 и более с дисками больше 3 ТБ практически гарантированно развалится при пересборке, когда один диск вылетел и мы читаем с оставшихся. Риск ошибки чтения хотя бы одного не того байта с этих 3 ТБ каждого диска просто огромен (для «потребительских» HDD стандартом является одна ошибка чтения на каждые 10 14 бит, т.е. на каждые
11 ТиБ). Когда мы пересобираем RAIDZ, а это тот же RAID 5, 6 и так далее, есть та же проблема.
Конечно, можно увеличить количество дисков, которое мы можем потерять: поставить RAIDZ 2, RAIDZ 3 — сколько копий будет хранится, но мы не решаем вопрос производительности восстановления. Новый диск, который мы меняем, по-прежнему является узким горлышком. Эти 15 — 20 ТБ будут восстанавливаться в лучшем случае со скоростью 200 МБ/сек (а в реалистичном — около 100 МБ/сек, а то и меньше). Несколько суток на восстановление одного диска — это очень долго.
Пример расположения блоков на дисках, RAIDZ. Источник: https://itnext.io/backup-storage-for-thousands-of-virtual-machines-using-free-tools-b3909004bef2
dRAID решает проблему одновременного восстановления данных на большом количестве дисков. Вместо того чтобы работать в рамках «один диск — одна единица», мы как бы нарезаем каждый диск на мелкие сущности по количеству дисков. Так, если в dRAID 50 дисков, то каждый из них будет разделен на
50 областей. Некоторые из этих областей будут зарезервированы как свободные (spare) области, на которые можно восстановиться.
Пример расположения блоков на дисках, dRAID. Источник: https://itnext.io/backup-storage-for-thousands-of-virtual-machines-using-free-tools-b3909004bef2
По сути, это RAID 5 или RAIDZ, повернутый на 90 градусов. Мы в рамках физических дисков имеем виртуальные сущности. Если вылетает один диск, то на других зарезервировано свободное место, можно восстановить вылетевший диск со скоростью, которая зависит от количества элементов в массиве. То есть когда у нас десять блоков данных, можно восстанавливаться сразу на десять дисков. Такой подход увеличивает скорость восстановления.
Например, мы собрали dRAID, аналогичный RAIDZ2 с одним spare диском, который позволяет вылететь двум дискам, один вылетел, осталось девять. Пока мы не вставили новый диск, размазываем данные на пустое зарезервированное пространство других дисков в группе. И так восстанавливаем ситуацию: дисков по-прежнему девять, но вылететь может уже два, а не один, ведь блоки с вылетевшего диска уже разъехались по уцелевшим оставшимся. Таким образом снимается проблема узкого горлышка в виде производительности spare диска, технически он теперь размазан на другие диски массива.
По этой же причине теперь можно задействовать spare диск, в RAIDZ он бы стоял без дела, а в dRAID он является активным участником, т.к. размазан по всем дискам.
Послесловие
В связи с тем, что ZFS пережил существование в разных компаниях и ОС, идёт активная централизация кода и документаций в проекте OpenZFS. Приглашаю желающих к созданию единой документации по проекту, буду рад вашим PR!