@ Карта сайта News Автора!

Bog BOS: Файловая система ZFS

Последние изменения:
2017.05.19: sysadmin: Файловая система zfs под Linux для архива

Последнее изменение файла: 2017.05.19
Скопировано с www.bog.pp.ru: 2017.08.18

Bog BOS: Файловая система ZFS

Файловая система ZFS рассматривается с целью организации крупного архива под Linux (CentOS) как альтернатива btrfs.

Особенности

Архитектура

ZFS (прописными) объединяет в единое целое управление пулом свободного местаи файловую систему zfs (строчными).

Пул (zpool) собирается из блочных устройств, объединяемых в зеркала и подобия RAID массивов - vdev.

Для ускорения работы используется кеш в памяти ARC и кеш чтения на выделенном устройстве (рекомендуется SSD) L2ARC.

Каждая операция записи является частью транзакции. Транзакция является атомарной операцией - она либо выполняется целиком, либо не выполняется вовсе. Каждая транзакция является частью группы транзакций (TXG, txg). Группы транзакций нумеруются и выполняются последовательно (транзакции внутри группы нет?). В каждый момент времени открыта только одна группа транзакций.

Для обеспечения синхронной записи применяется механизм ZIL и выделенное устройство для кеширования ZIL - SLOG.

Пул обеспечивает местом произвольное количество наборов данных (файловые системы zfs, тома, снимки и пр.).

Для набора данных можно создавать неизменяемые снимки, на базе которых можно делать изменяемые клоны исходного набора данных. Снимки автоматически монтируются при первом обращении к файлам.

Наборы данных можно экспортировать по NFS, SMB и iSCSI (тома как блочные устройства).

Компоненты (слои), снизу вверх:

История и совместимость

ZFS (торговая марка Oracle) разработана в Sun Microsystems (ныне Oracle), начало работ - 2001 год, включён в Solaris 10 в 2006.

Код изначально был закрыт, открыт в 2005 (в рамках OpenSolaris) под лицензией CDDL (несовместим с GPL, хотя не все в это верят), закрыт в 2010 (OpenSolaris форкнули в Illumos). Код разделился на ZFS Oracle и других.

Другие объединились под именем OpenZFS. Общий репозиторий отсутствует (планируется общий репозиторий утилит). Обеспечивает совместимость пулов хранения между реализациями. OpenZFS ныне посредник для обмена кодом из Illumos (2/3 исходных разработчиков ZFS ушли сюда после закрытия OpenSolaris), FreeBSD, OS X и ZFS on Linux.

В связи с якобы несовместимостью CDDL и GPL была разработана FUSE реализация ZFS в Linux, ныне похоже покойная (ещё есть в EPEL6, но нет в EPEL7).

Первоначально ZFS имела (ZFS Oracle и сейчас имеет) версии формата на диске, затем OpenZFS приняла единую версию 5000 и систему флагов возможностей (feature flags) - фич. Предполагается, что реализация версии 5000 включает все возможности на момент закрытия OpenSolaris - ZVOL (ZFS Emulated Volume) версии 28 и ZPL (ZFS POSIX Layer) 5.

Фича пула (свойство пула с именем feature@тия-фичи) может находиться в состоянии:

Фичи пула:

Предполагается введение фич ZPL.

ZFS on Linux

ZFS on Linux (под лицензией CDDL) представляет собой адаптацию OpenZFS для самостоятельной установки на Linux (сборка модуля ядра из исходных текстов). В Ubuntu 16.04 прямо бинарным модулем, Gentoo, Debian и ALT Linux через сборку с помощью DKMS. В дополнение к собственно ZFS поставляется SPL (Solaris Porting Layer). Для текущей версии (spl-0.6.5.8 / zfs-0.6.5.8) необходимо ядро не менее Linux 2.6.32 (RHEL/CentOS 6). Изменения в версии 0.6.5: "-o remount"; доступ к снимкам по NFS; адаптация к systemd; фичи: large_blocks (более 128КБ), filesystem_limits. Сломана фича birth_hole.

Каждый раз при обновлении ядра модуль пересобирается через DKMS (Dynamic Kernel Module Support, автоматическая перекомпиляция модуля при обновлении ядра) или стабильный API через kABI-tracking kmod (Kernel Application Binary Interface, стиль ELRepo, родной пакет kmod, не требуется переустановка модулей при обновлении ядра, если модуль использует внешние символы из белого списка). Рекомендуется использовать kABI-tracking kmod, а DKMS оставить для пользователей нестандартных ядер и любителей внести свои изменения в исходные тексты ZFS. Однако в RHEL 7.3 стабильность дала маху.

Для установки требуется добавить репозиторий yum от ZFS on Linux (для RHEL/CentOS 7, для RHEL/CentOS 7.3. В связи со сломом совместимости kABI установка kABI на 7.3 требует дополнительных действий: всё остановить, удалить и поставить заново. Ключ кладётся в /etc/pki/rpm-gpg/RPM-GPG-KEY-zfsonlinux, описание репозитория в /etc/yum.repos.d/zfs.repo

Создание зеркала репозитория yum (0.5 GB):

Установка в варианте kABI:

Устанавливаемые пакеты и файлы:

Версия 0.7.0-rc3 для el7_3 устанавливается аналогично (пытается собрать initrd для предыдущего ядра и ругается на несоответствие символов). Версия 0.7.0-rc3 для el7 не устанавливается (ругается на несоответствие символов в ядре).

Модули ядра нужно загружать явно (ранее запуск утилит zpool/zfs приводил к автоматической загрузке модулей, старое поведение можно вернуть через установку переменной окружения ZFS_MODULE_LOADING=yes, которая будет удалена в одном из будущих выпусков), загрузка модулей ZFS теперь осуществляется при помощи systemd или скриптов sysv init (initramfs после перезагрузки):

После установки надо загрузить модуль zfs вручную

modprobe zfs
Jan  3 18:42:06 x136 kernel: spl: module verification failed: signature and/or required key missing - tainting kernel
Jan  3 18:42:06 x136 kernel: SPL: Loaded module v0.6.5.8-1
Jan  3 18:42:06 x136 kernel: znvpair: module license 'CDDL' taints kernel.
Jan  3 18:42:06 x136 kernel: Disabling lock debugging due to kernel taint
Jan  3 18:42:06 x136 kernel: ZFS: Loaded module v0.6.5.8-1, ZFS pool version 5000, ZFS filesystem version 5
Jan  3 18:42:10 x136 kernel: SPL: using hostid 0x00000000

По умолчанию установлен параметр zfs_autoimport_disable модуля zfs, импортировать пул также придётся вручную:

zpool import -a

Под нагрузкой rngd забирает более 50% CPU. Рекомендуется 2048 в /proc/sys/kernel/random/read_wakeup_threshold (или "kernel.random.read_wakeup_threshold = 2048" в /etc/sysctl.conf).

Устройство управления - /dev/zfs (c,10:58).

Головная боль ZoL - борьба ядра и ZFS за память. ZFS расходует ОП на ARC (данные с диска, метаданные с диска и вспомогательные данные; информация в /proc/spl/kstat/zfs/arcstats, size - представление ARC о занятом месте, c_max - верхний предел), объекты из slab (информация в /proc/spl/kmem/slab, предоставляет ядру заниматься объектами размером менее spl_kmem_cache_slab_limit=16КиБ - информация в /proc/slabinfo, dmu_buf_impl_t - место под ссылки на объекты, часть slab слита с информацией от других подсистем ядра), неиспользуемое место (частично освобождённые slab). Однако ZFS ничего не знает о потерях памяти в результате фрагментации, в результате его сведения оказываются черезчур оптимистичными и система может подвиснуть по исчерпанию памяти. Обещают поправить в в версии 0.7 (уже есть RC).

Параметры модуля ядра spl для ZFS on Linux

spl - Solaris Porting Layer, изображает Solaris на Linux. Параметры можно установить при загрузке системы (spl.имя-параметра=значение), при загрузке модуля из файла /etc/modprobe.d/spl.conf, динамически в /sys/module/spl/parameters/имя-параметра:

Параметры модуля ядра zfs для ZFS on Linux

Модуль ядра zfs реализует файловую систему zfs (не путать с ZFS!). Параметры можно установить при загрузке системы (zfs.имя-параметра=значение), при загрузке модуля из файла /etc/modprobe.d/zfs.conf, динамически в /sys/module/zfs/parameters/имя-параметра.

Общее поведение, обработка ошибок и отладка:

Выделение места:

Базовый ввод/вывод:

Транзакции:

Предварительное чтение:

Обслуживание синхронной записи:

ARC кеш:

L2ARC кеш:

Работа с vdev:

scrub и лечение:

Тома и снимки:

События:

Что это:

Пул хранения (zpool)

Набор данных (в частности, файловая система zfs) создаётся поверх виртуального пула хранения (zpool), который конструируется из виртуальных устройств vdev, которые образуются из группы (1 штука - это тоже группа) блочных устройств: файлы, разделы или целые устройства. Разработчики рекомендуют указывать целое устройство - ZFS может включить кеш записи диска (для ZFS это считается безопасным, если по всей цепочке работает команда сброса кеша; см. параметр zfs_nocacheflush модуля zfs) в Solaris и FreeBSD, в ZFS on Linux для устройства устанавливается планировщик noop и создаётся GPT таблица разделов - маленький раздел на 8МБ и большой под ZFS (как выключить создание GPT? - можно сделать VG из 1 диска и LV на весь том, заодно с именами станет хорошо). Рекомендуется использовать имена дисков из каталога /dev/disk/by-id/ (ata-изготовитель_модель_серийный-номер, scsi-изготовитель_модель_серийный-номер, scsi-WWID, wwn-WWN (8 байт), wwn-WWID (16 байт)) или /dev/disk/by-path/ (позволяет разнести диски по ящикам, но нельзя тасовать их; в Solaris работает логика замены сбойнувшего диска на новый в ту же ячейку, а в Linux?) или /dev/disk/by-vdev/ (надо предварительно заполнить /etc/zfs/vdev_id.conf).

Типы vdev:

При создании пула он сразу импортируется, на нём создаётся корневая файловая система, которая сразу монтируется.

zpool create [ключи] имя-пула [тип-vdev] устройство1 ... [тип-vdev устройствоN ...] ... # создать пул и корневую файловую систему, ключи:

Имя пула должно начинаться с буквы и может содержать буквы, цифры, "_", "-", ".", ":", " ". Зарезервированы имена "mirror", "raidz*", "cache", "spare", "log".

Изменить количество блочных устройств в vdev невозможно (кроме расширения зеркала и разбиения состоящего из зеркал zpool), но можно добавить новый vdev в zpool. Также можно заменить устройство в vdev на большее (при наличии избыточности!): дождаться завершения лечения (resilver), повторить процедуру для оставшихся устройств (необходимо установить свойство пула autoexpand до замены первого диска - исправлено в новой версии?). ZFS не имеет средств ребалансировки, т.е. в новые vdev будут записаваться только новые данные. Кстати, лечение диска на 10ТБ потребует нескольких дней - лечение (как и scrub) идёт не последовательно, а по ссылкам инфраструктуры, так что замена одного диска вызывает полный проход по всем дискам.

В raidz (однопоточная?) производительность vdev на запись будет равна производительности 1 (самого медленного) диска, т.к. ZFS распределяет записи по vdev. При добавлении vdev распределение динамически увеличивается. Чтение может распараллеливаться внутри zdev. Придётся отказаться от традиции использовать LVM из нескольких подлежащих устройств в режиме RAID-0 (stripe) - надо добавлять в пул сами устройства.

В статье ZFS RAIDZ stripe width, or: How I Learned to Stop Worrying and Love RAIDZ рассказывается как в реальности раскладываются блоки данных, чётности и заполнителя и даётся таблица для расчёта "пропавшего" места для различных типов raidz, размера блока и размера сектора в процентах от сжатых данных. Если вкратце, то всё очень плохо - например, для raidz2 и сектор в 4 КиБ:

Для получение больших IOPS необходимо делать маленькие группы, для экономии места - большие. Однако при таких потерях и большие группы не помогут (на нашем корпусе данных 75% файлов имеют размер менее 4КиБ).

Рекомендации по построению пула (Things Nobody Told You About ZFS):

В реальности zpool - это дерево, которое начинается с корневого vdev, который состоит из vdev типа зеркало, raidz*, диск, файл, spare, cache и log. vdev типа зеркало и raidz* также могут включать vdev типа зеркало, raidz*, диск, файл. Вот только утилита создания не поддерживает такую конструкцию.

Метки ZFS присутствуют на физическом носителе, если на него производится запись данных (обычные диски в raidz, mirros и slog, но не spare). Для повышения надёжности на диске присутствуют 4 метки (по 256 КиБ) - две в начале диска и две в конце (по номерам, соответственно, 1, 2 и 3, 4). Кроме того, при обновлении данных в метках вначале обновляются первая и третья, а потом - вторая и четвёртая. Первая пара меток дополнительно содержит свободное пространство (8k) под EFI-метки и место под Boot Block Header (8k). За первой парой меток оставляется свободное пространство в 3.5 МиБ. Метка содержит описание и структуру устройств пула (кроме spare и cache) размером 112 КиБ и кольцевой буфер из 128 суперблоков размером 1 КиБ каждый. При изменении кофигурации суперблок перезаписывается на все устройства, иначе (закрытие транзакции) для перезаписи случайным образом выбирается не более 3 vdev; если выбранным оказался верхний vdev, то делается запись на все его физические устройства (пишутся 2 начальные метки, пишутся суперблоки, пишутся 2 конечные метки). При импорте по умолчанию выбирается корректный суперблок с наибольшим номером транзакции и временной меткой, но можно вручную выбрать любой из 128 (освобождённое место не используется на протяжении 3 транзакций, далее - как повезёт). Суперблок содержит указатель на MOS (Meta Object Set). Указатель имеет длину 128 байт и содержит 3 DVA длиной 128 бит (Device Virtual Address: размер объекта длиной 24 бита в единицах - ashift - верхнего vdev, номер vdev длиной 32 бита, смещение в ashift длиной 63 бита; ashift=12 - блоки по 4 КиБ), флаги: индианистость, дедупликация, шифрование, сжатие, встроенные данные, тип контрольной суммы и пр., номер транзакции выделения места, номер транзакции создания ссылки, контрольная сумма. 2 и 3 DVA используются для копий метанных (данных), см. свойство файловой системы copies. Дерево косвенных блоков данных без использования экстентов, по 128 указатель на блок размером 16 КиБ.

Каждый vdev разделен на логические разделы (metaslab), которые создаются автоматически при добавлении в zpool. Количество таких разделов определяется параметром metaslabs_per_vdev модуля zfs (по умолчанию - 200). При поиске свободного места сначал выбирается метаслаб (группа метаслабов) исходя из процента заполненности, фрагментированности свободного места (metaslab_fragmentation_factor_enabled) и пр. (см. параметры модуля zfs). Рекомендуется убрать дисковую оптимизацию при использовании SSD (metaslab_lba_weighting_enabled=0). При выделении места из метаслаба, в котором более 4% свободного места, используется алгоритм первого подходящего, иначе самого подходящего, что значительно медленнее. Чтобы предотвратить это не допускайте уменьшения свободного места в пуле ниже 10%. Или metaslab_lba_weighting_enabled=0 и можно опускать до 5%. В сильно изменяющемся пуле необходимо держать 20% свободного пространства, в слабоизменяющемся (архив) достаточно 4%.

В файле /etc/zfs/zpool.cache хранится список известных пулов (не файловых систем, посмотреть: "zdb -C"), манипуляции

zpool get [список-свойств|all] имя-пула # выводится имя свойства, значение и источник (local - отличное от умолчания), ключи:

zpool set имя-свойства=значение имя-пула # изменить значение свойства пула на ходу.

Неизменяемые свойства пула (статистика и т.п.):

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

zpool status [имя-пула] ... [интервал [отсчётов]] # показывает состояние (см. health) пула и фоновых задач; осторожно - пытается обратиться ко всем устройствам, что может вызвать большие задержки; ключи:

Сделал пул из 3 vdev, которые в свою очередь представляют собой массивы RAID-6 над LSI Logic MegaRAID SAS 9266-8i; выдернул 3 диска из одного из массивов, в результате чего он перешёл в режим Offline; попытался считать обещанные доступные файлы из zfs. Не тут-то было (особенно понравилось про отсутствие привилегий - исправлено после 0.7.0-rc3), ни прочитать, ни удалить, ни размонтировать, только перезагрузиться:

kernel: WARNING: Pool 'tm_small' has encountered an uncorrectable I/O failure and has been suspended.

zpool status -v 
  pool: tm_small
 state: UNAVAIL
status: One or more devices are faulted in response to IO failures.
action: Make sure the affected devices are connected, then run 'zpool clear'.
   see: http://zfsonlinux.org/msg/ZFS-8000-HC
  scan: scrub repaired 0 in 57h52m with 0 errors on Mon Mar 20 11:34:28 2017
config:

	NAME                                      STATE     READ WRITE CKSUM
	tm_small                                  UNAVAIL     64     0     0  insufficient replicas
	  scsi-3600605b008ca05c01fc0c51340366923  ONLINE       0     0     0
	  wwn-0x600605b008ca052020111fe9d78370c6  ONLINE       0     0     0
	  wwn-0x600605b008ca0500202630e6fda1c4eb  FAULTED      1     1     0  too many errors
	cache
	  l2arc                                   ONLINE       0     0     0

errors: List of errors unavailable (insufficient privileges)

zpool set failmode=continue tm_small
cannot set property for 'tm_small': pool I/O is currently suspended

zpool clear tm_small
cannot clear errors for tm_small: I/O error

но счётчик ошибок обнулился

zpool status -v
  pool: tm_small
 state: UNAVAIL
status: One or more devices are faulted in response to IO failures.
action: Make sure the affected devices are connected, then run 'zpool clear'.
   see: http://zfsonlinux.org/msg/ZFS-8000-HC
  scan: scrub repaired 0 in 57h52m with 0 errors on Mon Mar 20 11:34:28 2017
config:

	NAME                                      STATE     READ WRITE CKSUM
	tm_small                                  UNAVAIL      0     0     0  insufficient replicas
	  scsi-3600605b008ca05c01fc0c51340366923  ONLINE       0     0     0
	  wwn-0x600605b008ca052020111fe9d78370c6  ONLINE       0     0     0
	  wwn-0x600605b008ca0500202630e6fda1c4eb  UNAVAIL      0     0     0
	cache
	  l2arc                                   ONLINE       0     0     0

errors: 74 data errors, use '-v' for a list
# а с "-v" так:
errors: List of errors unavailable (insufficient privileges)

zpool scrub -s tm_small
cannot cancel scrubbing tm_small: pool I/O is currently suspended

zpool export tm_small
cannot export 'tm_small': pool I/O is currently suspended

rmmod zfs
rmmod: ERROR: Module zfs is in use

zfs umount tm_small
cannot open 'tm_small': pool I/O is currently suspended

zpool reopen tm_small
cannot reopen 'tm_small': pool I/O is currently suspended

zpool destroy -f tm_small # в Linux "umount -f" не работает
umount: /time_machine: target is busy.
        (In some cases useful info about processes that use
         the device is found by lsof(8) or fuser(1))
cannot unmount '/time_machine': umount failed
could not destroy 'tm_small': could not unmount datasets

перезагрузка (на удивление удалась)

zpool status -x
  pool: tm_small
 state: UNAVAIL
status: One or more devices could not be used because the label is missing 
	or invalid.  There are insufficient replicas for the pool to continue
	functioning.
action: Destroy and re-create the pool from
	a backup source.
   see: http://zfsonlinux.org/msg/ZFS-8000-5E
  scan: none requested
config:

	NAME                                      STATE     READ WRITE CKSUM
	tm_small                                  UNAVAIL      0     0     0  insufficient replicas
	  scsi-3600605b008ca05c01fc0c51340366923  ONLINE       0     0     0
	  wwn-0x600605b008ca052020111fe9d78370c6  ONLINE       0     0     0
	  wwn-0x600605b008ca0500202630e6fda1c4eb  UNAVAIL      0     0     0

zpool destroy -f tm_small
cannot destroy 'tm_small': no such pool or dataset

zpool list
NAME       SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
tm_small      -      -      -         -      -      -      -  FAULTED  -

zpool labelclear /dev/disk/by-id/scsi-3600605b008ca05c01fc0c51340366923
zpool labelclear /dev/disk/by-id/wwn-0x600605b008ca052020111fe9d78370c6

zpool list -v
NAME   SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
tm_small      -      -      -         -      -      -      -  FAULTED  -
  scsi-3600605b008ca05c01fc0c51340366923      -      -      -     16.0E      -      -
  wwn-0x600605b008ca052020111fe9d78370c6      -      -      -     16.0E      -      -
  wwn-0x600605b008ca0500202630e6fda1c4eb      -      -      -     16.0E      -      -

кеш бессмертен:

zdb -C
tm_small:
    version: 5000
    name: 'tm_small'
    state: 0
    txg: 755843
    pool_guid: 17750235030682792318
    vdev_tree:
        type: 'root'
        id: 0
        guid: 17750235030682792318
        create_txg: 4
        children[0]:
            type: 'disk'
            id: 0
            guid: 5817601266406712916
            path: '/dev/disk/by-id/scsi-3600605b008ca05c01fc0c51340366923-part1'
...

zpool create -f ... tm_small scsi-3600605b008ca05c01fc0c51340366923 cache /dev/system/l2arc
cannot create 'tm_small': pool already exists

rmmod zfs
mv /etc/zfs/zpool.cache ...
modprobe zfs

zpool list [имя-пула] ... [интервал [отсчётов]] # выдать список пулов с информацией о состоянии и заполненности, ключи:

zpool iostat [имя-пула] ... [интервал [отсчётов]] # статистика ввода/вывода, ключи:

zpool import # выдать список экспортированных пулов, доступных для импорта, ключи:

zpool import [имя-пула | идентификатор-пула [новое-имя-пула]] # перед использованием для монтирования файловой системы пул д.б. импортирован; при импорте в режиме только чтение не проигрывается ZIL и нельзя изменять свойства; ключи:

zpool destroy [-f] имя-пула # размонтировать файловые системы и уничтожить пул, подтверждения не запрашивается

zpool labelclear [-f] устройство # затереть метку zfs; заодно удаляет GPT, созданную zfs

zpool export имя-пула # отпустить пул перед переносом дисков на другой сервер - данные из кеша сбрасываются на диск, файловые системы размонтируются, диски помечаются как экспортированные, помечается запрет на автоматический импорт и монтирование, пул удаляется из кеша; пул недоступен для работы пока его не импортируют явно, если сервер умер и диски приходися переставлять без экспорта, то импортировать с "-f"; ключи:

zpool add имя-пула устройство ... # добавить vdev к пулу, ключи:

zpool remove имя-пула устройство ... # удалить диск замены, кеш или ZIL устройство

zpool scrub имя-пула # запуск в фоновом режиме проверки контрольных сумм каждой копии каждого используемого блока и проверку чётности для RAIDZ (при обычном чтении не делается), лечение по возможности; рекомендуется раз в неделю/месяц; ключ "-s" - остановить (продолжить нельзя); если совсем всё плохо: "zpool import -o readonly=on имя-пула; zpool scrub имя-пула"; scrub (и лечение) осуществляет проход по структуре, а не последовательное чтение, причём однопоточное синхронное, т.е. безумно медленно; проверка структуры производится по минимому - лишь бы можно было пройти; scrub производит 2 типа ввода/вывода: чтение каталогов и dnode производится с помощью обычного механизма (предварительное загрузка, синхронное чтение через механизм ARC, без всяких проверок, не учитывается в отчёте сканирования) и асинхронное чтение всех копий блоков с проверкой (учитывается в отчёте сканирования, настраивается с помощью параметров модуля вплоть до отключения); можно запустить только одну проверку пула одновременно:

массив из обычных дисков, собранный в LSI/LVM, 500 снимков, без нагрузки
  scan: scrub in progress since Thu Jan 26 18:36:45 2017
    877M scanned out of 40.8T at 5.10M/s, (scan is slow, no estimated time)
    0 repaired, 0.00% done

массив из быстрых дисков (SAS 10k rpm), собранный в LSI/LVM, 100 снимков, DDT, без нагрузки
  scan: scrub in progress since Fri Jan 27 22:35:58 2017
    20.5G scanned out of 13.2T at 35.8M/s, 107h17m to go
    0 repaired, 0.15% done

2 масива из разных дисков, 15 снимков, DDT, пробовал (без пользы), 10.5 ТБ (ALLOC) за 23.5 часа, без нагрузки
   128 в /sys/module/zfs/parameters/zfs_top_maxinflight
   1 в /sys/module/zfs/parameters/zfs_no_scrub_prefetch

  299G scanned out of 9.56T at 52.3M/s, 51h36m to go
  384G scanned out of 9.56T at 50.4M/s, 53h6m to go
  640G scanned out of 9.56T at 47.0M/s, 55h20m to go
  884G scanned out of 9.56T at 45.6M/s, 55h28m to go
  1.09T scanned out of 9.56T at 44.8M/s, 55h6m to go
  2.22T scanned out of 9.56T at 47.6M/s, 44h50m to go
  2.59T scanned out of 9.56T at 41.2M/s, 49h18m to go
  5.18T scanned out of 9.56T at 71.9M/s, 17h44m to go
  6.17T scanned out of 9.56T at 84.1M/s, 11h43m to go
  7.52T scanned out of 9.56T at 100M/s, 5h56m to go # оба массива читают по 600 МБ/сек
  8.20T scanned out of 9.56T at 108M/s, 3h40m to go
  8.63T scanned out of 9.56T at 113M/s, 2h24m to go
  8.84T scanned out of 9.56T at 115M/s, 1h50m to go
  9.28T scanned out of 9.56T at 117M/s, 0h42m to go
  9.41T scanned out of 9.56T at 118M/s, 0h21m to go

3 массива из разных дисков, добавлялись последовательно по мере наполнения, 28.9TB (ALLOC), без нагрузки
    2.61T scanned out of 28.9T at 59.1M/s, 129h36m to go
    4.33T scanned out of 28.9T at 59.1M/s, 121h8m to go
    5.06T scanned out of 28.9T at 57.8M/s, 120h18m to go
    10.7T scanned out of 28.9T at 83.8M/s, 63h29m to go
    17.0T scanned out of 28.9T at 115M/s, 30h16m to go
    19.0T scanned out of 28.9T at 121M/s, 23h47m to go
  scan: scrub repaired 0 in 57h52m with 0 errors on Mon Mar 20 11:34:28 2017

zpool replace имя-пула старое-устройство [устройство-замены] # подсоединить устройство замены, дождаться завершения лечения, отсоединить старое устройство, ключи:

zpool clear имя-пула [устройство] # сбросить счётчики ошибок

zpool offline имя-пула устройство # объявить устройство нерабочим, ключ "-t" - до перезагрузки

zpool online имя-пула устройство # объявить устройство рабочим, ключ "-e" - расширение устройства до физического

zpool attach имя-пула старое-vdev устройство # добавить устройство к vdev, простое vdev превращается в зеркало (начинается лечение), raidz расширить нельзя, ключи:

zpool detach имя-пула старое-устройство # извлечь устройство из зеркала, для временного извлечения рекомендуется "zpool offline"

zpool reopen имя-пула # заново открыть все устройства пула

zpool reguid # сгенерировать новый GUID пула

zpool split имя-пула новый-пул [устройство ...] # только для пула из зеркал; отщепить от каждого зеркала последнее устройство и собрать из них новый пул, ключи:

zpool upgrade # выдать список пулов, которые можно перевести на новую версию

zpool upgrade {имя-пула | -a} # перевод пула на новую версию, вернуться нельзя

zpool history [имя-пула] # история команд, история хранится в пуле и её нельзя отключить (а если пул заполнен на 100%?), используется кольцевой буфер (32 МиБ?); ключи:

zpool events имя-пула # выдать список событий zfs, сгенерированных ядром, см. zfs-events(5), ключи:

Кеш в памяти - ARC

Для ускорения работы используется кеш данных и метаданных в памяти - ARC (Adaptive Replacement Cache). ARC является модифицированной реализацией запатентованного IBM механизма кеширования как последних (LRU - Least Recently Used), так и частых запросов (LFU - Least Frequently Used), поддерживаются следующие очереди:

Кеш блоков общий. На один и тот же блок могут быть ссылки из MRU и MFU. Ghost MRU и Ghost MFU ведутся и при отсутствии L2ARC - блоки легче извлекать из пула при наличии этих ссылок. При извлечении блоков по ссылке из Ghost MRU расширяется список MRU за счёт MFU, и наоборот. Таким образом кеш автоматически подстраивается под тип нагрузки. Размер кеша может меняться по требованию ядра (и в Linux?), блоки имеют разный размер, блоки могут быть заблокированы от удаления (?).

Место в ARC расходуется на данные, метаданные и вспомогательную информацию. Тип кешируемой информации можно установить с помощью свойств набора данных primarycache. Статистика ARC и L2ARC доступна через /proc/spl/kstat/zfs/arcstats, в удобном виде показывается утилитой arc_summary.py. По умолчанию размер используемой ОП колеблется от 1/32 (zfs_arc_min) до 1/2 (zfs_arc_max) всей ОП. Если предполагается запуск программ, требовательных к ОП, рекомендуется заранее ограничить ARC. Некоторые программы перед запуском проверяют размер свободной памяти и отказываются запускаться при её недостатке, хотя в реальности память могла быть освобождена системой по требованию. Некоторые программы могут требовать больших непрерывных сегментов памяти или huge pages, которые ARC без настроек фрагментирует.

По умолчанию только 1/4 (3/4?) ARC может использоваться под метаданные (включая таблицу дедупликации), объём метаданных оценивается как 1% от ёмкости хранилища. Изменить можно параметром zfs_arc_meta_limit модуля zfs или командой "zfs set primarycache=metadata|all|none".

ARC в реализации ZFS on Linux не связан с системой кеширования ОС (страницы виртуальной памяти), например, команда free показывает ARC в графе used. Это требует тщательного планирования и управления (лучше не запускать на файловом сервере требовательных к ОП программ). Фрагментация памяти в Linux приводит к тому, что в реальности используется больше памяти, чем показывается (и как представляется управляющей программе ARC). mmap() не умеет брать из ARC, только из страниц виртуальной памяти.

Кеш второго уровня на SSD - L2ARC

Кеш ARC может быть расширен (только для операций чтения) с помощью быстрого SSD устройства - L2ARC (second level ARC). L2ARC может входить в пул с момента создания или быть добавлен в пул и убран из пула без остановки его работы:

zpool add имя-пула cache устройство

Место в L2ARC расходуется на данные, метаданные (включая таблицу дедупликации) и вспомогательную информацию. Тип кешируемой информации можно установить с помощью свойств набора данных secondarycache. Нежелательно превышать 5 (?) размеров ARC: место в ARC расходуется на ссылки на L2ARC (Ghost, ARC_SPACE_L2HDRS), причём оно не освобождается даже под давлением - производительность может уменьшиться. Статистика ARC и L2ARC доступна через /proc/spl/kstat/zfs/arcstats, в удобном виде показывается утилитой arc_summary.py. Статистика L2ARC общая для модуля zfs, не обнулишь, пока не выгрузишь модуль.

Потеря устройства не ведёт к потере данных (кешируется только чтение). Можно использовать несколько L2ARC устройств (без страйпинга). Зеркало и raidz не поддерживаются.

Предварительное чтение регулируется параметром l2arc_noprefetch модуля zfs (ещё есть общий параметр prefetch_disable модуля zfs).

Может заполняться несколько часов.

ARC - глобальный, L2ARC - привязан к пулу, неразделяемый, а ссылки на L2ARC в ARC занимают общее место.

Samsung 840 Pro теряет 1% жизни в день или два (настроенная дедупликация - L2ARC размером 300GB (529.86 GiB сжатого до 200.24 GiB), Hit Ratio - 8.03%, входящий поток 1Gbps). В общем, если нет хотя бы Intel DC S3600, то установить secondarycache=metadata, иначе будет тормозить, а потом умрёт.

Управление синхронной записью - ZIL

Асинхронная запись кешируется в ОП (ARC), при коммите транзакции (transaction group commits, каждые N секунд) накопленные (грязные) данные сбрасываются на устройство постоянного хранения. Но запросы на синхронную запись должны быть записаны на устройство постоянного хранения немедленно с подтверждением, для этого используется механизм временного хранения ZIL (ZFS intent log). По умолчанию ZIL располагается на дисках обслуживаемого пула (отдельная структура для каждого набора данных - файловой системы или тома). Дисковый ZIL читается только при восстановлении после падения сервера. После размещения данных из ARC на постоянное место хранения место в дисковом ZIL освобождается. Структуры ZIL в ОП накапливают все записи, относящиеся к незавершённым транзакциям (все записи, т.к. неизвестно какие из них будут синхронными) Операции над метаданными (создание, переименование) по умолчанию являются синхронными. Набор данных может иметь свойство "sync=always", что объявляет каждую запись синхронной, или "sync=disabled", что отключает логику дискового ZIL, но структуры ZIL в ОП продолжают накопление записей, которые сбрасываются на диск при завершении транзакции.

ZFS имеет механизм обхода ZIL для потоковой нагрузки - данные пишутся сразу на место. При монтировании NFS с флагом async большинство записи проходит мимо ZIL. Локальная запись обычно также асинхронна.

При необходимости можно выделить специальное устройство SLOG (ZIL device), учитывая режим работы - однопоточная синхронная запись (для одного dataset) и защита от отключения питания - рекомендуется STEC ZeusRAM (память с батарейкой), SSD SLC и т.п. Размер определяется максимальным трафиком записи за тройное время между комитами транзакций (по умолчанию параметр zfs_txg_timeout модуля zfs был 30, потом 5, потом 10), но не более размера ARC. Для MLC SSD для продления его жизни надо взять устройство (раздел) побольше. Потеря SLOG приведёт к потере последних данных (но не метаданных), пул не будет импортироваться автоматически (можно импортировать вручную), поэтому желательно использовать vdev типа зеркало (raidz не поддерживается). Можно поставить несколько vdev типа slog - они будут работать паралллельно.

Статистику можно посмотреть в /proc/spl/kstat/zfs/zil.

Советы:

Основные настройки:

Контроллер RAID превращает синхронную запись в асинхронную с помощью буферизации в память, защищённую батарейкой.

Наборы данных: файловая система и том

В пуле может быть создано несколько именованных (длина имени не более 256 байт) наборов данных (datasets):

Свойства набора данных наследуются от пула или родительского набора данных (при создании пула свойства корневой файловой системы можно указать ключом "-O", при создании файловой системы свойства можно указать ключом "-o") задаются при создании (постоянно) или монтировании (временно). Имеется возможность задавать свои (пользовательские) свойства, они не влияют на работу ZFS, всегда наследуются, имя - до 256 байт, значение - до 1024 байт. Свойства требуют места в пуле и при его заполнении их невозможно изменить.

zfs get {список-свойств|all} [имя-пула[/имя-набора-данных[@имя-снимка]]] # выдать список значений свойств; выводятся колонки: имя набора данных, имя свойства, значение свойства, источник; в колонке источник (SOURCE) могут быть выданы значения: default (значение взято по умолчанию), inherited (значение унаследовано от пула или родительского набора данных), local (значение свойства установлено явно этого набора данных), temporary (значение установлено временно при монтировании), received (send/receive) или '-' (none, вычисляемый); ключи:

zfs set свойство=значение имя-пула[/имя-набора-данных[@имя-снимка]] # изменить свойство.

zfs inherit свойство имя-пула[/имя-набора-данных] # унаследовать свойство от родительского набора или пула или умолчания; ключи:

Задаваемые свойства набора данных (свойства наследуются; изменение свойства действует на файлы, создаваемые после изменения, сжатие происходит до дедупликации - не надо менять режим сжатия при включённой дедупликации на полпути):

Информационные свойства набора данных (не наследуются, не устанавливаются):

Размер свободного использованного места в zfs ещё более сложен, чем в btrfs (см. выше описание параметров used*, referenced, logicalused, logicalreferenced). df и du показывают занятое место на диске после сжатия с учётом метаданных, но без учёта дедупликации (даёт ответ на вопрос - "сколько места освободится на диске после удаления?"). Чтобы узнать размер файлов до сжатия необходимо использовать "du --apparent-size". Команда "ls -l" показывает исходный размер файла, команда "ls -lsh" показывает размер файла на диске без учёта дедупликации. Полный размер файловой системы (total), выдаваемый командой df, изменяется по мере изменения коэффициента дедупликации (и сжатия?). Счётчики обновляются в момент завершения транзакции. При использовании vdev типа raidz2 каждый блок содержит как минимум 2 сектора (512 байт или с учётом ashift?) чётности, которые не попадают ни в какие отчёты.

zfs create имя-пула/имя-файловой-системы # создание файловой сисемы (монтируется автоматически), ключи:

zfs create -V размер имя-пула/имя-тома # создание тома (zvol), экспортируется в блочное устройство /dev/zvol/имя-пула/имя-тома, размер округляется до 128 КиБ, ключи:

zfs destroy имя-пула/имя-набора-данных # удаление файловой системы или тома; файловая система размонтируется и разшаривается; не д.б. наследников и зависимых клонов (см. ключ "-r" и "-R"); осторожно: приводит к необходимости изменения миллионов (сотен миллионов) блоков метаданных, при использовании фичи async_destroy изменения идут в фоновом режиме и продолжаются с точки остановки после перезагрузки; ключи:

zfs destroy имя-пула/имя-набора-данных@имя-снимка[%имя-снимка][,...] # удаление снимков, можно указать список интервалов снимков; удаляется немедленно, если нет блокировок (hold) и зависимых клонов, иначе помечается для удаления после выполнения указанных условий; снимок 84 GiB (самый большой) удалился быстро; интервал снимков (482 GiB) удалялся полторы минуты (в фоне); ключи:

zfs destroy имя-пула/имя-набора-данных#имя-закладки # удалить закладку

zfs snapshot имя-пула/имя-файловой-системы-или-закладки@имя-снимка # создать снимок; в снимок попадают старые значения при изменении файловой системы, менять нельзя; ключи:

zfs rollback имя-пула/имя-файловой-системы-или-тома@имя-снимка # откатить состояние файловой системы или тома на время создания снимка; снимки подчинённых файловых систем не удаляются даже с ключами -rR; ключи:

zfs clone имя-пула/имя-файловой-системы-или-тома@имя-снимка имя-пула/новое-имя-файловой-системы-или-тома # создать новую файловую систему или том на основе снимка; файловая система будет смонтирована по умолчанию в /имя-пула/новое-имя-файловой-системы; ключи:

zfs promote клонированная-файловая-система # исходная файловая система становится клоном (её можно потом удалить, но снимок - нет!), клон становится независимой файловой системой, а снимок привязывается к ней, все предыдущие снимки также привязываются к бывшему клону, последующие остаются привязанными к бывшей исходной файловой системе. предварительно необходимо разрешить все конфликты имён.

zfs bookmark имя-пула/имя-файловой-системы-или-тома@имя-снимка имя-закладки # создать закладку.

zfs rename имя-пула/имя-набора-данных имя-пула/новое-имя; переименовать набор данных; при необходимости производится перемонтирование; ключи:

zfs rename [-f] имя-пула/имя-файловой-системы@имя-снимка новое-имя-снимка # переименовать снимок; ключи:

zfs list [имя-пула/имя-набора-данных] ... # выдать список наборов данных и их свойств; ключи:

zfs mount # выести список смонтированных файловых систем; временно смонтированные файловые системы для снимков не показывает.

zfs mount {имя-пула/имя-файловой-системы|-a} # смонтировать файловую систему; автоматически выполняется при загрузке (импорте пула?); ключи:

zfs unmount|umount {-a | имя-пула/имя-файловой-системы | точка-монтирования} # размонтирование файловой системы; ключ "-f" размонтирует насильсьтвенно (не действует в Linux).

zfs share {-a | имя-пула/имя-файловой-системы} # выдаёт (экспортирует, расшаривает) файловую систему наружу для NFS, SMB или iSCSI для файловых систем и томов с установленными свойствами sharenfs, sharesmb или shareiscsi; выполняется автоматически при загрузке (импорте пула?); шары создаются в подкаталоге .zfs/shares/ корня файловой системы; снимки экспортируются вместе с файловой системой (при первом обращении к .zfs/snapshot); можно экспортировать непосредственно .zfs/snapshot.

zfs unshare {-a | имя-пула/имя-файловой-системы | точка-монтирования} # закрывает файловую систему для экспорта; выполняется автоматически при заверешнии работы сервера.

zfs send имя-пула/имя-набора-данных@имя-снимка # вывести на stdout поток, представляющий содержимое снимка; этот поток можно сохранить или сразу использовать локально или удалённо (например, с помощью ssh) командой "zfs receive"; формат потока стандартизован и зафиксирован; send делает hold на снимки; посмотреть заголовки и статистику можно с помощью утилиты zstreamdump; на передающем конце данные разжимаются и дуплицируются (см. "-D"), на приёмном сжимаются обратно и дедуплицируются; ключи:

zfs send имя-пула/имя-набора-данных # вывести на stdout поток, представляющий содержимое файловой системы; файловая система должна быть размонтирована или смонтирована только на чтение; на приёмном конце создаётся искусственный снимок с именем "--head--"; ключи:

zfs receive имя-пула/имя-набора-данных[@имя-снимка] # принять поток от "zfs send" на stdin и создать из него снимок для инкрементального потока (файловая система должна существовать, также проверяется адекватность снимка, если имя-снимка указано в команде, то берётся из команды, иначе - из потока); при приёме полного потока создаются файловая система и снимок; при приёме пакета потоков (-R) на приёмном конце удаляются снимки, отсутствующие у источника ("zfs destroy -d"); при приёме тома ссылка на устройство пересоздаётся (не получится его использовать во время передачи); скорость передачи/приёма первое время (5ТБ) ограничивается скоростью сжатия, затем скоростью ввода/вывода; при прерывании передачи файловая система откатывается к моменту начала (зависла при использовании "send -D", не убила даже "zpool destroy ...", процесс заблокировал накопленные 2 ГБ ОП); после передачи первого снимка монтирования не произошло, попытался вручную - файловая система пуста, передача прервалась ("dataset is busy"), не трогайте приёмник до завершения всей передачи; ключи:

zfs diff имя-пула/имя-файловой-системы@имя-снимка имя-пула/имя-файловой-системы[@имя-снимка] # вывести список файлов, изменившихся между снимками ("-" - удалён, "+" - добавлен, "M" - изменён, "R" - переименован); ключи:

zfs userspace имя-пула/имя-файловой-системы[@имя-снимка] # показать квоты и занимаемое место (см. свойства userused@имя-пользователя и userquota@имя-пользователя; ключи:

zfs groupspace имя-пула/имя-файловой-системы[@имя-снимка] # показать квоты и занимаемое место (см. свойства groupused@имя-группы и groupquota@имя-группы; ключи:

zfs allow и unallow позволяют передать непривилегированному пользователю (не uid 0) часть прав по администрированию файловой системы или тома. Без параметров выводит текущие права.

zfs hold [-r] метка имя-пула/имя-файловой-системы@имя-снимка ... # именованная блокировка не позволяет удалить снимок.

zfs holds [-r] имя-пула/имя-файловой-системы@имя-снимка ... # вывести список блокировок.

zfs release [-r] метка имя-пула/имя-файловой-системы@имя-снимка ... # снять поименованную блокировку.

zfs upgrade [-v] # показать список файловых систем (не пулов!), которые можно улучшить. В настоящее время нет ничего кроме версии 5.

zfs upgrade {-a | имя-пула/имя-файловой-системы} # обновить версию файловой системы (не пула!); ключи:

Для InnoDB необходимо установить параметр zfs_nocacheflush модуля zfs и создать отдельную файловую систему со свойствами recordsize=16K, primarycache=metadata, logbias=throughput, atime=off, sync=disabled.

Для MyISAM необходимо установить параметр zfs_nocacheflush модуля zfs и создать отдельную файловую систему со свойствами recordsize=8K, primarycache=metadata, logbias=throughput, atime=off, sync=disabled.

А лучше не использовать CoW файловую систему для работы с СУБД, под swap, блочные устройства виртуальных машин и т.п..

Кроме предварительного чтения на уровне устройств ZFS предлагает механизм предварительного чтения на уровне файлов - zfetch. Этот механизм отслеживает шаблоны чтения файлов и при обнаружении потока последовательного чтения (вперёд или назад, сплошного или интервального, 8 потоков на файл - на dnode, а не на file handler) заранее загружает данные в кеш ARC. Статистику можно получить в /proc/spl/kstat/zfs/zfetchstats или с помощью утилиты arc_summary.py. Управлять можно с помощью параметров zfs_prefetch_disable, zfetch_array_rd_sz, zfetch_block_cap, zfs_read_chunk_size модуля zfs.

Для обработки ситуации с удалением использумых в настоящий момент файлов (pending delete) применяется такой внутренний объект ZFS как очередь удаления, которая хранит ссылки на все временно не удалённые объекты (отдельная очередь для каждой файловой системы и снимка, таким образом место не освободится пока не будет удалён последний снимок). Эта очередь передаётся в операциях send/receive и в момент монтирования по завершению передачи файлы удаляются, порождая расхождение между текущим состоянием файловой системы и только что переданных снимком (но место не осовободится!), при следующей инкрементальной передаче придётся использовать ключ "-F" для откатки этого изменения. Поиск объектов очереди удаления (не нашёл):

zdb -dddd имя-файловой-системы 1

найти в выводе "DELETE_QUEUE = номер-объекта"

zdb -dddd имя-файловой-системы номер-объекта
...
ZAP entries: количество объектов в очереди на удаление

Дедупликация

ZFS использует синхронную дедупликацию, которая производится после сжатия (не надо менять сжатие на ходу!) на блочном уровне. Дедупликация воздействует на весь пул - дедуплицированные файлы могут ссылаться на записи в других файловых системах этого пула, производится дополнительная работа со всеми файлами пула, размер DDT определяется всем пулом, даже свойство dedupratio относится к пулу, а не файловой системе. Метаданные и каталоги не участвуют в дедупликации.

Для работы дедупликации необходимо ведение на ходу таблицы дедупликации (DDT), которая хранит хеш блока (sha256) и количество блоков, имеющих этот хеш. Каждый указатель на блок данных имеет флаг дедупликации, который взводится при записи при наличия дубля с таким же хешем. DDT не используется при чтении данных (если не произошло ошибки чтения и не пришлось читать запасную копию), DDT изменяется при записи, при удалении блока проверяется флаг дедупликации указателя на блок и при необходимости изменяется счётчик использования в DDT. Если счётчик уменьшается до нуля, то удаляется сама запись из DDT. DDT всегда есть, возможно пустая. На каждый пул заводится отдельная DDT (одна на весь пул; похоже, что заводится отдельная таблица на блоки с 1 ссылкой?). DDT относится к метаданным и пишется в режиме CoW. На каждый блок данных требуется 320 байт на диске ("zdb -L -D" сообщает, что требуется 449 байт для уникальных блоков и 476 байт для всех дублей с одним хешем на диске и 153/145 байт в памяти). Если грубо, то на каждый ТБ ёмкости хранилища необходимо от 1 до 5ГБ под DDT, для более точного подсчёта текущих потребностей необходимо получить количество блоков в пуле - bp count ("zdb -L -b имя-пула" - очень долго и нужно очень много памяти) и умножить на 320 (449 для уникальных блоков и 476 для каждой группы одинаковых). Занимаемое место отражается в USEDCHILD. При необходимости (?) регенерируется из метаданных.

Выключение дедупликации не отменяет необходимости вносить изменения в DDT при удалении блока.

При проверке и лечении DDT используется как источник ссылок, по которым надо пробежаться.

Для обеспечения нормальной скорости DDT должна быть в ARC, в крайнем случае - в L2ARC. При недостатке ARC и L2ARC удаление снимка может потребовать сутки (и его нельзя прервать даже перезагрузкой). Кроме DDT в ARC должно остаться место под прочие метаданные (в среднем 1% от ёмкости хранилища) и данные (3/4 от ARC, параметр zfs_arc_meta_limit модуля zfs?) с учётом максимального размера самого ARC и уровня фрагментации памяти (как узнать?). Кстати, записи DDT в L2ARC (300-500 байт?) требуют места под ссылки на них в ARC (180 байт?).

Если ожидается большой средний размер файла, то можно увеличить recordsize файловой системы с 128 КиБ до 1 МиБ, таким образом уменьшив потребности в памяти в 8 раз (в предельно оптимистичном случае). У меня средний размер блока получился равным 338 КБ до сжатия и 114 КБ после оного.

При выборе SSD под L2ARC необходимо учитывать большую и непрерывную нагрузку, так что надо не хуже Intel DC S3600 (S3500?). Предполагаемая производительность DDR3 в этом режиме - 100-150k IOPS.

Встречаются самые разные рекомендации от необходимости вынесения всех дедуплицированных файловых систем в отдельный пул до категорического неприятия дедупликации как таковой. Важной информацией для решения является степень дедупликации dedupratio, предсказать её можно командой "zdb -S имя-пула" (очень долго, строится временная DDT - заодно узнаете достаточно ли у Вас памяти ;).

Офлайновую дедупликацию сделать не получится, т.к. отсутствует механизм прозрачной для пользователя перезаписи блоков данных и метаданных. Этот же механизм (BPR - Block Pointer Rewrite, ожидается с 2008) позволит сделать дефрагментацию, ребалансировку, уменьшение пула или vdev и т.д..

Утилита zdb

Утилита zdb позволяет узнать полезную информацию о текущем состоянии ZFS, базовые ключи ("-L" - не делать проверок):

Утилиты сбора статистики

arc_summary.py - статистика использования ARC ("-p 1" и "-p 2") и L2ARC ("-p 3") и DMU ("-p 4"), также выводит значения параметров модулей ядра ("-p 6 -d").

arcstat.py - iostat для кеша.

dbufstat.py - статистика (ключ "-t") и содержимое объектов в памяти.

udev и vdev

Видимо, в Solaris нет udev и пришлось делать своё. См. vdev_id.conf.5 и vdev_id.8, правила udev в /usr/lib/udev/rules.d/: 60-zvol.rules, 69-vdev.rules, 90-zfs.rules

Система извещений

См. zfs-events.5 и zed.8, /usr/libexec/zfs/zed.d/.

Настройки systemd

См. в /usr/lib/systemd/system-preset/50-zfs.preset и /usr/lib/systemd/system/: zfs-import-scan.service, zfs-mount.service, zfs-share.service, zfs-zed.service, system/zfs.target.

Выделенный сервер архива без дедупликации

Выделенный сервер архива без дедупликации: 8 ядер по 3.5GHz, 64 ГиБ ОП, сеть 10Gbps, большой локальный массив (LSI MEGARAID 2xRAID-6 of 18 SATA HDD LFF 2000GB 7200 rpm (старые больные диски) + lvmcache на SSD Intel DC S3500).

Параметры модуля spl (/etc/modprobe.d/spl.conf): отсутствуют.

Параметры модуля zfs (/etc/modprobe.d/zfs.conf): отсутствуют.

Создание пула (надо было xattr=sa и без utf8only, выше gzip-7 не тянет, вместе с relatime надо включать atime, checksum лучше делать sha256):

zpool create -f -m /time_machine -o ashift=12 -o listsnapshots=on \
-d -o feature@async_destroy=enabled -o feature@empty_bpobj=enabled -o feature@lz4_compress=enabled -o feature@spacemap_histogram=enabled -o feature@extensible_dataset=enabled -o feature@bookmarks=enabled -o feature@enabled_txg=enabled -o feature@embedded_data=enabled -o feature@large_blocks=enabled \
-O utf8only=on \
-O compression=gzip-7 \
-O atime=off -O relatime=on \
-O acltype=posixacl -O xattr=on \
-O dedup=off \
-O redundant_metadata=most \
-O sync=disabled -O logbias=throughput \
-O snapdir=visible \
time_machine dm-name-x136all36-share 

Наполнение архива с помощью rsync (40 потоков, "--max-size=100GB -vas --inplace --numeric-ids --ignore-errors --delete").

Статистика после заполнения первого дня, в 1.5 раза дольше btrfs поверх того же аппаратного RAID и LVM cache, примерно тот же объём (но 3.5% - 2 ТБ - заблокировано):

df -B MB /time_machine
Filesystem     1MB-blocks       Used  Available Use% Mounted on
time_machine   61778751MB 11329313MB 50449439MB  19% /time_machine

zpool list
NAME           SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
time_machine    58T  10.3T  47.7T         -    14%    17%  1.00x  ONLINE  -

zfs  list -o compress,compressratio,refcompressratio,usedbychildren,usedbydataset,usedbyrefreservation,usedbysnapshots
COMPRESS  RATIO  REFRATIO  USEDCHILD  USEDDS  USEDREFRESERV  USEDSNAP
  gzip-7  2.56x     2.56x      56.0M   10.3T              0         0

zfs list
NAME           USED  AVAIL  REFER  MOUNTPOINT
time_machine  10.3T  45.9T  10.3T  /time_machine

Статистика блоков после заполнения первого дня

zdb -b time_machine
Traversing all blocks to verify nothing leaked ...

loading space map for vdev 0 of 1, metaslab 64 of 116 ...
10.3T completed (1421MB/s) estimated time remaining: 0hr 00min 00sec
        No leaks (block sum matches space maps exactly)

        bp count:       291107412
        ganged count:           0
        bp logical:    28883875873792      avg:  99220
        bp physical:   11236123043328      avg:  38597     compression:   2.57
        bp allocated:  11329371234304      avg:  38918     compression:   2.55
        bp deduped:             0    ref>1:      0   deduplication:   1.00
        SPA allocated: 11329371234304     used: 17.77%

        additional, non-pointer bps of type 0:   24469613
        Dittoed blocks on same vdev: 5579261 

Статистика после заполнения 23-го дня:

df -i /time_machine
Filesystem          Inodes    IUsed       IFree IUse% Mounted on
time_machine   93362015349 78754757 93283260592    1% /time_machine

df -B MB /time_machine
Filesystem     1MB-blocks       Used  Available Use% Mounted on
time_machine   60204402MB 12443373MB 47761030MB  21% /time_machine

zpool list
NAME           SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
time_machine    58T  12.7T  45.3T         -    14%    21%  1.00x  ONLINE  -

zfs  list time_machine -o compress,compressratio,refcompressratio,usedbychildren,usedbydataset,usedbyrefreservation,usedbysnapshots
COMPRESS  RATIO  REFRATIO  USEDCHILD  USEDDS  USEDREFRESERV  USEDSNAP
  gzip-7  2.78x     2.64x      1.36G   11.3T              0     1.43T

zfs list|head -4;zfs list |tail -4
NAME                    USED  AVAIL  REFER  MOUNTPOINT
time_machine           12.7T  43.4T  11.3T  /time_machine
time_machine@20140801  16.3G      -  10.3T  -
time_machine@20140802  3.52G      -  10.9T  -
time_machine@20140820  13.9G      -  11.1T  -
time_machine@20140821  6.93G      -  11.2T  -
time_machine@20140822  2.80G      -  11.2T  -
time_machine@20140823  1.87G      -  11.3T  - 

Статистика после заполнения 96-го дня (фрагментация свободного пространства всё ещё приличная):

df -i /time_machine
Filesystem          Inodes    IUsed       IFree IUse% Mounted on
time_machine   86838204271 81602375 86756601896    1% /time_machine

df -B MB /time_machine
Filesystem     1MB-blocks       Used  Available Use% Mounted on
time_machine   58034215MB 13614834MB 44419381MB  24% /time_machine

zpool list
NAME           SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
time_machine    58T  15.8T  42.2T         -    19%    27%  1.00x  ONLINE  -

zfs  list time_machine -o compress,compressratio,refcompressratio,usedbychildren,usedbydataset,usedbysnapshots
COMPRESS  RATIO  REFRATIO  USEDCHILD  USEDDS  USEDSNAP
  gzip-7  2.89x     2.65x      3.41G   12.4T     3.40T

zfs list|head -4;zfs list |tail -4
NAME                    USED  AVAIL  REFER  MOUNTPOINT
time_machine           15.8T  40.4T  12.4T  /time_machine
time_machine@20140801  16.3G      -  10.3T  -
time_machine@20140802  3.52G      -  10.9T  -
time_machine@20141031  1.41G      -  12.3T  -
time_machine@20141101  2.47G      -  12.4T  -
time_machine@20141102  1.34G      -  12.4T  -
time_machine@20141103   298M      -  12.4T  - 

zdb -L -b time_machine

Traversing all blocks ...

16.4T completed ( 671MB/s) estimated time remaining: 0hr 00min 04sec         
	bp count:       500483120
	ganged count:           0
	bp logical:    52499166426624      avg: 104896
	bp physical:   17887185559552      avg:  35739     compression:   2.94
	bp allocated:  18031836352512      avg:  36028     compression:   2.91
	bp deduped:             0    ref>1:      0   deduplication:   1.00
	SPA allocated: 18031836352512     used: 28.28%

	additional, non-pointer bps of type 0:   29943472
	Dittoed blocks on same vdev: 12402758

Статистика L2ARC:

L2 ARC Size: (Adaptive)				254.89	GiB
	Compressed:			49.48%	126.12	GiB
	Header Size:			0.23%	598.29	MiB

L2 ARC Breakdown:				2.54b
	Hit Ratio:			3.19%	81.03m
	Miss Ratio:			96.81%	2.46b
	Feeds:					228.49k

zfs set secondarycache=metadata time_machine
zpool remove time_machine /dev/system/l2arc
zpool add time_machine cache /dev/system/l2arc # статистика общая

Попытался выполнить "zdb -S" на системе с 64ГиБ ОП и распределённым пулом 21 ТиБ (из 58 ТиБ). После 3 часов молчаливой работы система начала тупить (трешинг свопа? вплоть до "сервер недоступен" в мониторинге), при этом zdb потребил почти 19 ГиБ, top показывал наличие свободной памяти.

Статистика после заполнения 236-го дня (фрагментация свободного пространства всё ещё приличная, средний прирост - 70 ГБ в день):

df -i /time_machine
Filesystem          Inodes     IUsed       IFree IUse% Mounted on
time_machine   66644509563 108181763 66536327800    1% /time_machine

df -B MB /time_machine
Filesystem     1MB-blocks       Used  Available Use% Mounted on
time_machine   47971509MB 13904913MB 34066597MB  29% /time_machine

zpool list -v
NAME   SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
time_machine    58T  25.2T  32.8T         -    32%    43%  1.00x  ONLINE  -
  dm-name-x136all36-share    58T  25.2T  32.8T         -    32%    43%
cache      -      -      -         -      -      -
  l2arc   145G  12.5G   132G         -     0%     8%

zfs list time_machine -o compress,compressratio,refcompressratio,usedbychildren,usedbydataset,usedbysnapshots
COMPRESS  RATIO  REFRATIO  USEDCHILD  USEDDS  USEDSNAP
  gzip-7  3.01x     2.64x      11.7G   12.6T     12.5T

Статистика после заполнения 300-го дня:

df -i /time_machine
Filesystem          Inodes     IUsed       IFree IUse% Mounted on
time_machine   59961056654 114028446 59847028208    1% /time_machine

df -B MB /time_machine
Filesystem     1MB-blocks       Used  Available Use% Mounted on
time_machine   44739499MB 14097821MB 30641679MB  32% /time_machine

zpool list -v
NAME   SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
time_machine    58T  28.3T  29.7T         -    36%    48%  1.00x  ONLINE  -
  dm-name-x136all36-share    58T  28.3T  29.7T         -    36%    48%
cache      -      -      -         -      -      -
  l2arc   145G  13.7G   131G         -     0%     9%

zfs list time_machine -o compress,compressratio,refcompressratio,usedbychildren,usedbydataset,usedbysnapshots
COMPRESS  RATIO  REFRATIO  USEDCHILD  USEDDS  USEDSNAP
  gzip-7  3.05x     2.56x      14.6G   12.8T     15.5T

Статистика после заполнения 365-го дня:

df -i /time_machine
Filesystem          Inodes     IUsed       IFree IUse% Mounted on
time_machine   52350051528 118689584 52231361944    1% /time_machine

df -B MB /time_machine
Filesystem     1MB-blocks       Used  Available Use% Mounted on
time_machine   42062128MB 15319671MB 26742458MB  37% /time_machine

zpool list -v
NAME   SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
time_machine    58T  31.9T  26.1T         -    41%    54%  1.00x  ONLINE  -
  dm-name-x136all36-share    58T  31.9T  26.1T         -    41%    54%
cache      -      -      -         -      -      -
  l2arc   145G  14.7G   130G         -     0%    10%

zfs list time_machine -o compress,compressratio,refcompressratio,usedbychildren,usedbydataset,usedbysnapshots
COMPRESS  RATIO  REFRATIO  USEDCHILD  USEDDS  USEDSNAP
  gzip-7  3.05x     2.54x      17.1G   13.9T     17.9T

Статистика после заполнения 512-го дня:

df -i /time_machine
Filesystem          Inodes     IUsed       IFree IUse% Mounted on
time_machine   31871545123 123555195 31747989928    1% /time_machine

df -B MB /time_machine
Filesystem     1MB-blocks       Used  Available Use% Mounted on
time_machine   31505671MB 15250700MB 16254971MB  49% /time_machine

zpool list -v
NAME   SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
time_machine    58T  41.4T  16.6T         -    54%    71%  1.00x  ONLINE  -
  dm-name-x136all36-share    58T  41.4T  16.6T         -    54%    71%
cache      -      -      -         -      -      -
  l2arc   145G  16.0G   129G         -     0%    11%

zfs list time_machine -o compress,compressratio,refcompressratio,usedbychildren,usedbydataset,usedbysnapshots
COMPRESS  RATIO  REFRATIO  USEDCHILD  USEDDS  USEDSNAP
  gzip-7  3.10x     2.58x      25.2G   13.9T     27.5T

Предварительный итог: zfs без дедупликации ненастроенный со сжатием gzip-7, без файлов копирования файлов размером более 100ГБ, rsync в режиме --inplace, с 20140801 по 20151217 (503 дня)

Несколько часов что-то делал без видимого результата (не было ввода/вывода, rngd + txg_sync + z_null_iss + txg_quiesce + rsync). Убийство rsync не помогло, второй rsync не убился. Неожиданно помогла попытка размонтировать файловую систему ("zfs unmount time_machine", не "umount /time_machine"): размонтировать отказался, но "плохое место" проскочил (а может просто совпало? дважды, но на третий раз пришлось убить rsync, размонтировать, смонтировать и перезапустить задачи вручную). На следующем витке не повторилось, т.е. проблема возникает из-за сочетания обстоятельств.

Выделенный сервер архива с дедупликацией

Выделенный сервер архива с дедупликацией: 12 ядер по 3.5GHz, 80 ГиБ ОП, сеть 1Gbps, локальный массив среднего размера (LSI MEGARAID RAID-6 of 15 HDD SFF 1800GB 10k rpm).

Параметры модуля spl (/etc/modprobe.d/spl.conf): отсутствуют.

Параметры модуля zfs (/etc/modprobe.d/zfs.conf): отсутствуют.

Создание пула (надо было xattr=sa и без utf8only, выше gzip-8 не тянет, вместе с relatime надо включать atime, checksum лучше делать sha256):

zpool create -f -m /time_machine -o ashift=12 \
-d -o feature@async_destroy=enabled -o feature@empty_bpobj=enabled -o feature@lz4_compress=enabled -o feature@spacemap_histogram=enabled -o feature@extensible_dataset=enabled -o feature@bookmarks=enabled -o feature@enabled_txg=enabled -o feature@embedded_data=enabled -o feature@large_blocks=enabled \
-O utf8only=on \
-O compression=gzip-8 \
-O atime=off -O relatime=on \
-O acltype=posixacl -O xattr=on \
-O dedup=on \
-O redundant_metadata=most \
-O sync=disabled -O logbias=throughput \
-O snapdir=visible \
-O recordsize=1048576 \
tm_small scsi-3600605b008ca05c01fc0c51340366923 cache /dev/system/l2arc

Наполнение архива с помощью rsync (40 потоков, "--max-size=100GB -vas --inplace --numeric-ids --ignore-errors --delete").

Статистика блоков (в самом начале):

zdb -L -b tm_small

3.74T completed (1014MB/s) estimated time remaining: 46259hr 54min 49sec        4294967241sec
        bp count:       113034474
        ganged count:           0
        bp logical:    9842270394880      avg:  87073
        bp physical:   3968674195968      avg:  35110     compression:   2.48
        bp allocated:  4115137540096      avg:  36406     compression:   2.39
        bp deduped:    953664348160    ref>1: 8947494   deduplication:   1.23
        SPA allocated: 3161473191936     used: 13.53%

        additional, non-pointer bps of type 0:    5667515
        Dittoed blocks on same vdev: 5681636

Статистика после заполнения первого дня (большая фрагментация свободного пространства):

df -i /time_machine
Filesystem          Inodes    IUsed       IFree IUse% Mounted on
tm_small       26910345944 76876211 26833469733    1% /time_machine

df -B G /time_machine
Filesystem     1G-blocks   Used Available Use% Mounted on
tm_small          23363G 10568G    12796G  46% /time_machine

zpool list -v
NAME   SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
tm_small  21.2T  8.02T  13.2T         -    44%    37%  1.30x  ONLINE  -
  scsi-3600605b008ca05c01fc0c51340366923  21.2T  8.02T  13.2T         -    44%    37%
cache      -      -      -         -      -      -
  l2arc   300G   202G  97.8G         -     0%    67%

zfs  list -o compress,compressratio,refcompressratio,usedbychildren,usedbydataset,usedbyrefreservation,usedbysnapshots
COMPRESS  RATIO  REFRATIO  USEDCHILD  USEDDS  USEDREFRESERV  USEDSNAP
  gzip-8  2.56x     2.56x      79.4G   10.3T              0         0

zfs list
NAME       USED  AVAIL  REFER  MOUNTPOINT
tm_small  10.4T  12.5T  10.3T  /time_machine

Статистика после заполнения 6-го дня:

df -i /time_machine
Filesystem          Inodes    IUsed       IFree IUse% Mounted on
tm_small       25355323516 77948660 25277374856    1% /time_machine

df -B G /time_machine
Filesystem     1G-blocks   Used Available Use% Mounted on
tm_small          23334G 11281G    12054G  49% /time_machine

zpool list -v
NAME   SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
tm_small  21.2T  8.74T  12.5T         -    48%    41%  1.29x  ONLINE  -
  scsi-3600605b008ca05c01fc0c51340366923  21.2T  8.74T  12.5T         -    48%    41%
cache      -      -      -         -      -      -
  l2arc   300G   143G   157G         -     0%    47%

zfs  list -o compress,compressratio,refcompressratio,usedbychildren,usedbydataset,usedbyrefreservation,usedbysnapshots tm_small
COMPRESS  RATIO  REFRATIO  USEDCHILD  USEDDS  USEDREFRESERV  USEDSNAP
  gzip-8  2.66x     2.63x      91.8G   11.0T              0      157G

zfs list
NAME                USED  AVAIL  REFER  MOUNTPOINT
tm_small           11.3T  11.8T  11.0T  /time_machine
tm_small@20140801  15.8G      -  10.3T  -
tm_small@20140802  3.50G      -  10.9T  -
tm_small@20140803  2.44G      -  10.9T  -
tm_small@20140804   623M      -  10.9T  -
tm_small@20140805  43.1G      -  11.1T  -

Статистика дедупликации:

zpool status -D

dedup: DDT entries 188783133, size 458 on disk, 148 in core

bucket              allocated                       referenced
______   ______________________________   ______________________________
refcnt   blocks   LSIZE   PSIZE   DSIZE   blocks   LSIZE   PSIZE   DSIZE
------   ------   -----   -----   -----   ------   -----   -----   -----
     1     148M   17.3T   7.61T   7.63T     148M   17.3T   7.61T   7.63T
     2    25.5M   2.89T    954G    958G    55.6M   6.26T   2.01T   2.02T
     4    4.95M    528G    144G    145G    23.7M   2.45T    669G    676G
     8    1.21M    110G   25.2G   25.9G    12.4M   1.11T    256G    262G
    16     437K   37.7G   8.54G   8.77G    9.26M    822G    188G    192G
    32     141K   11.5G   2.18G   2.27G    5.90M    487G   92.0G   96.0G
    64    45.2K   2.69G    600M    644M    3.80M    227G   50.6G   54.4G
   128    19.8K    841M    282M    304M    3.37M    144G   47.9G   51.6G
   256    14.7K    744M    456M    471M    4.94M    247G    153G    158G
   512    5.57K    198M   57.3M   62.9M    3.68M    128G   34.6G   38.5G
    1K    1.93K    127M   35.7M   37.4M    2.44M    151G   43.3G   45.5G
    2K      584   44.5M   21.0M   21.5M    1.84M    156G   77.8G   79.3G
    4K      291   3.59M    370K   1.14M    1.68M   19.1G   2.00G   6.73G
    8K       79   2.40M    148K    316K     935K   34.1G   1.87G   3.65G
   16K       35   1.65M     73K    140K     710K   28.6G   1.31G   2.77G
   32K       37   2.29M     98K    148K    1.68M    118G   4.80G   6.71G
   64K       10    337K   29.5K     40K     889K   28.2G   2.66G   3.47G
  128K       24   2.50M     82K     96K    4.65M    516G   16.4G   18.6G
  256K        4      2K      2K     16K    1.58M    811M    811M   6.34G
  512K        1     512     512      4K     649K    324M    324M   2.53G
    1M        1    128K      4K      4K    1.35M    173G   5.40G   5.40G
    2M        1     512     512      4K    2.76M   1.38G   1.38G   11.1G
 Total     180M   20.9T   8.72T   8.74T     291M   30.3T   11.2T   11.3T

Статистика после заполнения 33-го дня (чудовищная фрагментация свободного места):

df -i /time_machine
Filesystem          Inodes    IUsed       IFree IUse% Mounted on
tm_small       21932741784 79019953 21853721831    1% /time_machine

df -B MB /time_machine
Filesystem     1MB-blocks       Used  Available Use% Mounted on
tm_small       23833665MB 12644559MB 11189106MB  54% /time_machine

zpool list -v
NAME   SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
tm_small  21.2T  10.3T  10.9T         -    58%    48%  1.30x  ONLINE  -
  scsi-3600605b008ca05c01fc0c51340366923  21.2T  10.3T  10.9T         -    58%    48%
cache      -      -      -         -      -      -
  l2arc   300G   182G   118G         -     0%    60%

zfs list tm_small -o compress,compressratio,refcompressratio,usedbychildren,usedbydataset,usedbysnapshots
COMPRESS  RATIO  REFRATIO  USEDCHILD  USEDDS  USEDSNAP
  gzip-8  2.79x     2.66x       129G   11.5T     1.74T

zfs list|head -4;zfs list |tail -4
NAME                USED  AVAIL  REFER  MOUNTPOINT
tm_small           13.4T  10.2T  11.5T  /time_machine
tm_small@20140801  15.8G      -  10.3T  -
tm_small@20140802  3.50G      -  10.9T  -
tm_small@20140831   174M      -  11.5T  -
tm_small@20140901  2.74G      -  11.5T  -
tm_small@20140902  20.9G      -  11.5T  -
tm_small@20140903   216M      -  11.5T  -

Тест прерван в пользу улучшенного варианта.

Выделенный сервер архива с дедупликацией настроенный

Выделенный сервер архива с дедупликацией: 12 ядер по 3.5GHz, 80 ГиБ ОП, сеть 1Gbps, локальный массив среднего размера (LSI MEGARAID RAID-6 of 15 HDD SFF 1800GB 10k rpm).

2048 в /proc/sys/kernel/random/read_wakeup_threshold (или "kernel.random.read_wakeup_threshold = 2048" в /etc/sysctl.conf).

Параметры модуля spl (/etc/modprobe.d/spl.conf): отсутствуют.

Параметры модуля zfs (/etc/modprobe.d/zfs.conf):

options zfs zfs_autoimport_disable=0
options zfs spa_asize_inflation=3 # нет зеркал/raid и никаких дополнительных копий, кроме метаданных (most)
#options zfs spa_slop_shift=6
options zfs metaslab_lba_weighting_enabled=0
options zfs zio_taskq_batch_pct=85 # больше не надо
options zfs_txg_timeout=30
options zfs zfs_nocacheflush=1
options zfs zfs_arc_max=60000000000
#options zfs zfs_arc_max=77309411328
#options zfs zfs_arc_meta_limit=?
options zfs zfs_arc_average_blocksize=32768 # можно 65536
#options zfs zfs_arc_lotsfree_percent=5
#options zfs zvol_inhibit_dev=1
#options zfs zfs_admin_snapshot=1

Создание пула (bin/zfsdedup.sh, вместе с relatime надо включать atime, checksum лучше делать sha256, составное LVM устройство в режиме RAID-0 разобрать):

zpool create -f -m /time_machine -o ashift=12 \
-d -o feature@async_destroy=enabled -o feature@empty_bpobj=enabled -o feature@lz4_compress=enabled -o feature@spacemap_histogram=enabled -o feature@extensible_dataset=enabled -o feature@bookmarks=enabled -o feature@enabled_txg=enabled -o feature@embedded_data=enabled -o feature@large_blocks=enabled \
-O compression=gzip-8 \
-O atime=off -O relatime=off \
-O acltype=posixacl -O xattr=sa \
-O dedup=on \
-O redundant_metadata=most \
-O sync=disabled -O logbias=throughput \
-O snapdir=visible \
-O recordsize=1048576 \
-O secondarycache=metadata \
tm_small scsi-3600605b008ca05c01fc0c51340366923 cache /dev/system/l2arc

mkdir /time_machine/{colddata,raid,share4h,share4s,share4x,share5c,xeon01,xeon04}

Наполнение архива с помощью rsync (20 потоков, "--max-size=100GB -vas --inplace --numeric-ids --ignore-errors --delete").

Статистика после начального заполнения первого дня:

df -i /time_machine
Filesystem          Inodes    IUsed       IFree IUse% Mounted on
tm_small       27371887339 76877617 27295009722    1% /time_machine

df -B MB /time_machine
Filesystem     1MB-blocks       Used  Available Use% Mounted on
tm_small       24948903MB 10973859MB 13975045MB  44% /time_machine

zpool list -v
NAME   SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
tm_small  21.2T  7.81T  13.4T         -    30%    36%  1.28x  ONLINE  -
  scsi-3600605b008ca05c01fc0c51340366923  21.2T  7.81T  13.4T         -    30%    36%
cache      -      -      -         -      -      -
  l2arc   300G   240G  60.5G         -     0%    79%

zfs list tm_small -o compress,compressratio,refcompressratio,usedbychildren,usedbydataset,usedbysnapshots
COMPRESS  RATIO  REFRATIO  USEDCHILD  USEDDS  USEDSNAP
  gzip-8  2.70x     2.70x      19.0G   9.98T         0

zfs list|head -4;zfs list |tail -4
NAME       USED  AVAIL  REFER  MOUNTPOINT
tm_small  10.0T  12.7T  9.98T  /time_machine

Статистика дедупликации после начального заполнения первого дня:

zpool status -D
 dedup: DDT entries 34317141, size 481 on disk, 155 in core

bucket              allocated                       referenced
______   ______________________________   ______________________________
refcnt   blocks   LSIZE   PSIZE   DSIZE   blocks   LSIZE   PSIZE   DSIZE
------   ------   -----   -----   -----   ------   -----   -----   -----
     1    25.6M   15.4T   6.80T   6.82T    25.6M   15.4T   6.80T   6.82T
     2    5.04M   2.38T    785G    789G    11.1M   5.15T   1.66T   1.66T
     4    1.37M    477G    125G    127G    6.72M   2.22T    582G    589G
     8     480K    104G   21.2G   21.8G    4.79M   1.05T    216G    222G
    16     179K   34.6G   7.16G   7.37G    3.77M    757G    158G    162G
    32    62.2K   10.2G   1.79G   1.88G    2.65M    433G   75.6G   79.5G
    64    28.6K   2.12G    507M    551M    2.45M    187G   43.1G   46.9G
   128    14.7K    762M    213M    233M    2.53M    129G   34.2G   37.8G
   256    9.93K    731M    447M    462M    3.39M    245G    149G    155G
   512    4.51K    194M   53.6M   59.1M    2.98M    123G   31.9G   35.7G
    1K    1.06K    119M   32.7M   34.3M    1.41M    152G   39.5G   41.7G
    2K      279   48.2M   20.3M   20.9M     800K    159G   75.5G   77.0G
    4K      283   18.4M    344K   1.11M    1.64M    107G   1.89G   6.59G
    8K       59   2.13M     76K    236K     660K   25.9G    886M   2.58G
   16K       35   12.0M   69.5K    140K     712K    219G   1.28G   2.78G
   32K       25   7.04M   53.5K    100K     997K    250G   2.10G   3.89G
   64K        9   1.08M   25.5K     36K     848K    133G   2.50G   3.31G
  128K        5   2.50K   2.50K     20K     880K    440M    440M   3.44G
  256K        3   1.50K   1.50K     12K    1.31M    670M    670M   5.24G
  512K        1     512     512      4K     642K    321M    321M   2.51G
    2M        1     512     512      4K    2.72M   1.36G   1.36G   10.9G
 Total    32.7M   18.3T   7.72T   7.74T    78.5M   26.6T   9.84T   9.93T

Статистика блоков после начального заполнения первого дня:

zdb -L -b tm_small

Traversing all blocks ...

10.1T completed (2399MB/s) estimated time remaining: 4294617589hr 00min 4294967252sec
        bp count:       103252048
        ganged count:           0
        bp logical:    29739547317760      avg: 288028
        bp physical:   10967514414592      avg: 106220     compression:   2.71
        bp allocated:  11117812854784      avg: 107676     compression:   2.67
        bp deduped:    2427436392448    ref>1: 7569740   deduplication:   1.22
        SPA allocated: 8690376462336     used: 37.19%

        additional, non-pointer bps of type 0:   11884845
        Dittoed blocks on same vdev: 7125171

Статистика после заполнения 33-го дня (по сравнению с первым вариантом: дедупликация меньше и сжатие больше - места на 3% меньше, фрагментация значительно лучше):

df -i /time_machine
Filesystem          Inodes    IUsed       IFree IUse% Mounted on
tm_small       22709829244 79029191 22630800053    1% /time_machine

df -B MB /time_machine
Filesystem     1MB-blocks       Used  Available Use% Mounted on
tm_small       23801210MB 12214241MB 11586970MB  52% /time_machine

zpool list -v
NAME   SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
tm_small  21.2T  9.96T  11.3T         -    38%    46%  1.28x  ONLINE  -
  scsi-3600605b008ca05c01fc0c51340366923  21.2T  9.96T  11.3T         -    38%    46%
cache      -      -      -         -      -      -
  l2arc   300G   200G  99.7G         -     0%    66%

zfs list tm_small -o compress,compressratio,refcompressratio,usedbychildren,usedbydataset,usedbysnapshots
COMPRESS  RATIO  REFRATIO  USEDCHILD  USEDDS  USEDSNAP
  gzip-8  2.95x     2.79x      23.3G   11.1T     1.63T

zfs list
NAME       USED  AVAIL  REFER  MOUNTPOINT
tm_small  12.8T  10.5T  11.1T  /time_machine

zfs list -t snapshot|head -4;zfs list -t snapshot |tail -4
NAME                USED  AVAIL  REFER  MOUNTPOINT
tm_small@20140801  15.1G      -  9.98T  -
tm_small@20140802  3.15G      -  10.5T  -
tm_small@20140803  2.24G      -  10.6T  -
tm_small@20140831   164M      -  11.1T  -
tm_small@20140901  2.70G      -  11.1T  -
tm_small@20140902  19.4G      -  11.1T  -
tm_small@20140903  37.2M      -  11.1T  -

Статистика дедупликации после заполнения 33-го дня:

zpool status -D

 dedup: DDT entries 43561002, size 440 on disk, 142 in core

bucket              allocated                       referenced
______   ______________________________   ______________________________
refcnt   blocks   LSIZE   PSIZE   DSIZE   blocks   LSIZE   PSIZE   DSIZE
------   ------   -----   -----   -----   ------   -----   -----   -----
     1    32.8M   21.5T   8.63T   8.65T    32.8M   21.5T   8.63T   8.65T
     2    6.26M   3.47T   1.04T   1.04T    13.8M   7.61T   2.25T   2.26T
     4    1.62M    663G    158G    160G    7.99M   3.09T    742G    750G
     8     544K    136G   26.7G   27.4G    5.44M   1.36T    275G    282G
    16     206K   50.8G   9.77G   10.0G    4.32M   1.07T    212G    218G
    32    69.9K   13.3G   2.13G   2.23G    2.94M    562G   89.6G   93.9G
    64    31.7K   3.22G    578M    623M    2.64M    261G   46.5G   50.3G
   128    16.2K   1.07G    273M    295M    2.85M    185G   46.1G   50.0G
   256    10.2K    838M    435M    450M    3.54M    288G    156G    161G
   512    5.76K    238M   75.0M   82.5M    3.84M    157G   46.3G   51.4G
    1K    1.22K    125M   34.5M   36.4M    1.62M    162G   42.7G   45.2G
    2K      317   49.0M   20.4M   21.0M     892K    161G   75.7G   77.3G
    4K      282   18.6M    383K   1.16M    1.70M    110G   2.08G   7.03G
    8K       83   2.21M    134K    332K     905K   27.9G   1.45G   3.53G
   16K       32   12.0M   71.5K    128K     678K    265G   1.49G   2.65G
   32K       30   7.04M     56K    120K    1.26M    300G   2.47G   5.04G
   64K        7     77K   17.5K     28K     641K   8.68G   1.65G   2.50G
  128K        6   1.01M     10K     24K    1.03M    234G   1.78G   4.12G
  256K        3   1.50K   1.50K     12K    1.17M    601M    601M   4.69G
  512K        2      1K      1K      8K    1.19M    608M    608M   4.75G
    2M        1     512     512      4K    2.87M   1.43G   1.43G   11.5G
 Total    41.5M   25.8T   9.86T   9.88T    94.1M   37.3T   12.6T   12.7T

Статистика блоков после заполнения 33-го дня:

zdb -L -b tm_small

Traversing all blocks ...

12.8T completed (2008MB/s) estimated time remaining: 46981hr 05min 41sec        4294967256sec
        bp count:       121664603
        ganged count:           0
        bp logical:    41122740267008      avg: 338000
        bp physical:   13873447785984      avg: 114030     compression:   2.96
        bp allocated:  14041409785856      avg: 115410     compression:   2.93
        bp deduped:    3083509776384    ref>1: 9173591   deduplication:   1.22
        SPA allocated: 10957900009472     used: 46.90%

        additional, non-pointer bps of type 0:   12900459
        Dittoed blocks on same vdev: 8499054

Статистика после заполнения 105-го дня (фрагментация свободного места ещё терпимая, коэффициент сжатия поражает):

df -i /time_machine
Filesystem          Inodes    IUsed       IFree IUse% Mounted on
tm_small       17950274179 83943603 17866330576    1% /time_machine

df -B MB /time_machine
Filesystem     1MB-blocks       Used  Available Use% Mounted on
tm_small       22458963MB 13311402MB 9147562MB  60% /time_machine

zpool list -v
NAME   SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
tm_small  21.2T  12.2T  9.09T         -    47%    57%  1.28x  ONLINE  -
  scsi-3600605b008ca05c01fc0c51340366923  21.2T  12.2T  9.09T         -    47%    57%
cache      -      -      -         -      -      -
  l2arc   300G   202G  97.9G         -     0%    67%

zfs list tm_small -o compress,compressratio,refcompressratio,usedbychildren,usedbydataset,usedbysnapshots
COMPRESS  RATIO  REFRATIO  USEDCHILD  USEDDS  USEDSNAP
  gzip-8  3.10x     2.81x      33.1G   12.1T     3.47T

zfs list
NAME       USED  AVAIL  REFER  MOUNTPOINT
tm_small  15.6T  8.32T  12.1T  /time_machine

Тестирование чтения привычным tarnull_all_common.sh базового снимка в момент 120 снимка:

Тестирование чтения привычным tarnull_all_common.sh снимка 120 (20141130):

Передача накопленного (gzip-1 для скорости - 1.23 TB/час - 342 MB/s, постепенно снижается до 300 MB/s):

# осторожно с памятью!
zfs set primarycache=metadata tm_small
zfs set secondarycache=metadata tm_small
zpool remove tm_small /dev/system/l2arc

zpool create -f -m /tm_tiny -o ashift=12 \
-d -o feature@async_destroy=enabled -o feature@empty_bpobj=enabled -o feature@lz4_compress=enabled -o feature@spacemap_histogram=enabled -o feature@extensible_dataset=enabled -o feature@bookmarks=enabled -o feature@enabled_txg=enabled -o feature@embedded_data=enabled -o feature@large_blocks=enabled \
-O compression=gzip-1 \
-O atime=off -O relatime=off \
-O acltype=posixacl -O xattr=sa \
-O dedup=on \
-O redundant_metadata=most \
-O sync=disabled -O logbias=throughput \
-O snapdir=visible \
-O recordsize=1048576 \
-O secondarycache=metadata \
tm_tiny wwn-1 wwn-2 cache /dev/system/l2arc

zfs set primarycache=metadata tm_tiny
zfs set secondarycache=metadata tm_tiny

zfs send -R -Le -v tm_small@20140815 | zfs receive -vd -F tm_tiny

send from @ to tm_small@20140801 estimated size is 26.6T
send from @20140801 to tm_small@20140802 estimated size is 2.22T
...
send from @20140814 to tm_small@20140815 estimated size is 368G
total estimated size is 33.3T

receiving full stream of tm_small@20140801 into tm_tiny@20140801
TIME        SENT   SNAPSHOT
22:42:31    614K   tm_small@20140801 # исходных до сжатия?
...

zpool list -v

NAME   SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
tm_small  21.2T  13.2T  8.04T         -    51%    62%  1.28x  ONLINE  -
  scsi-3600605b008ca05c01fc0c51340366923  21.2T  13.2T  8.04T         -    51%    62%
tm_tiny  9.88T  4.85T  5.03T         -    43%    49%  1.33x  ONLINE  -
  wwn-0x600605b008ca0500ff00978d08a70a6a  4.91T  2.42T  2.49T         -    42%    49%
  wwn-0x600605b008ca052020111fe9d78370c6  4.97T  2.43T  2.54T         -    44%    48%
cache      -      -      -         -      -      -
  l2arc   300G  6.09G   294G         -     0%     2%

zfs list tm_small tm_tiny -o name,compress,compressratio,refcompressratio,usedbychildren,usedbydataset,usedbysnapshots

NAME      COMPRESS  RATIO  REFRATIO  USEDCHILD  USEDDS  USEDSNAP
tm_small    gzip-8  3.12x     2.83x      37.5G   11.8T     5.10T
tm_tiny     gzip-1  2.40x     1.00x      6.46T     96K         0

zfs list

NAME       USED  AVAIL  REFER  MOUNTPOINT
tm_small  16.9T  7.26T  11.8T  /time_machine
tm_tiny   6.46T  4.67T    96K  /tm_tiny

В процессе тестирования попытался подключить ("zpool add -o ashift=12 tm_tiny dm-name-mpaths209") старенький iSCSI SAN HP StorageWorks MSA 2012i (при сжатии lz4 не хватило места), получил завал по записи и (igb - драйвер сетевой карты):

Jan 25 03:27:03 x142 kernel: BUG: Bad page state in process swapper/4  pfn:117940c
Jan 25 03:27:03 x142 kernel: page:ffffea0045e50300 count:0 mapcount:-1 mapping:          (null) index:0x0
Jan 25 03:27:03 x142 kernel: page flags: 0x6fffff00008000(tail)
Jan 25 03:27:03 x142 kernel: page dumped because: nonzero mapcount
Jan 25 03:27:03 x142 kernel: Call Trace:
Jan 25 03:27:03 x142 kernel:   [] dump_stack+0x19/0x1b
Jan 25 03:27:03 x142 kernel: [] bad_page.part.59+0xdf/0xfc
Jan 25 03:27:03 x142 kernel: [] free_pages_prepare+0x16d/0x190
Jan 25 03:27:03 x142 kernel: [] free_compound_page+0x29/0x40
Jan 25 03:27:03 x142 kernel: [] __put_compound_page+0x1f/0x30
Jan 25 03:27:03 x142 kernel: [] put_compound_page+0x145/0x170 
...
Jan 25 03:32:15 x142 kernel: BUG: Bad page state in process z_rd_int_6  pfn:faca0c
Jan 25 03:32:15 x142 kernel: page:ffffea003eb28300 count:0 mapcount:-1 mapping:          (null) index:0x0
Jan 25 03:32:15 x142 kernel: page flags: 0x6fffff00008000(tail)
Jan 25 03:32:15 x142 kernel: page dumped because: nonzero mapcount
Jan 25 03:32:15 x142 kernel:   [] dump_stack+0x19/0x1b
Jan 25 03:32:15 x142 kernel: [] bad_page.part.59+0xdf/0xfc
Jan 25 03:32:15 x142 kernel: [] free_pages_prepare+0x16d/0x190
Jan 25 03:32:15 x142 kernel: [] free_compound_page+0x29/0x40
Jan 25 03:32:15 x142 kernel: [] __put_compound_page+0x1f/0x30
Jan 25 03:32:15 x142 kernel: [] put_compound_page+0x145/0x170
Jan 25 03:32:15 x142 kernel: [] put_page+0x2c/0x40
Jan 25 03:32:15 x142 kernel: [] skb_release_data+0x88/0x110
Jan 25 03:32:15 x142 kernel: [] skb_release_all+0x24/0x30
Jan 25 03:32:15 x142 kernel: [] consume_skb+0x2c/0x80
Jan 25 03:32:15 x142 kernel: [] __dev_kfree_skb_any+0x3d/0x50
Jan 25 03:32:15 x142 kernel: [] igb_poll+0xe6/0x770 [igb] 
При этом счётчик переданных байт застыл на 4.33TB, mpaths209 имеет 100% загрузки на случайной записи, "zpool destroy tm_tiny" не остановил случайную запись.

Оказалось, что приёмник нельзя трогать до окончания передачи. Запустил заново с gzip-2 (примерно 1 ТБ/час или 293 МБ/сек).

zfs send -R -Le -v tm_small@20140811 | zfs receive -vd -F tm_tiny
send from @ to tm_small@20140801 estimated size is 26.6T
send from @20140801 to tm_small@20140802 estimated size is 2.22T
send from @20140802 to tm_small@20140803 estimated size is 176G
send from @20140803 to tm_small@20140804 estimated size is 72.9G
send from @20140804 to tm_small@20140805 estimated size is 742G
send from @20140805 to tm_small@20140806 estimated size is 295G
send from @20140806 to tm_small@20140807 estimated size is 204G
send from @20140807 to tm_small@20140808 estimated size is 387G
send from @20140808 to tm_small@20140809 estimated size is 920G
send from @20140809 to tm_small@20140810 estimated size is 47.3G
send from @20140810 to tm_small@20140811 estimated size is 50.6G
total estimated size is 31.7T
...
zfs send -Le -v  -I tm_small@20140811 tm_small@20140813 | zfs receive -vd -F tm_tiny
send from @20140811 to tm_small@20140812 estimated size is 238G
send from @20140812 to tm_small@20140813 estimated size is 725G
total estimated size is 963G
would receive incremental stream of tm_small@20140812 into tm_tiny@20140812
TIME        SENT   SNAPSHOT
16:51:12   1013M   tm_small@20140812
...
received 725GB stream in 2971 seconds (250MB/sec)

zpool list -v
NAME   SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
tm_small  21.2T  13.2T  8.04T         -    51%    62%  1.28x  ONLINE  -
  scsi-3600605b008ca05c01fc0c51340366923  21.2T  13.2T  8.04T         -    51%    62%
tm_tiny  9.88T  9.43T   456G         -    81%    95%  1.28x  ONLINE  -
  wwn-0x600605b008ca0500ff00978d08a70a6a  4.91T  4.69T   220G         -    83%    95%
  wwn-0x600605b008ca052020111fe9d78370c6  4.97T  4.74T   236G         -    80%    95%
cache      -      -      -         -      -      -
  l2arc   300G  8.73G   291G         -     0%     2%

zfs list tm_small tm_tiny -o name,used,avail,refer,compress,compressratio,refcompressratio,usedbychildren,usedbydataset,usedbysnapshots
NAME       USED  AVAIL  REFER  COMPRESS  RATIO  REFRATIO  USEDCHILD  USEDDS  USEDSNAP
tm_small  16.9T  7.65T  11.8T    gzip-8  3.12x     2.83x      37.5G   11.8T     5.10T
tm_tiny   12.1T   255G  11.3T    gzip-2  2.72x     2.67x      20.2G   11.3T      808G

zfs send -Le -v  -I tm_small@20140813 tm_small@20140814 | zfs receive  -vd -F tm_tiny
...
received 306GB stream in 1667 seconds (188MB/sec)

zfs send -Le -v  -I tm_small@20140814 tm_small@20140815 | zfs receive  -vd -F tm_tiny
send from @20140814 to tm_small@20140815 estimated size is 368G
total estimated size is 368G
receiving incremental stream of tm_small@20140815 into tm_tiny@20140815
...
received 368GB stream in 1277 seconds (295MB/sec)

zfs send -Le -v  -I tm_small@20140815 tm_small@20140816 | zfs receive  -vd -F tm_tiny
send from @20140815 to tm_small@20140816 estimated size is 560G
total estimated size is 560G
receiving incremental stream of tm_small@20140816 into tm_tiny@20140816
...
21:48:17    492G   tm_small@20140816
cannot receive incremental stream: out of space
warning: cannot send 'tm_small@20140816': Broken pipe

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

Попробовал писать в переполненный пул

NAME   SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
tm_tiny  9.88T  9.56T   326G         -    71%    96%  1.28x  ONLINE  -
  wwn-0x600605b008ca0500ff00978d08a70a6a  4.91T  4.75T   157G         -    73%    96%
  wwn-0x600605b008ca052020111fe9d78370c6  4.97T  4.80T   170G         -    70%    96%

NAME       USED  AVAIL  REFER  COMPRESS  RATIO  REFRATIO  USEDCHILD  USEDDS  USEDSNAP
tm_tiny   12.3T      0  11.4T    gzip-2  2.72x     2.68x      42.3G   11.4T      799G

dd if=/dev/sda bs=1k of=/tm_tiny/share4h/test
^C

не пишет и не снимается

ls -ld /tm_tiny/share4h
^C^C

kill -9 не помогает

zfs umount -f /tm_tiny
umount: /tm_tiny: target is busy.

отвисла, когда прекратил активную работу с другим пулом 

На одном из тестовых серверов (на котором меньше ОП - 64ГиБ, но больше пул - 64ТБ) проявилась проблема - жёсткая нехватка памяти (80% в cache), arc_reclaim потребляет 100% CPU, но не успевает освободить (фрагментированность?), попытки понять и попбороть:

В порыве борьбы за память: metadata в primarycache и secondarycache. Добавил ещё 1 виртуальный диск.

Статистика после заполнения 215-го дня:

df -i /time_machine
Filesystem          Inodes    IUsed       IFree IUse% Mounted on
tm_small       17584992388 106959602 17478032786    1% /time_machine

df -B MB /time_machine
Filesystem     1MB-blocks       Used  Available Use% Mounted on
tm_small       22770856MB 13822104MB 8948753MB  61% /time_machine

zpool list -v
tm_small  26.2T  17.1T  9.15T         -    52%    65%  1.36x  ONLINE  -
  scsi-3600605b008ca05c01fc0c51340366923  21.2T  17.0T  4.22T         -    65%    80%
  wwn-0x600605b008ca052020111fe9d78370c6  4.97T  37.2G  4.93T         -     0%     0%
cache      -      -      -         -      -      -
  l2arc   300G  14.2G   286G         -     0%     4%

zfs list tm_small -o name,used,avail,refer,compress,compressratio,refcompressratio,usedbychildren,usedbydataset,usedbysnapshots
NAME       USED  AVAIL  REFER  COMPRESS  RATIO  REFRATIO  USEDCHILD  USEDDS  USEDSNAP
tm_small  23.2T  8.14T  12.6T    gzip-8  3.19x     2.82x      51.7G   12.6T     10.6T

Статистика после заполнения 301-го дня:

df -i /time_machine
Filesystem          Inodes    IUsed       IFree IUse% Mounted on
tm_small       20124719802 114330347 20010389455    1% /time_machine

df -B MB /time_machine
Filesystem     1MB-blocks       Used  Available Use% Mounted on
tm_small       23955499MB 13710181MB 10245319MB  58% /time_machine

zpool list -v
tm_small  30.3T  19.8T  10.5T         -    54%    65%  1.37x  ONLINE  -
  scsi-3600605b008ca05c01fc0c51340366923  21.2T  18.0T  3.22T         -    69%    84%
  wwn-0x600605b008ca052020111fe9d78370c6  4.97T  1.16T  3.81T         -    25%    23%
  wwn-0x600605b008ca0500202630e6fda1c4eb  4.06T   607G  3.47T         -    13%    14%
cache      -      -      -         -      -      -
  l2arc   300G  19.2G   281G         -     0%     6%

zfs list tm_small -o name,used,avail,refer,compress,compressratio,refcompressratio,usedbychildren,usedbydataset,usedbysnapshots
NAME       USED  AVAIL  REFER  COMPRESS  RATIO  REFRATIO  USEDCHILD  USEDDS  USEDSNAP
tm_small  27.2T  9.32T  12.5T    gzip-8  3.26x     2.70x      63.3G   12.5T     14.6T

Статистика после заполнения 361-го дня:

df -i /time_machine
Filesystem          Inodes    IUsed       IFree IUse% Mounted on
tm_small       15406945432 118602991 15288342441    1% /time_machine

df -B MB /time_machine
Filesystem     1MB-blocks       Used  Available Use% Mounted on
tm_small       22466955MB 14639324MB 7827631MB  66% /time_machine

zpool list -v
tm_small  30.3T  22.0T  8.32T         -    60%    72%  1.37x  ONLINE  -
  scsi-3600605b008ca05c01fc0c51340366923  21.2T  18.7T  2.52T         -    71%    88%
  wwn-0x600605b008ca052020111fe9d78370c6  4.97T  1.92T  3.05T         -    41%    38%
  wwn-0x600605b008ca0500202630e6fda1c4eb  4.06T  1.31T  2.75T         -    30%    32%
cache      -      -      -         -      -      -
  l2arc   300G  22.1G   278G         -     0%     7%

zfs list tm_small -o name,used,avail,refer,compress,compressratio,refcompressratio,usedbychildren,usedbydataset,usedbysnapshots
NAME       USED  AVAIL  REFER  COMPRESS  RATIO  REFRATIO  USEDCHILD  USEDDS  USEDSNAP
tm_small  30.1T  7.12T  13.3T    gzip-8  3.27x     2.69x      74.0G   13.3T     16.7T

Статистика после заполнения 518-го дня (место кончилось):

zpool list -v
NAME   SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
tm_small  30.3T  28.9T  1.35T         -    59%    95%  1.37x  ONLINE  -
  scsi-3600605b008ca05c01fc0c51340366923  21.2T  20.8T   445G         -    56%    97%
  wwn-0x600605b008ca052020111fe9d78370c6  4.97T  4.44T   538G         -    69%    89%
  wwn-0x600605b008ca0500202630e6fda1c4eb  4.06T  3.67T   405G         -    67%    90%
cache      -      -      -         -      -      -
  l2arc   300G  26.7G   273G         -     0%     8%

zfs list tm_small -o name,used,avail,refer,compress,compressratio,refcompressratio,usedbychildren,usedbydataset,usedbysnapshots
NAME       USED  AVAIL  REFER  COMPRESS  RATIO  REFRATIO  USEDCHILD  USEDDS  USEDSNAP
tm_small  39.7T  74.5G  13.9T    gzip-8  3.33x     2.75x      86.1G   13.9T     25.7T

Статистика блоков после заполнения 518-го дня (7 часов):

zdb -L -bb tm_small
        bp count:       403056102
        ganged count:           0
        bp logical:    143683750113792      avg: 356485
        bp physical:   42932481053696      avg: 106517     compression:   3.35
        bp allocated:  43624229873152      avg: 108233     compression:   3.29
        bp deduped:    11819060480512    ref>1: 32743371   deduplication:   1.27
        SPA allocated: 31805169392640     used: 95.53%

        additional, non-pointer bps of type 0:   34730385
        Dittoed blocks on same vdev: 15595207

Blocks  LSIZE   PSIZE   ASIZE     avg    comp   %Total  Type
  284K  34.7G   8.09G   25.1G   90.5K    4.29     0.06  bpobj
 17.4M   278G   56.3G    137G   7.92K    4.94     0.34  DMU dnode
  317M   130T   39.0T   39.4T    127K    3.34    99.26  ZFS plain file
 43.4M  45.8G   12.3G   77.3G   1.78K    3.74     0.19  ZFS directory
 5.45M  21.8G   14.2G   57.8G   10.6K    1.54     0.14  DDT ZAP algorithm

Статистика дедупликации после заполнения 518-го дня (быстро)

zdb -L -DD tm_small
DDT-sha256-zap-duplicate: 32743371 entries, size 414 on disk, 150 in core
DDT-sha256-zap-unique: 110802556 entries, size 437 on disk, 160 in core

DDT histogram (aggregated over all DDTs):

bucket              allocated                       referenced
______   ______________________________   ______________________________
refcnt   blocks   LSIZE   PSIZE   DSIZE   blocks   LSIZE   PSIZE   DSIZE
------   ------   -----   -----   -----   ------   -----   -----   -----
     1     106M   71.3T   23.5T   23.6T     106M   71.3T   23.5T   23.6T
     2    23.6M   13.2T   4.27T   4.30T    52.0M   28.8T   9.31T   9.37T
     4    4.97M   2.17T    602G    608G    24.3M   10.4T   2.78T   2.81T
     8    1.51M    508G    120G    122G    15.3M   4.99T   1.18T   1.21T
    16     640K    140G   28.9G   29.9G    13.3M   2.94T    625G    646G
    32     249K   60.5G   9.48G   9.90G    10.4M   2.55T    402G    420G
    64     101K   17.1G   2.07G   2.21G    8.75M   1.43T    176G    189G
   128    63.5K   10.7G   1020M   1.08G    11.0M   1.90T    186G    200G
   256    48.2K   4.20G    824M    881M    17.0M   1.47T    308G    329G
   512    17.4K   2.65G    354M    388M    12.8M   1.82T    252G    277G
    1K    7.69K    468M    112M    124M    10.1M    609G    149G    166G
    2K    1.56K    167M   36.8M   40.3M    4.12M    489G    120G    129G
    4K      353   7.22M   1.67M   2.57M    1.79M   40.9G   8.43G   13.1G
    8K      401   41.9M    590K   1.61M    4.59M    509G   6.45G   18.7G
   16K      128   14.3M    216K    506K    2.73M    324G   4.56G   10.8G
   32K       57   9.10M   72.5K    228K    2.49M    457G   3.27G   9.97G
   64K       21   41.5K     29K     84K    1.69M   3.20G   2.27G   6.75G
  128K       11    112K     16K     44K    1.92M   19.1G   2.96G   7.70G
  256K        5   1.00M      6K     20K    1.75M    259G   1.75G   6.98G
  512K        4      2K      2K     16K    2.78M   1.39G   1.39G   11.1G
    1M        2      1K      1K      8K    2.69M   1.35G   1.35G   10.8G
    4M        1     512     512      4K    4.96M   2.48G   2.48G   19.8G
 Total     137M   87.4T   28.5T   28.6T     312M    130T   38.9T   39.4T

dedup = 1.38, compress = 3.34, copies = 1.01, dedup * compress / copies = 4.55

Тестирование чтения привычным tarnull_all_common.sh базового снимка в момент 518 снимка (l2arc_noprefetch=1, zfs_prefetch_disable=0, primarycache=metadata, secondarycache=metadata - для чтения это оказалось плохо):

Тестирование чтения привычным tarnull_all_common.sh базового снимка в момент 518 снимка (l2arc_noprefetch=0, zfs_dedup_prefetch=1, primarycache=all, secondarycache=all)

Тестирование чтения привычным tarnull_all_common.sh последнего снимка (20151231) (l2arc_noprefetch=0, zfs_dedup_prefetch=1, primarycache=all, secondarycache=all, задействованы 3 vdev)

Итог тестирования компактности: zfs с дедупликацией настроенный со сжатием gzip-8, без копирования файлов размером более 100ГБ, rsync в режиме --inplace, с 1 августа 2014 по 31 декабря 2015 (518 день)

Передача по сети (предусмотреть - screen, iptables):

Измерение скорости send в /dev/null (разжимается перед передачей):

time zfs send -R -Le  tm_small@20151231 | dd bs=1024k > /dev/null # статистика zfs двоичная, dd - десятичная
send from @ to tm_small@20140801 estimated size is 26.6T
send from @20140801 to tm_small@20140802 estimated size is 2.22T
send from @20140802 to tm_small@20140803 estimated size is 176G
...
send from @20151230 to tm_small@20151231 estimated size is 163G
total estimated size is 130T

143709025174440 bytes (144 TB) copied, 139968 s, 1.0 GB/s

Измерение скорости send в /dev/null без разжимания (0.7.0-rc3, возврат на 0.6.9 прошёл без проблем)

time zfs send -R -Le -c tm_small@20151231 | dd bs=1024k > /dev/null # статистика zfs двоичная, dd - десятичная
full send of tm_small@20140801 estimated size is 9.86T
send from @20140801 to tm_small@20140802 estimated size is 590G
...
send from @20151230 to tm_small@20151231 estimated size is 33.9G
total estimated size is 39.0T

43369814706360 bytes (43 TB) copied, 92704.8 s, 468 MB/s

Реальная пересылка без разжимания:

# разведка
time zfs send -n -v -R -p -Le -c time_machine@20170326
full send of time_machine@20140901 estimated size is 11.1T
send from @20140901 to time_machine@20140902 estimated size is 49.0G
...
send from @20170325 to time_machine@20170326 estimated size is 12.7G
total estimated size is 82.0T

# оценка
time zfs send -R -p -Le -c time_machine@20170326 | dd bs=1024k > /dev/null # статистика zfs двоичная, dd - десятичная
670009514760 bytes (670 GB) copied, 1302.84 s, 514 MB/s

ncat -l порт | dd bs=1024k | zfs receive -vd -F time_machine
time zfs send -R -p -Le -c time_machine@20170326 | ncat хост порт

receiving incremental stream of time_machine@20170326 into time_machine@20170326
91080262204792 bytes (91 TB) copied, 371889 s, 245 MB/s

# накопившиеся за время пересылки остатки
zfs send -p  -Le -c -I time_machine@20170326  time_machine@20170331 | ncat хост порт

Сравнение сжатия на подмножестве share4x/[a-c]* 20160101-20160304 (~10% по файлам, объёму и времени):

В связи с проблемами в реализации дельта алгоритма в rsync в режиме "--inplace" попробовал отключить его ("--whole-file --inplace") и оценить разницу на небольшом подмножестве (share4x/a[a-l]*:20160101-20160131, 1.5TB), gzip-1, итог: в 1.5 раза быстрее, место примерно столько же за счёт увеличения коэффициента дедупликации ("--whole-file" отличается от "--whole-file --inplace"):

--inplace, 10 часов на изменения

   tm_tiny  dedupratio                  1.38x
   tm_tiny  allocated                   401313722368
   tm_tiny           used                  552812175360
   tm_tiny           referenced            426534752256
   tm_tiny           compressratio         3.85x
   tm_tiny           usedbysnapshots       125003440128           -
   tm_tiny           usedbydataset         426534752256           -
   tm_tiny           usedbychildren        1273982976             -

zfs rollback -R tm_tiny@20160101
--whole-file --inplace, 6.5 часов на изменения

   tm_tiny  dedupratio                  1.43x                       -
   tm_tiny  allocated                   401376501760                -
   tm_tiny           used                  573943959552           -
   tm_tiny           referenced            426534752256           -
   tm_tiny           compressratio         4.18x                  -
   tm_tiny           usedbysnapshots       146084622336           -
   tm_tiny           usedbydataset         426534752256           -
   tm_tiny           usedbychildren        1324584960   

Попробовал rsync 3.1.1 на том же подмножестве, gzip-1, итог: стало быстрее чем в 3.0, но медленнее, чем с --whole-file, --preallocate выигрыша в месте не даёт:

--preallocate и --inplace без --whole-file, 7 часов 45 мин
   tm_tiny  dedupratio                  1.38x
   tm_tiny  allocated                   401245483008
   tm_tiny           used                  552747048960
   tm_tiny           referenced            426536271872
   tm_tiny           compressratio         3.85x
   tm_tiny           usedbysnapshots       125001945088           -
   tm_tiny           usedbydataset         426536271872           -
   tm_tiny           usedbychildren        1208832000  

zdb -L -b tm_tiny
        bp count:         6923504
        ganged count:           0
        bp logical:    2094598171136      avg: 302534
        bp physical:   542733561344      avg:  78390     compression:   3.86
        bp allocated:  552747257856      avg:  79836     compression:   3.79
        bp deduped:    151501774848    ref>1: 372618   deduplication:   1.27
        SPA allocated: 401245483008     used:  4.05%

        additional, non-pointer bps of type 0:     892290
        Dittoed blocks on same vdev: 622766

Ссылки

@ Карта сайта News Автора!

Bog BOS: Файловая система ZFS

Последние изменения:
2017.05.19: sysadmin: Файловая система zfs под Linux для архива

TopList

Copyright © 1996-2017 Sergey E. Bogomolov; www.bog.pp.ru (КГБ знает все, даже то что у Вас на диске ;)