Это учебная статья посвященная ZFS, из которой вы узнаете, что это такое, как использовать и как лучше настроить.
Для тех, кто не в курсе это локально-распределенная файловая система нового поколения, которая объединяет отдельные диски в пулы с возможностью создания RAID 0, 1, 10, 5. Это 128-битная файловая система с переменным размером блока (или кластера, как в терминологии fat) до 128 КБ. Таким образом каждый пул может адресовать огромный массив данных, в идеале (2^128)*128 КБ. В качестве полезных функций имеются встроенные механизмы квотирования, резервирования, контроля целостности
данных и некоторые др. Отличительные черты - быстродействие, надежность и удобство.
Сразу стоит сказать, что ZFS требовательна к ресурсам, минимально для комфортной работы ей нужно не менее 1 Гб оперативной памяти на любой архитектуре, но чем больше тем лучше. Поэтому 64-битные системы предпочтительней, у них нет жестких ограничений адресного пространства.
Журналируемость, транзакционность и контрольные суммы каждого блока в совокупности с основным приемуществом ZFS - методом записи "Copy On Write" обеспечивают уверенную отказоустойчивость при нештатных отключениях питания.
Сразу стоит сказать, что ZFS требовательна к ресурсам, минимально для комфортной работы ей нужно не менее 1 Гб оперативной памяти на любой архитектуре, но чем больше тем лучше. Поэтому 64-битные системы предпочтительней, у них нет жестких ограничений адресного пространства.
Журналируемость, транзакционность и контрольные суммы каждого блока в совокупности с основным приемуществом ZFS - методом записи "Copy On Write" обеспечивают уверенную отказоустойчивость при нештатных отключениях питания.
По технологии "CoW" новые данные не перезаписывают старые, а пишутся в свободное пространство и меняется только указатель. Правда у нее есть и обратная сторона медали, при чрезмерном заполнении пула происходит падение производительности. Поэтому рекомендуется активно пользоваться квотированием и не допускать заполнения больше, чем на 80%.
Учитывая, такие факторы, как распределение нагрузки между всеми дисками, входящими в пул, использование быстрого кэша и блока с переменным размером, можно ожидать от ZFS порядочного быстродействия.
И ради любопытства я провел дилетантское сравнение быстродействия с UFS (журнал + soft update) при операции записи. Я выполнял копирование с помощью dd if=/dev/zero of=file bs=1M count=2000. Как и следовало ожидать на моем слабом железе ZFS оказался медлительней.
Действительно, что ZFS может сделать на стареньком P4 3Гц, c 2ГБ памяти и одним жестким диском SATA. Хотя в процессе тестирования я и пытался настраивать разные параметры производительности ZFS (их мы рассмотрим чуть ниже), но лучшие результаты все равно оказались следующими ZFS - 26, 35 сек против UFS - 19,67 сек.
Поэтому отдаем себе отчет, что ZFS предназначена для достаточно мощного и современного оборудования с 64-битной архитектурой и с не менее, чем 4 Гб памяти. Но на старом железе конечно тоже будет работает, проверено лично. Но какой результат и зачем мучить свой старенький комп?
И так, приступим к препарированию.
B ZFS нет понятий томов и слайсов, как в традиционных ФС. Есть пул, внутри которого создаются файловые системы или как их еще называют датасеты. Размер файловых систем не фиксируется и может быть легко увеличен в результате присоединения нового диска к пулу. Поэтому здесь не может наступить критической ситуации полного заполнения диска.
Уменьшить размер ZFS пула уже не возможно! К примеру нельзя изъять диск, если это не зеркало. Это сразу приведет в выходу из строя всего пула! Заменить диск на другой, большего размера, всегда пожалуйста. Поэтому единственное, как можно уменьшить пул, это сохранить все данные на внешнем носителе, разрушить пул и создать новый.
Установка FreeBSD на ZFS
Нужно загрузиться с CD-диска или USB Memstick и начать установку как обычно. В FreeBSD 10 установка на ZFS уже полностью автоматизирована через bsdinstaller. На этапе разметки дисков достаточно выбрать пункт ZFS и система все сделает за вас. Ну а если хотите сделать это руками, то заходите в shell.
Здесь следует обратить внимание на следующие настройки: тип пула (stripe, mirror или raidz1, raidz2, raidz3), далее выбрать нужные диски для его создания. Пункт "forse 4k sectors" устанавливает выравнивание по 4К для каждого созданного раздела. Это важно, если у вас новые жесткие диски большого объема с размером сектора 4K, а не 512Б. Если нет, то укажите NO.
Давайте разберем, какие шаги выполняет установщик и заодно научимся работать с пулами. Описанные команды так же можно выполнять в ручном режиме, результат будет одинаковый.
Установщик автоматически создает три раздела GPT: один для загрузчика, раздел swap и основной раздел под пул.
Посмотрим для начала на структуру диска
# gpart show ada0Так удаляется старая таблица разделов
# gpart destroy ada0Создается новая таблица GPT
# gpart create -s GPT ada0Добавляются три раздела
# gpart add -s 512 -a 4k -t freebsd-boot -l boot0 ada0Здесь с помощью опции -a задается выравнивание разделов по 4Кб. Если у вас старые винты с физическим сектором 512б, то опцию пропускаем.
# gpart add -s 4g -a 4k -t freebsd-swap -l swap0 ada0
# gpart add -a 4k -t freebsd-zfs -l disk0 ada0
Устанавливается загрузчик
# gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada0Здесь используются два загрузчика, первый pmbr в области Protective MBR перед GPT, он передает управление второму gptzfsboot, он на первом секторе раздела freebsd-boot. А уже на третьем этапе вызывается loader.
Если вдруг вы решите не использовать ZFS, а вернетесь к UFS, то надо использовать другой загрузчик
# gpart bootcode -b /boot/pmbr -p /boot/gptboot -i 1 da0Для работы с ZFS загружаем модуль
# kldload zfs
При использовании дисков с сектором 4К важно задать размер блока ZFS. Поскольку диск для совместимости рапортует о секторе 512Б. И по умолчанию такой размер выбирается автоматически для блока при создании пула. Поэтому обязательно перед созданием пула нужно сделать следующее!
Поверх диска создается устройство gnop с размером сектора 4К
# gnop create –S 4096 /dev/gpt/disk0Создается пул
# zpool create -o altroot=/mnt -O canmount=off -m none zroot /dev/gpt/disk0.nopОтсоединяется пул
# zpool export zrootУдаляется устройство gnop
# gnop destroy /dev/gpt/disk0.nopСнова присоединяется пул
# zpool import zrootПроверяем, если ashift=12, то блок установлен правильно 2^12=4К. Если 9, то 2^9=512Б.
# zdb –C tank | grep ashift
Так же в FreeBSD 10 размер блока ZFS можно задать проще, с помощью
# sysctl vfs.zfs.min_auto_ashift=12
Сделать это нужно так же перед созданием пула и добавить в /etc/sysctl.conf, что бы не делать это вручную каждый раз в будущем.
Задаем алгоритм проверки контрольных сумм fletcher4, по умолчанию используется fletcher2.
# zfs set checksum=fletcher4 zrootЗапрещаем обновление времени доступа при каждом обращении к файлу.
# zfs set atime=off zrootСоздаем файловые системы
# zfs create -o mountpoint=none zroot/ROOT
# zfs create -o mountpoint=/ zroot/ROOT/default
# zfs create -o mountpoint=/tmp -o compression=lzjb -o setuid=off zroot/tmp
# chmod 1777 /mnt/tmp
# zfs create -o mountpoint=/usr zroot/usr zfs create zroot/usr/local
# zfs create -o mountpoint=/home -o setuid=off zroot/home
# zfs create -o compression=lzjb -o setuid=off zroot/usr/ports
# zfs create -o compression=off -o exec=off -o setuid=off zroot/usr/ports/distfiles
# zfs create -o compression=off -o exec=off -o setuid=off zroot/usr/ports/packages
# zfs create -o compression=lzjb -o exec=off -o setuid=off zroot/usr/src
# zfs create zroot/usr/obj
# zfs create -o mountpoint=/var zroot/var
# zfs create -o compression=lzjb -o exec=off -o setuid=off zroot/var/crash
# zfs create -o exec=off -o setuid=off zroot/var/db
# zfs create -o compression=lzjb -o exec=on -o setuid=off zroot/var/db/pkg
# zfs create -o exec=off -o setuid=off zroot/var/empty
# zfs create -o compression=lzjb -o exec=off -o setuid=off zroot/var/log
# zfs create -o compression=gzip -o exec=off -o setuid=off zroot/var/mail
# zfs create -o exec=off -o setuid=off zroot/var/run
# zfs create -o compression=lzjb -o exec=on -o setuid=off zroot/var/tmp
# chmod 1777 /mnt/var/tmpУказываем корневую ФС.
# zpool set bootfs=zroot/ROOT/default zrootДобавляем swap раздел в fstab
# vi /tmp/bsdinstall_etc/fstabПосле того как будут созданы все файловые системы, если выполняли в ручном режиме, то нужно выйти из shell, пишем exit. Далее установка продолжается, как обычно.
--# Device Mountpoint FStype Options Dump Pass#
/dev/gpt/swap0 none swap sw 0 0
Так же для ручного режима, перед перезагрузкой нужно еще раз зайти в shell и прописать автоматическое монтирование файловых систем.
# mount -t devfs devfs /devДля порядка зададим только чтение для /var/empty, поскольку она всегда должна быть пустой.
# echo 'zfs_enable="YES"' >> /etc/rc.conf
# echo 'zfs_load="YES"' >> /boot/loader.conf
# zfs set readonly=on zroot/var/empty
На этом установка завершена. Но, если вам хочется добиться лучшей производительности можно настроить еще некоторые параметры.
Способы оптимизации сильно зависят от назначения вашей системы и будут отличаться для БД, вэб-сервера и файлового сервера. В числе основных рекомендаций, можно найти такие, отключение обновления времени доступа при каждом обращении atime (мы уже это сделали), иметь как можно меньше снимков
Как вы знаете на i386 архитектуре ядро FreeBSD по умолчанию резервирует под все свои нужды всего 1Гб адресного пространства из 4 возможных, а остальное оставляет процессам. Но, если в ядре есть такой большой потребитель оперативной памяти, как ZFS, то его может и не хватить! Поэтому нужно увеличить это значение хотя бы до 2Гб, добавив в ядро опцию.
Способы оптимизации сильно зависят от назначения вашей системы и будут отличаться для БД, вэб-сервера и файлового сервера. В числе основных рекомендаций, можно найти такие, отключение обновления времени доступа при каждом обращении atime (мы уже это сделали), иметь как можно меньше снимков
состояний, использовать для ZIL и L2ARC отельные SSD диски. Использовать для файловых систем разные recordsize, соразмерно хранимым на них файлам. Если много мелких файлов, то recordsize лучше сделать 16Кб, а по умолчанию он 128Кб.# zfs create -o recordsize=8k tank/mysqlЕсть конечно и параметры, влияющие работу в целом. Рассмотрим их.
Как вы знаете на i386 архитектуре ядро FreeBSD по умолчанию резервирует под все свои нужды всего 1Гб адресного пространства из 4 возможных, а остальное оставляет процессам. Но, если в ядре есть такой большой потребитель оперативной памяти, как ZFS, то его может и не хватить! Поэтому нужно увеличить это значение хотя бы до 2Гб, добавив в ядро опцию.
options KVA_PAGES=512
(размер страницы — 4 Кб)*512=2Гб.
Но после пересборки ядра, во время загрузки, у меня начались "double fault panic". Как оказалось, проблема распространенная и многие пользователи ZFS на i386 архитектуре наблюдают переполнение стека ядра. Это начало происходить с того момента, как Clang сделали компилятором по умолчанию. Для того, что бы этого избежать нужно добавить еще одну опцию.
options KSTACK_PAGES=4Или задать в /etc/sysctl.conf параметр
kern.kstack_pages=4
На amd64 проблем с нехваткой адресного пространства нет. Там по умолчанию отвели ядру 512 Гб
виртуальных адресов, поэтому вышеописанное не потребуется.
Теперь, когда виртуальное адресное пространство ядра KVА (Kernel Virtual Address space) увеличено, надо этим поделиться с ZFS. В /boot/loader.conf добавляем параметры
vm.kmem_size="1G"
vm.kmem_size_max="1G"
kmem - это участок KVA, который используется для динамического выделения памяти malloc, и соответственно он будет использоватьcя ZFS.
ARC
Еще одним важным параметром влияющим на быстродействие ZFS является размер кэша адаптивной замены ARC (Adjustable Replacement Cache). Это очень быстрый кэш, расположенный в ОЗУ, построенный на двух алгоритмах MRU им MFU. Общий смысл его заключается в том, что бы обеспечить доступ к наиболее часто используемым данным прямо из памяти, а не с медленного диска. И поэтому, чем у вас больше оперативной паями, тем лучше для ZFS.
Еще одним важным параметром влияющим на быстродействие ZFS является размер кэша адаптивной замены ARC (Adjustable Replacement Cache). Это очень быстрый кэш, расположенный в ОЗУ, построенный на двух алгоритмах MRU им MFU. Общий смысл его заключается в том, что бы обеспечить доступ к наиболее часто используемым данным прямо из памяти, а не с медленного диска. И поэтому, чем у вас больше оперативной паями, тем лучше для ZFS.
По умолчанию ARC разрешается использовать всю свободную память по необходимости, кроме 1Гб зарезервированного ядром. Но если если у вас категорическая не хватка паями и ее обязательно надо оставить для других важных задач, то имеет смысл ограничивать размер кэша
vfs.zfs.arc_max="512M"
Если этого не сделать, то может произойти kernel panic по причине отсутствия свободного пространства. Поэтому проверяйте
# sysctl vm.kvm_freeТак же есть дешевый способ увеличить размер кэша при помощи обычной флешки. Изначально для этого задумано использовать SATA SSD-диски. Это называется вторым уровнем кэша L2ARC. В этой статье человек делится опытом подключения флешки 1G в качестве L2ARC.
# zpool add pool cache device
# zpool remove pool device
Но в виду того, что пропускная способность шины USB 2.0 ниже, чем у механических жестких дисков: 30 против 100 Мбайт/сек, то в качестве полноценного кэша старая флешка не годиться. Да и быстро выйдет из строя из-за постоянной перезаписи и отсутствия механизма выравнивания износа. Тем не менее сгодится для домашнего использования при малой нагрузке.
Ведь время поиска (seek time) y флешек гораздо меньше, чем у дисков и составляет от 1 до 3 мсек, против 12 мсек. Поэтому прирост скорости можно получить только на произвольном (не последовательном) чтении данных. И лучше
хранить на ней только метаданные, это позволит прослужить ей дольше.
# zfs set secondarycache=metadata pool
Что касается usb 3.0, то там полезная скорость возросла до 500 Мбайт/с и возможно такие флешки уже пригодны, но надо тестировать.
ZIL
На случай потери данных при сбоях и отключении питания некоторые приложения (например, NFS и БД) используют синхронную запись данных. Для этих целей у ZFS имеется целевой журнал ZIL (ZFS Intent log). Когда приложение хочет записать данные на диск, оно отправляет запрос ОС и ждет ответа. ОС сначала кэширует данные в ROM, затем сохраняет их в ZIL и только после этого возвращает управление приложению. При этом ZIL обязательно должен находиться в энергонезависимой памяти и по умолчанию располагается на диске внутри пула. Вот это и является узким местом при увеличении производительности. Но ZFS позволяет использовать в качестве log-устройства отдельные диски или даже несколько дисков одновременно. Поэтому обязательно обзаведитесь быстрым SSD-диском.
На случай потери данных при сбоях и отключении питания некоторые приложения (например, NFS и БД) используют синхронную запись данных. Для этих целей у ZFS имеется целевой журнал ZIL (ZFS Intent log). Когда приложение хочет записать данные на диск, оно отправляет запрос ОС и ждет ответа. ОС сначала кэширует данные в ROM, затем сохраняет их в ZIL и только после этого возвращает управление приложению. При этом ZIL обязательно должен находиться в энергонезависимой памяти и по умолчанию располагается на диске внутри пула. Вот это и является узким местом при увеличении производительности. Но ZFS позволяет использовать в качестве log-устройства отдельные диски или даже несколько дисков одновременно. Поэтому обязательно обзаведитесь быстрым SSD-диском.
# zpool add pool log c2d0
В особых случаях, если нет SSD, то ZIL лучше отключить, производительность возрастет, но появится опасность потери данных при записях во время сбоев.
В /boot/loader.conf добавляем
Теперь рассмотрим функциональность и познакомимся с основными командами для управления ZFS.
Здесь все просто, для работы с пулами используется утилита zpool, а с файловыми системами - zfs. Они имеют смысловые команды типа create, desptoy, attach, deattach и т.д.
Работа с пулами
Пулы создается командой
В /boot/loader.conf добавляем
vfs.zfs.zil_disable="1"Еще можно отключать zil отдельно для каждой файловой системы.
# zfs set sync=disabled pool/name
Теперь рассмотрим функциональность и познакомимся с основными командами для управления ZFS.
Здесь все просто, для работы с пулами используется утилита zpool, а с файловыми системами - zfs. Они имеют смысловые команды типа create, desptoy, attach, deattach и т.д.
Работа с пулами
Пулы создается командой
# zpool create pool /dev/ada0Если пул не загрузочный, то можно использовать весь диск целиком без GPT разбивки.
Удаляется пул командой
# zpool destroy pool
Вывести список подключенных пулов
Добавить дополнительный диск к пулу
# zpool listУзнать состояние
# zpool status poolОтсоединить пул
# zpool export poolПрисоединить
# zpool import poolЕсли использовать команду import без параметров, то получите список доступных пулов.
Добавить дополнительный диск к пулу
# zpool add pool ada3Присоединяем зеркало. Диски должны быть одинакового размера, иначе по меньшему. После этого начнется resilvering, процесс синхронизации.
# zpool attach pool /disk /new-diskОтсоединяем зеркало
# zpool detach pool /diskЗамена одного устройства на другое
# zpool replace pool /disk /new-disk
После завершения выполнения команды диск отключается от конфигурации и может быть удален из системы.Посмотреть все параметры пула можно так
# zpool get allФайловые системы
Создание файловой системы в пуле осуществляется командой
# zfs create pool/nameПо умолчанию каждая созданная ФС монтируется в одноименный каталог. Но точку монтирования можно указать и другую.
Все созданные файловые системы монтируюся автоматически при присоединении пула, поэтому их не надо прописывать в fstab.# zfs set mountpoint=/new/puth pool/name
Монтирование файловой системы в пул
# zfs mount myzfs/bob
# zfs unmount myzfs/bob
Файловая система созданная внутри другой наследует ее свойства. К ним относится алгоритм сжатия и
алгоритм вычисления контрольных сумм, размер блока, квота и мн. др. Посмотреть все свойства можно по команде
# zfs get all
Зарезервировать место для файловой системы
# zfs set reservation=100G pool/nameЗадать квоту
# zfs set quota=50G pool/nameКвоты можно задавать отдельно для групп и пользователей
# zfs set userquota@user=5G pool/nameСмотреть общую информацию по использованию квот можно так
# zfs set groupquota@group=10G pool/name
# zfs userspace pool/nameили конкретно для каждого
# zfs groupspace pool/name
# zfs get userused@user pool/nameZFS предлагает очень удобный механизм резервного копирования. Для этого используются снимки и клоны.
# zfs get groupused@group pool/name
Снимок - это копия состояния ФС, хранящаяся прямо в пуле и по началу совсем не занимающая места. Но по мере изменения данных снимок начинает расти, поскольку продолжает ссылаться на старые данные и препятствует их удалению. Поэтому рекомендуется хранить минимальное число снимков.
Получить прямой доступ к снимкам нельзя. Их можно только клонировать, создавать резервные копии, выполнять откат и др. Создается снимок так
# zfs snapshot pool/name@snap_nameесли указать параметр рекурсии -r, то создаются снимки всех дочерних ФС. Располагаются в директории .zfs/snapshot в корне каждой файловой системы.
# zfs snapshot -r pool/name@nowУдалить снимок
# zfs destroy pool/name@snap_nameМожно переименовывать снимки
# zfs rename pool/name@old_name new_nameВывести список всех снимков
# zfs list -t snapshotВыполнить откат к снимку
# zfs rollback pool/name@snap_nameФС предварительно должна быть размонтирована. Все изменения, а так же созданные снимки после будут удалены и система вернется к состоянию на момент снимка.
На основе снимков можно создавать клоны.
# zfs clone pool/name@yesterday pool/cloneУничтожить клон
# zfs destroy pool/cloneМожно выполнить замену исходной файловой системы на клон.
# zfs promote pool/cloneNFS
Есть удобный механизм добавления ресурсов в NFS. Для этого сперва нужно убедиться, что у вас запущены службы NFS. В /etc/rc.conf пишем
nfs_server_enable="YES"Что бы добавить общий ресурс используется следующий синтаксис.
nfs_server_flags="-u -t -n 4"
rpcbind_enable="YES"
mountd_enable="YES"
mountd_flags="-r"
# zfs set sharenfs=on pool/name
Ресурс будет доступен всем для записи и чтения и свойства автоматически наследуются для всех дочерних файловых систем. В качесте параметров sharenfs можно использовать все опции доступные в exports.Что бы задачть только для чение, то указывается опция ro
# zfs set sharenfs=ro pool/name
Если у ресурса установлен признак sharenfs, то его можно включать и отключать командами share и unshare.
# zfs share -aКак только опция sharenfs меняется, служба mountd перезагружается автоматически.
# zfs unshare pool/name
# zfs unshare -a
Если нужно разрешить доступ только конкретным сетям или адресам, то так
# zfs set sharenfs="-maproot=root -alldir -network 10.0.0.0 -mask 255.255.255.0 192.168.15.2 192.168.10.5" zroot/shareПосмотеть все расшаренные ресурсы
# zfs get sharenfsНа стороне клиента ресурс монтируется следующим образом
# mount -t nfs server_ip:/pool/name /mntДля втоматического монтирования в /etc/fstab нужно добавить
server_ip:/pool/name /mnt nfs rw 2 2Еще бывает полезно посмотреть активность дисков в реальном времени.
# gstat -a
Всесто: gnop destroy ada0.nop
ОтветитьУдалитьнало: gnop destroy/dev/gpt/disk0.nop
Да, вы правы, спасибо за исправление!
Удалить"Получить прямой доступ к снимкам нельзя. Их можно только клонировать, создавать резервные копии, выполнять откат и др."
ОтветитьУдалитьпрямо с венды захожу в шару в \.zfs\snapshot
и вижу их и файло которое можно копировать и да же удалять )
Имелось же ввиду содержимое снимков, а не ссылки на них!
УдалитьВсе понятно - но вот вопрос
ОтветитьУдалитьПрисоединяем зеркало. Диски должны быть одинакового размера, иначе по меньшему. После этого начнется resilvering, процесс синхронизации.
# zpool attach pool /disk /new-disk
Отсоединяем зеркало
# zpool detach pool /disk
Что потом с этим диском disk отсоединенным делать? Как его можно примаунтить и работать?
Первое, что вы можете сделать это удалить диск из зеркальной конфигурации detach с целью последующей замены.
Удалить# zpool replace tank disk
Второе, вы можете импортировать пул в другую систему, но перед этим должны выполнить экспорт, поскольку попытка импорта пула, который не был явно экспортирован, отклоняется!