|
Bog BOS: Файловая система ZFS |
Последние изменения: |
Последнее изменение файла: 2024.11.20
Скопировано с www.bog.pp.ru: 2024.11.23
Файловая система ZFS рассматривается с целью организации крупного архива под Linux (CentOS) как альтернатива btrfs.
ZFS объединяет управление пулом устройств (zpool: избыточность, контрольные суммы, выделение места, дедупликация) и наборами данных (dataset - блочные устройства и файловые системы POSIX), zfs (строчными буквами): снимки, клоны, иерархические контрольные суммы, сжатие. Особый упор сделан на сохранность данных, точнее на обнаружение их повреждения. В частности, рекомендуется использовать ОП с ECC, т.к. прочие источники повреждений устранены. Развитие идёт в сторону управления корзинами и устройствами хранения: управление индикацией, питанием, заливка прошивок.
Опробовал устойчивость. Сделал (OpenZFS/ZFSonLinux 0.6 и 0.8) пул из 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
ZFS (прописными) объединяет в единое целое управление пулом свободного места zpool и файловую систему zfs (строчными).
Пул (zpool) представляется в виде дерева, корнем которого является корневой vdev, который собирается из виртуальных блочных устройств vdev различных типов (vdev верхнего уровня) - обычное блочное устройство, зеркало (mirror), zraid{1,2,3} (подобие RAID массивов с 1, 2 или 3 контрольными суммами), кеш (L2ARC), запасной диск (spare) и журнал (log, SLOG для ZIL). Зеркало (2 и более) и zraid* собираются из vdev (утилиты умеют собирать только из блочных устройств).
Для ускорения работы используется кеш в памяти ARC и кеш чтения на выделенном устройстве (рекомендуется SSD) L2ARC.
Каждая операция записи является частью транзакции. Транзакция является атомарной операцией - она либо выполняется целиком, либо не выполняется вовсе. Каждая транзакция является частью группы транзакций (TXG, txg). Группы транзакций нумеруются последовательно. Группа транзакций может быть последовательно в одном из состояний (в каждом состоянии только одна группа в каждый момент времени): открыта, в покое (quiescing) или синхронизации (запись на диск). Транзакции добавляются в открытую группу, выполняются когда группа открыта или в покое. Группа закрывается когда достигнут предел по времени, объёму или требуется синхронизация (создание снимка и т.д.). Накопленные изменения пишутся на диск в состоянии синхронизации. Синхронизация может потребовать дополнительных изменений (например, в карте пространства при выделении новых блоков), т.е. требуется несколько проходов, после превышения лимита проходов ZFS откладывает освобождение и останавливает сжатие.
Для обеспечения синхронной записи применяется механизм ZIL и выделенное устройство для кеширования ZIL - SLOG.
Пул обеспечивает местом произвольное количество наборов данных (файловые системы zfs, тома, снимки и пр.). Файловые системы монтируются автоматически в точку "/имя-набора" (можно изменить в свойстве mountpoint), каталог создаётся автоматически.
Для набора данных можно создавать неизменяемые снимки, которые доступны по имени как файловые системы или тома. Снимки файловой системы автоматически монтируются при первом обращении к файлам. На базе снимков можно делать изменяемые клоны исходного набора данных, удалять исходный снимок нельзя на время жизни клона, можно поменять ролями исходый набор данных и его клон (promote) после чего удалить набор бывший исходным и ставшиий клоном. Кроме снимков (snapshot) можно делать отметки (bookmark) - привязываются к снимку, недоступны как файловые системы.
Наборы данных можно экспортировать по NFS, SMB и iSCSI (тома как блочные устройства).
Компоненты (слои), снизу вверх:
ZFS (торговая марка Oracle) разработана в Sun Microsystems (ныне Oracle), начало работ - 2001 год, включён в Solaris 10 в 2006.
Код открыт в 2005 (в рамках OpenSolaris) под лицензией CDDL, закрыт в 2010 (OpenSolaris форкнули в Illumos). Код разделился на ZFS Oracle и других.
Другие объединились под именем OpenZFS. Обеспечивает совместимость пулов хранения между реализациями. OpenZFS стал посредником для обмена кодом из Illumos/DelphixOS (2/3 исходных разработчиков ZFS ушли сюда после закрытия OpenSolaris), FreeBSD, OS X и ZFS on Linux (ZOL). В последующем оказалось, что Illumos фактически мёртв, FreeBSD использует код от OpenZFS, который в основном пополняется от ZOL. В результате ZOL перепаковали в OpenZFS.
В связи с якобы несовместимостью CDDL и GPL некогда была разработана FUSE реализация ZFS в Linux, покойная с 2016 года (ещё есть в EPEL6, но нет в EPEL7).
Первоначально ZFS имела (ZFS Oracle и сейчас имеет) версии формата на диске, затем OpenZFS приняла единую версию 5000 и систему флагов возможностей (feature flags) - фич. Предполагается, что реализация версии 5000 включает все возможности на момент закрытия OpenSolaris - ZVOL (ZFS Emulated Volume) версии 28 и ZPL (ZFS POSIX Layer) 5.
Фича пула (свойство пула с именем feature@название-фичи, полное имя - feature@org.zfsonlinux:имя, но можно сократить до "имя", если нет совпадений) может находиться в состоянии:
Преобразование пула происходит по команде "zpool upgrade" или при установке свойства в состояние enabled.
Пул с неподдерживаемыми фичами может быть импортирован, если фича не была активирована (свойство пула unsupported@название-фичи=inactive) или используется в режиме только чтения (свойство readonly) и фича такой импорт допускает (свойство пула unsupported@название-фичи=readonly).
Некоторые фичи зависят от других.
Свойство compatibility (zpool create -o compatibility=...) позволяет задать список совместимости:
Фичи пула (сравнение производительности алгоритмов вычисления контрольной суммы - /proc/spl/kstat/zfs/chksum_bench и /proc/spl/kstat/zfs/fletcher_4_bench):
zhack позволяет узнать состояние фич пула или поменять их "вручную"
zhack feature stat bigpool # показаны ненулевые for_read_obj: com.delphix:extensible_dataset = 9957 org.illumos:lz4_compress = 1 org.freebsd:zstd_compress = 6638 org.open-zfs:large_blocks = 6637 com.delphix:embedded_data = 1 for_write_obj: org.zfsonlinux:allocation_classes = 1 com.delphix:spacemap_v2 = 1 com.delphix:livelist = 3318 com.delphix:log_spacemap = 1 com.delphix:enabled_txg = 14 com.delphix:empty_bpobj = 10262661 com.delphix:spacemap_histogram = 28075 descriptions_obj: enabled_txg_obj: com.datto:resilver_defer = 4 com.delphix:redaction_bookmarks = 4 com.delphix:livelist = 4 org.freebsd:zstd_compress = 4 com.delphix:spacemap_v2 = 4 com.delphix:zpool_checkpoint = 4 com.datto:encryption = 4 com.delphix:enabled_txg = 4 org.open-zfs:large_blocks = 4 com.delphix:log_spacemap = 4 com.delphix:redacted_datasets = 4 org.illumos:lz4_compress = 4 com.delphix:spacemap_histogram = 4 org.zfsonlinux:large_dnode = 4
Предполагается (предполагалось?) введение фич ZPL.
ZFS on Linux - ZOL (под лицензией CDDL, якобы несовместимой с GPL) представлял собой адаптацию OpenZFS для самостоятельной установки на Linux (требуется самостоятельная сборка модуля ядра из исходных текстов). В дальнейшем ZOL был перепакован под именем OpenZFS. В Ubuntu 16.04 LTS устанавливается прямо бинарным модулем (и никто их не осудил), в Gentoo, Debian и ALT Linux через сборку с помощью DKMS. В дополнение к собственно ZFS поставляется SPL (Solaris Porting Layer). Для текущей версии (OpenZFS 2.2.2) необходимо ядро не менее Linux 3.10 (RHEL/CentOS 7).
Каждый раз при обновлении ядра модуль пересобирается через DKMS (Dynamic Kernel Module Support, автоматическая перекомпиляция модуля при обновлении ядра) или используется стабильный API через kABI-tracking kmod (Kernel Application Binary Interface, стиль ELRepo, родной пакет kmod, не требуется переустановка модулей при обновлении ядра, если модуль использует внешние символы из белого списка). Разработчики рекомендовали использовать kABI-tracking kmod, а DKMS оставить для пользователей нестандартных ядер и любителей внести свои изменения в исходные тексты ZFS. Однако в RHEL 7.3 стабильность API дала маху, в RHEL 7.4 история повторилась, в RHEL 7.5 ещё раз и в RHEL 7.6 ещё. С тех пор обеспечивается отдельный репозиторий для каждой минорной версии RHEL.
Для установки требуется добавить репозиторий yum от OpenZFS (для RHEL/CentOS 7 (поддерживается только последняя минорная версия). В связи со сломом совместимости kABI установка kABI на 7.3 (7.4) требует дополнительных действий: всё остановить, удалить и поставить заново. Ключ кладётся в /etc/pki/rpm-gpg/RPM-GPG-KEY-zfsonlinux, описание репозитория в /etc/yum.repos.d/zfs.repo
Создание зеркала репозитория yum (от 0.5GB до 4GB!), в последнее время тестовые ветки содержат предпоследнюю версию, а основные ещё более старую:
Установка [в варианте kABI]:
systemctl preset zfs-import-cache zfs-import-scan zfs-mount zfs-share zfs-zed zfs.target vendor preset: enabled zfs-import-cache # "/sbin/modprobe zfs; /sbin/zpool import -c /etc/zfs/zpool.cache -aN" zfs-mount # "/sbin/zfs mount -a" zfs-share # "/bin/rm -f /etc/dfs/sharetab; /sbin/zfs share -a" zfs-zed zfs.target
Предпочитающие погорячее (ибо в репозитории времён 2.2.2 лежит версия 2.0.7 и в testing - 2.1.13) могут поставить только что сделанные BuildBot-ом пакеты (testing сломан), например, оглавление для CentOS 7
Устанавливаемые пакеты и файлы (2.0.6-1 для CentOS 7):
Или ещё горячее - собрать свои rpm:
# нужна инфраструктура сборки модулей ядра (для Rocky Linux 8.9: autoconf, automake, libtool, libuuid-devel, libblkid-devel, libtirpc-devel, rpm-build, ncompress, libaio-devel, libffi-devel, libudev-devel, python3-cffi, python3-packaging GIT_SSL_NO_VERIFY=true git clone --branch=zfs-2.2.2 https://github.com/openzfs/zfs.git zfs cd zfs ./autogen.sh ./configure # --prefix=/usr --libdir=/lib64 --sysconfdir=/etc/zfs --datarootdir=/usr/share --mandir=/usr/share/man --enable-linux-builtin=yes --with-linux=? # нужны пакеты python36-devel (в CentOS7 имеется python3-devel.x86_64, поменял rpm/redhat/zfs.spec), python36-packaging, python36-cffi make rpm # zfs-kmod-2.2.2-1.el7.src.rpm # kmod-zfs-3.10.0-1160.53.1.el7.x86_64-2.2.2-1.el7.x86_64.rpm # kmod-zfs-devel-2.2.2-1.el7.x86_64.rpm # kmod-zfs-devel-3.10.0-1160.53.1.el7.x86_64-2.2.2-1.el7.x86_64.rpm # zfs-dkms-2.2.2-1.el7.src.rpm # zfs-dkms-2.2.2-1.el7.noarch.rpm # zfs-2.2.2-1.el7.src.rpm # zfs-dracut-2.2.2-1.el7.noarch.rpm # python3-pyzfs-2.2.2-1.el7.noarch.rpm # libzfs5-2.2.2-1.el7.x86_64.rpm # libuutil3-2.2.2-1.el7.x86_64.rpm # libnvpair3-2.2.2-1.el7.x86_64.rpm # pam_zfs_key-2.2.2-1.el7.x86_64.rpm # libzpool5-2.2.2-1.el7.x86_64.rpm # libzfs5-devel-2.2.2-1.el7.x86_64.rpm # zfs-2.2.2-1.el7.x86_64.rpm # zfs-test-2.2.2-1.el7.x86_64.rpm
Устанавливаемые пакеты и файлы (2.2.2-1 для CentOS 7.9) в варианте DKMS:
С dracut не разбирался, т.к. не использую ZFS в качестве корневой файловой системы.
Модули ядра нужно загружать явно (systemd или sysv init) - к версии 2.2.2 остались только модули spl и zfs,
Отредактировать /etc/modprobe.d/zfs.conf (spl.conf). Выгрузить и загрузить модуль zfs.
После установки надо загрузить модуль zfs вручную (systemd позаботится о вас)
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 Nov 22 20:23:41 grid0001 kernel: spl: loading out-of-tree module taints kernel. Nov 22 20:23:41 grid0001 kernel: spl: module verification failed: signature and/or required key missing - tainting kernel Nov 22 20:23:41 grid0001 kernel: icp: module license 'CDDL' taints kernel. Nov 22 20:23:41 grid0001 kernel: Disabling lock debugging due to kernel taint Nov 22 20:23:41 grid0001 kernel: ZFS: Loaded module v2.0.6-1, ZFS pool version 5000, ZFS filesystem version 5 Feb 15 18:15:10 grid0156 kernel: Request for unknown module key 'DKMS module signing key: 4b5f14880c6a862f1cfb0e7b663f1c4ba4c18502' err -11 Feb 15 18:15:10 grid0156 kernel: spl: loading out-of-tree module taints kernel. Feb 15 18:15:10 grid0156 kernel: spl: module verification failed: signature and/or required key missing - tainting kernel Feb 15 18:15:10 grid0156 kernel: Request for unknown module key 'DKMS module signing key: 4b5f14880c6a862f1cfb0e7b663f1c4ba4c18502' err -11 Feb 15 18:15:10 grid0156 kernel: zfs: module license 'CDDL' taints kernel. Feb 15 18:15:10 grid0156 kernel: Disabling lock debugging due to kernel taint Feb 15 18:15:12 grid0156 kernel: ZFS: Loaded module v2.2.2-1, ZFS pool version 5000, ZFS filesystem version 5
По умолчанию установлен параметр zfs_autoimport_disable модуля zfs, импортировать пул также придётся вручную (systemd позаботится о вас):
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).
Головная боль OpenZFS (ZoL) - борьба ядра и ZFS за память. ZFS расходует ОП на ARC (данные с диска, метаданные с диска и вспомогательные данные; информация в /proc/spl/kstat/zfs/arcstats и /proc/spl/kstat/zfs/dbufstats, 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 переделали списочная структура ARC Buffer Data (ABD) - /proc/spl/kstat/zfs/abdstats, данные хранятся в сжатом виде, но теперь растут в трёх местах, насколько это помогло не исследовал. /proc/spl и /proc/zfs содержат море статистики. В версии 2.0 встроили автоматическую настройку параметров ARC.
spl - Solaris Porting Layer, изображает Solaris на Linux. Параметры можно установить при загрузке системы (spl.имя-параметра=значение), при загрузке модуля из файла /etc/modprobe.d/spl.conf, динамически в /sys/module/spl/parameters/имя-параметра (kmem - собственная подсистема выделения памяти ядра, taskq - собственная подсистема управления потоками в ядре):
Модуль реализует SPA, DMU, ZVOL и ZPL. Параметры (273 штуки в версии 2.0.0-rc1; 320 штук в версии 2.2.2) можно установить при загрузке системы (zfs.имя-параметра=значение), при загрузке модуля из файла /etc/modprobe.d/zfs.conf, динамически в /sys/module/zfs/parameters/имя-параметра.
Общее поведение, обработка ошибок:
Отладка:
send/receive:
Выделение места:
Базовый ввод/вывод:
Транзакции (открытие и наполнение, завершение, синхронизация (запись изменений) на устройство; синхронизация может потребовать выделения места, которое требует записи для себя и т.д. - несколько проходов):
Ограничение потока записи (уменьшение процентов уменьшает эффективность буферизации за счёт снижения расхода памяти и уменьшения задержек, при чрезмерном увеличении подлежащее устройство будет захлёбываться; статистика в /proc/spl/kstat/zfs/dmu_tx (dmu_tx_assigned - всего транзакций, dmu_tx_dirty_delay - задержано, dmu_tx_dirty_throttle - задержка не помогла и устройство захлебнулось)):
Шифрование:
Предварительное чтение:
Обслуживание синхронной записи (ZIL, SLOG):
ARC кеш (статистика в /proc/spl/kstat/zfs/dbufstats):
L2ARC кеш:
Планировщик ввода/вывода (отдельные очереди для задач каждого типа):
Выбор алгоритма рассчёта контрольной суммы:
Работа с vdev:
scrub и лечение:
Тома и снимки:
События:
Что это:
Набор данных (в частности, файловая система 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:
При создании пула он сразу импортируется, на нём создаётся корневая файловая система, которая сразу монтируется.
Имя пула должно начинаться с буквы и может содержать буквы, цифры, "_", "-", ".", ":", " ". Зарезервированы имена "mirror*", "raidz*", "cache", "spare*", "log", "draid*".
Пул, каждый vdev и каждое блочное устройство имеют уникальные GUID (не настоящие 128-битные в специальном формате, а просто случайные 64 бита).
Изменить количество блочных устройств в vdev невозможно (кроме расширения зеркала и разбиения состоящего из зеркал zpool), но можно добавить новый vdev в zpool. Также можно заменить устройство в vdev на большее (при наличии избыточности!): дождаться завершения лечения (resilver), повторить процедуру для оставшихся устройств (необходимо установить свойство пула autoexpand до замены первого диска - не сработало для LVM2). Данные распределяются по vdev, но ZFS не имеет средств ребалансировки, т.е. в новые vdev будут записаваться только новые данные. Кстати, до версии 0.8 лечение диска на 10ТБ потребует нескольких дней - лечение (как и scrub) идёт не последовательно, а по ссылкам инфраструктуры, так что замена одного диска вызывает полный проход по всем дискам. Да и в новых версиях идёт очень долго, если метаданные не вынесены в special на SSD ("19.8T scanned at 49.2M/s, 19.8T issued at 49.1M/s, 287T total, 65 days 21:30:16 to go").
В raidz (однопоточная?) производительность vdev на запись будет равна производительности 1 (самого медленного) диска, т.к. ZFS распределяет записи по vdev, не по конечным устройствам внутри него. При добавлении vdev распределение динамически увеличивается. Чтение может распараллеливаться внутри vdev. Придётся отказаться от традиции использовать LVM из нескольких подлежащих устройств в режиме RAID-0 (stripe) - надо добавлять в пул ZFS сами устройства.
В статье 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 2013 год):
В реальности zpool - это дерево, которое начинается с корневого vdev, который состоит из vdev типа зеркало, raidz*, диск, файл, spare, cache, special и log. vdev типа зеркало и raidz* также могут включать vdev типа зеркало, raidz*, диск, файл. Вот только утилита создания не поддерживает такую конструкцию. Зато отладчик (zdb -C) показывает пул в виде дерева.
Метки 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), GUID пула (?) и контрольную сумму GUID всех vdev. Указатель имеет длину 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) и ? (получаются разделы по 2^34 байт). При поиске свободного места сначал выбирается vdev (предпочтение незаполненному vdev - metaslab_bias_enabled, поочередно (512 KiB?)), затем метаслаб в нём (группа метаслабов) исходя из процента заполненности, фрагментированности свободного места (metaslab_fragmentation_factor_enabled) и пр. (см. параметры модуля zfs). Рекомендуется убрать дисковую оптимизацию при использовании SSD (metaslab_lba_weighting_enabled=0). При поиске свободного места внутри метаслаба используется карта пространства (space map, список диапазонов с журнальной структурой - журнал выделений и освобождений, отсортированный по номеру группы транзакций; при чтении с диска в память формируется отсортированный список свободных пространств, который при записи преобразуется в журнал выделений). При выделении места из метаслаба, в котором более 4% свободного места, используется алгоритм первого подходящего, иначе самого подходящего, что значительно медленнее. Чтобы предотвратить это не допускайте уменьшения свободного места в пуле ниже 10%. Или metaslab_lba_weighting_enabled=0 и можно опускать до 5%. В сильно изменяющемся пуле необходимо держать 20% свободного пространства, в слабоизменяющемся (архив) достаточно 4%.
В файле /etc/zfs/zpool.cache хранится список известных пулов (не файловых систем, посмотреть: "zdb -C"), манипуляции
Переменные окружения для утилиты zpool:
Неизменяемые свойства пула (статистика и т.п.):
Свойства пула, которые можно задать при создании, импортировании и изменении (свойства требуют места в пуле и при его заполнении их невозможно изменить):
Пул может иметь пользовательские свойства, которые не влияют на поведение ZFS. Имя пользовательского свойства должно содержать ":" и быть короче 256 символов (байт?). Предполагается, что имя начинается с DNS имени в обратном порядке. Значение может быть произвольной строкой до 8192 байт.
Отдельные vdev также имеют встроенные и пользовательские свойства (zpool get -o all all имя-пула all-vdevs) начиная с версии 2.2:
zpool -? # вывести список команд.
zpool version # вывести версию ZFS (аналогично "zpool -V" или "zpool --version").
zpool create [ключи] имя-пула [тип-vdev] устройство1 ... [тип-vdev устройствоN ...] ... # создать пул и корневую файловую систему, администратор ответственнен за неиспользование устройств одновременно в 2 пулах; ключи:
zpool get список-свойств-через-запятую|all [имя-пула [all-vdevs|имя-vdev]] # выводится имя пула, имя свойства, значение и источник, ключи:
zpool set имя-свойства=значение имя-пула [имя-vdev] # изменить значение свойства пула или vdev на ходу.
zpool status [имя-пула ...] [интервал [отсчётов]] # показывает состояние (см. health) пула и фоновых задач (scrub и resilver); осторожно - пытается обратиться ко всем устройствам, что может вызвать большие задержки; ключи:
zpool list [имя-пула] ... [интервал [отсчётов]] # выдать список пулов с информацией о состоянии и заполненности, ключи:
zpool iostat [имя-пула-и/или-vdev] ... [интервал [отсчётов]] # логическая статистика ввода/вывода (для физической статистики см. iostat), информация о ёмкости, свободном месте, операциях ввода и вывода, пропускной способности ввода и вывода, числа двоичные, ключи:
zpool import # выдать список экспортированных пулов, доступных для импорта, имена, уникальные идентификаторы, топологию и состояние; ключи:
zpool import [имя-пула | идентификатор-пула [новое-имя-пула]] # перед использованием для монтирования файловой системы пул д.б. импортирован; при импорте в режиме только чтение не проигрывается ZIL и нельзя изменять свойства; при импорте много пишется (txg_sync - 100% ЦП) на носитель (6ГБ со скоростью 300 МБ/сек для файловой системы в 10ТБ); ключи:
zpool destroy [-f] имя-пула # размонтировать файловые системы и уничтожить пул, подтверждения не запрашивается.
zpool labelclear [-f] устройство # затереть метку zfs; заодно удаляет GPT, созданную zfs
zpool export имя-пула # отпустить пул перед переносом дисков на другой сервер - данные из кеша сбрасываются на диск, файловые системы размонтируются, устройства помечаются как экспортированные, помечается запрет на автоматический импорт и монтирование, пул удаляется из кеша; не экспортируется без ключа "-f", если к пулу приписано разделяемок устройство горячего резерва и оно используется; пул недоступен для работы пока его не импортируют явно, если сервер умер и устройства хранения приходится переставлять без экспорта, то импортировать придётся с ключом "-f"; ключи:
zpool add имя-пула устройство ... # добавить vdev к пулу, ключи:
zpool remove имя-пула устройство ... # удалить диск замены, кеш (L2ARC), SLOG (ZIL) устройство, vdev (включая dedup и special, но не raidz); данные с удаляемых vdev переписываются на оставшиеся устройства в фоновом режиме (см. zpool status); требует фичи device_removal; скорость высокая (346G copied out of 5.31T at 1.19G/s); вместо старого vdev в таблице остаётся устройство indirect-1; ключи:
zpool scrub имя-пула # запуск или продолжение в фоновом режиме (состояние смотреть "zpool status") проверки контрольных сумм каждой копии каждого используемого логического блока и проверку чётности для RAIDZ (а при обычном чтении делается?), лечение по возможности; рекомендуется раз в неделю/месяц; если совсем всё плохо: "zpool import -o readonly=on имя-пула; zpool scrub имя-пула"; в версии до 0.8 scrub (и лечение) осуществляет проход по структуре, а не последовательное чтение, причём однопоточное синхронное, т.е. безумно медленно; проверка структуры производится по минимому - лишь бы можно было пройти; scrub производит 2 типа ввода/вывода: чтение каталогов и dnode производится с помощью обычного механизма (предварительное загрузка, синхронное чтение через механизм ARC, без всяких проверок, не учитывается в отчёте сканирования) и асинхронное чтение всех копий блоков с проверкой (учитывается в отчёте сканирования, настраивается с помощью параметров модуля вплоть до отключения); можно запустить только одну проверку пула одновременно: ключи:
Примеры производительности версия 0.6 массив из обычных дисков, собранный в 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 версия ? 2 массива из разных дисков (RAID6 из 17 дисков SATA 2TB LFF 7200 в LSI MegaRAID), собранных в LVM (stripe), без снимков, без DDT, без нагрузки scan: scrub in progress since Fri Oct 26 19:48:04 2018 5.58T scanned out of 9.67T at 1.36G/s, 0h51m to go 0B repaired, 57.72% done 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 реальный архив, много снимков, DDT, без нагрузки NAME SIZE ALLOC FREE EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT time_machine 116T 69.1T 46.9T - 22% 59% 1.52x ONLINE - scan: scrub repaired 0 in 236h0m with 0 errors версия 2.1.7 2 массива из дисков (RAID6 из 18 дисков SAS 10TB LFF 7200 в LSI MegaRAID), собранных в LVM (stripe), l2arc и lvmcache на SSD scan: scrub in progress since Thu Mar 14 18:42:02 2024 4.28T scanned at 57.9M/s, 3.51T issued at 47.6M/s, 287T total 0B repaired, 1.23% done, 72 days 05:27:09 to go версия 2.2 2 массива из дисков (RAID6 из 17 дисков SAS 16TB LFF 7200 в LSI), собранных в LVM (stripe), SSD для метаданных, много снимков, DDT, без нагрузки scan: scrub in progress since Wed Mar 13 22:23:44 2024 176T / 244T scanned at 2.54G/s, 95.3T / 244T issued at 1.38G/s 0B repaired, 39.11% done, 1 days 06:41:06 to go
zpool resilver имя-пула # запуск в фоновом режиме проверки и исправления контрольных сумм каждой копии каждого используемого блока; в отличие от scrub проверяет не все устройства, а только недавно добавленные или подменённые; приостановки нет, при запуске во время выполнения начинает с начала.
zpool attach имя-пула старое-vdev устройство # добавить устройство к vdev, простое vdev превращается в зеркало (начинается лечение), raidz расширить нельзя, ключи:
zpool detach имя-пула старое-устройство # извлечь устройство из зеркала, для временного извлечения рекомендуется "zpool offline".
zpool replace имя-пула старое-устройство [устройство-замены] # эквивалент процедуры: подсоединить устройство замены (mirror или raidz), дождаться завершения лечения, отсоединить старое устройство; устройство замены можно не указывать, если неисправное устройство уже было заменено новым на том же месте; ключи:
zpool clear [--power] имя-пула [устройство] # сбросить счётчики ошибок; пул может быть автоматически возвращён в работу; "--power" или переменная окружения ZPOOL_AUTO_POWER_ON_SLOT включает питание слота (но как?!).
zpool offline [--power] имя-пула устройство-хранения # объявить устройство нерабочим или сбойным (остаётся сбойным даже после импортирования), ключи:
zpool online [--power] имя-пула устройство-хранения # объявить устройство рабочим, ключ "-e" - расширение доступного к распределению на устройстве места до полного.
zpool reopen [имя-пула] # заново открыть (зачем? случайно выдернули устройство и тут же вставили его обратно?) все vdev пула, ключ "-n" - не возобновлять идущую процедуру проверки (scrub).
zpool reguid # сгенерировать новый GUID пула (длительный процесс?).
zpool split имя-пула новый-пул [устройство ...] # только для пула из зеркал и пул не д.б. в состоянии лечения; отщепить от каждого зеркала указанные устройства (по умолчанию последнее устройство) и собрать из них новый пул (GUID одинаковый? пулы останутся из зеркал?), ключи:
zpool upgrade # выдать список пулов, которые можно перевести на новую версию или добавить фичу.
zpool upgrade -v # выдать список поддерживаемых версий и фич.
zpool upgrade {имя-пула | -a} # перевод пула на новую версию с добавлением поддержки всех фич, вернуться нельзя (есть более гуманный способ: "zpool set feature@...=enable").
zpool history [имя-пула] # вывести историю команд, история хранится в пуле и её нельзя отключить (а если пул заполнен на 100%?), используется кольцевой буфер (32 МиБ?); отличный способ подсмотреть, что там сделала send -r/receive; ключи:
zpool events [имя-пула] # выдать список событий zfs, сгенерированных модулем ядром zfs и используемых zed (ошибки, зависания), см. zpool-events(8); сюда же попадают "события" создания записи в history; ключи:
zpool checkpoint имя-пула # создать контрольную точку для пула (может существовать только 1 точка); откатиться можно командой "zpool import --rewind-to-checkpoint"; наличие контрольной точки запрещает использование команд remove, attach, detach, split и reguid; команда "zpool status" показывает наличие контрольной точки; команда "zpool list" показывает количество места, потраченного на контрольную точку; ключи:
zpool initialize имя-пула [устройство] # начать или продолжить заполнение незанятого пространство в пуле ерундой (а зачем?); ключи:
zpool sync [имя-пула] # все изменённые данные записать из ОП на устройство (не в SLOG/ZIL).
zpool trim имя-пула [имя-устройства] # ручная инициализация или продолжение посылки команд TRIM/UNMAP на устройство для всех неиспользуемых секторов; имеется свойство пула для автоматической посылки - autotrim; "zpool status -t" показывает устройства, которые не поддерживают TRIM/UNMAP (trim unsupported) или которые поддерживают, но ожидают ручной инициализации (untrimmed); как это выключить насовсем? ключи:
zpool wait имя-пула [интервал-информирования] # ждать прекращения фоновых операций по завершению, прекращению или приостановке операции или уничтожению или экспорту пула; ключи:
Для ускорения работы используется кеш данных и метаданных в памяти - 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 (в новых версиях просто arc_summary). По умолчанию размер используемой ОП колеблется от 1/32 (zfs_arc_min) до 1/2 (zfs_arc_max) всей ОП. Если предполагается запуск программ, требовательных к ОП, рекомендуется заранее ограничить ARC. Некоторые программы перед запуском проверяют размер свободной памяти и отказываются запускаться при её недостатке, хотя в реальности память могла быть освобождена системой по требованию. Некоторые программы могут требовать больших непрерывных сегментов памяти или huge pages, которые ARC без настроек фрагментирует.
По умолчанию только 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, только из страниц виртуальной памяти.
В ZoL 0.7 вместо отображения страниц используется списочная структура ARC Buffer Data (ABD), что теоретически позволяет бороться с фрагментацией, последствия не исследовал.
В OpenZFS 2.2 сделали адаптивную очистку и удалили множество ручных настроек. Последствия пока непонятны.
Кеш 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 (в новых версиях просто arc_summary). Статистика L2ARC общая для модуля zfs, не обнулишь, пока не выгрузишь модуль.
Потеря устройства не ведёт к потере данных (кешируется только чтение). Можно использовать несколько L2ARC устройств (без страйпинга, заполняются по очереди). Зеркало и raidz не поддерживаются.
Может заполняться несколько часов.
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, иначе будет тормозить, а потом умрёт.
После появления возможности выделить под метаданные отдельный быстрый и устойчивый к истиранию SSD я не использую L2ARC.
Асинхронная запись кешируется в ОП (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/TLC SSD для продления его жизни надо взять устройство (раздел) побольше. Потеря SLOG приведёт к потере последних данных (но не метаданных), пул не будет импортироваться автоматически (можно импортировать вручную), поэтому желательно использовать vdev типа зеркало (raidz не поддерживается). Можно поставить несколько vdev типа slog - они будут работать паралллельно.
Статистику можно посмотреть в /proc/spl/kstat/zfs/zil.
Советы:
Основные настройки:
Контроллер RAID и SSD класса DC превращают синхронную запись в асинхронную с помощью буферизации в память, защищённую батарейкой. ZIL не нужен.
В пуле может быть создано несколько именованных (длина имени не более 256 байт, глубина вложенности - 50) наборов данных (datasets) следующих типов:
Каждый набор данных имеет неизменяемый всё время существования уникальный между пулами GUID, сохраняется при пересылке. Также имеется уникальный внутри пула objsetid, не сохраняется при пересылке, может использоваться повторно после удаления набора данных.
Свойства набора данных наследуются от пула или родительского набора данных, задаются при создании (постоянно, ключ "-O" при создании пула, ключ "-o" при создании файловой системы) или монтировании (временно). Имеется возможность задавать свои (пользовательские) свойства, они не влияют на работу ZFS, всегда наследуются, имя - до 256 байт (обязательно наличие символа ":"), значение - до 8192 (ранее 1024) байт. Свойства требуют места в пуле и при его заполнении их невозможно изменить.
Задаваемые свойства набора данных (свойства наследуются; изменение свойства действует на файлы, создаваемые после изменения, разбиение на логические блоки и сжатие и подсчёт контрольной суммы происходит до дедупликации - не надо ничего менять при включённой дедупликации на полпути):
Информационные свойства набора данных (не наследуются, не устанавливаются):
Размер свободного использованного места в zfs ещё более сложен, чем в btrfs (см. выше описание параметров used*, referenced, logicalused, logicalreferenced). df и du показывают занятое место на диске после сжатия с учётом метаданных, но без учёта дедупликации (даёт ответ на вопрос - "сколько места освободится на диске после удаления, если все блоки были последними в таблице дедупликации?"). Чтобы узнать размер файлов до сжатия необходимо использовать "du --apparent-size". Команда "ls -l" показывает исходный размер файла, команда "ls -lsh" показывает размер файла на диске без учёта дедупликации. Полный размер файловой системы (total), выдаваемый командой df, изменяется по мере изменения коэффициента дедупликации (и сжатия?). Счётчики обновляются в момент завершения транзакции. При использовании vdev типа raidz2 каждый блок содержит как минимум 2 сектора (512 байт или с учётом ashift?) чётности, которые не попадают ни в какие отчёты.
Свойства, устанавливаемые на время монтирования: atime/noatime (atime), auto/noauto (canmount), dev/nodev (devices), exec/noexec (exec), ro/rw (readonly), relatime/norelatime (relatime), suid/nosuid (setuid), xattr/noxattr (xattr), mand/nomand (nbmand), context=, fscontext=, defcontext=, rootcontext=.
Набор данных может иметь пользовательские свойства, которые не влияют на поведение ZFS. Имя пользовательского свойства должно содержать ":" и быть короче 256 символов (байт?). Предполагается, что имя начинается с DNS имени в обратном порядке. Значение может быть произвольной строкой до 8192 байт.
Переменные окружения для утилиты zfs
zfs -?.
zfs version
zfs get {свойство[,...]|all} [имя-пула[/имя-набора-данных[@имя-снимка]]] ... # выдать список значений свойств; выводятся колонки: имя набора данных, имя свойства, значение свойства, источник; в колонке источник (SOURCE) могут быть выданы значения: default (значение взято по умолчанию), inherited (значение унаследовано от пула или родительского набора данных), local (значение свойства установлено явно этого набора данных), temporary (значение установлено временно при монтировании), received (send/receive) или '-' (none, вычисляемый); ключи:
zfs set свойство=значение ... имя-пула[/имя-набора-данных[@имя-снимка]] ... # изменить свойство; ключи:
zfs inherit свойство имя-пула[/имя-набора-данных] ... # унаследовать свойство от родительского набора или пула или умолчания; ключи:
zfs create имя-пула/имя-файловой-системы # создание файловой системы (монтируется автоматически), ключи:
zfs create -V размер имя-пула/имя-тома # создание тома (zvol), экспортируется в блочное устройство /dev/zvol/имя-пула/имя-тома, размер округляется до размера блока, указанный размер резервируется, ключи:
zfs destroy имя-пула/имя-набора-данных # удаление файловой системы или тома; файловая система размонтируется и разшаривается; не д.б. наследников и зависимых клонов (см. ключ "-r" и "-R"); осторожно: приводит к необходимости изменения миллионов (сотен миллионов) блоков метаданных, при использовании фичи async_destroy изменения идут в фоновом режиме и продолжаются с точки остановки после перезагрузки; ключи:
zfs destroy имя-пула[/имя-набора-данных]@имя-снимка[%имя-снимка][,...] # удаление снимков, можно указать список интервалов снимков; удаляется немедленно, если нет блокировок (hold) и зависимых клонов, иначе помечается для удаления после выполнения указанных условий (ни разу не удалялся немедленно, хотя не было ни блокировок, ни клонов). Снимок 84 GiB (самый большой) удалился быстро (lvmcache); интервал снимков (482 GiB) удалялся полторы минуты (в фоне, использовался lvmcache); на заполненной системе интервал снимков 854 ГБ удалялся более 4 часов (без lvmcache); при удалении может потребоваться место; ключи:
Следить за фоновым освобождением места можно командой (freeing)
zpool list -p -o name,size,allocated,free,freeing,leaked,fragmentation,expandsize,capacity,dedupratio,health 30
zfs destroy имя-пула/имя-набора-данных#имя-закладки # удалить закладку
zfs snapshot имя-пула/имя-набора-данных@имя-снимка # создать снимок; при изменениях в файловой системе в снимке остаются старые значения, менять нельзя; ключи:
zfs rollback имя-пула/имя-набора-данных@имя-снимка # откатить состояние файловой системы или тома на время создания снимка; все сделанные после создания указанного снимка изменения удаляются; промежуточные снимки и закладки требуется удалить (ключ "-r" или "-R"); снимки подчинённых файловых систем не удаляются даже с ключами "-rR", каждую требуется откатить отдельно; ключи:
zfs clone имя-пула/имя-набора-данных@имя-снимка имя-пула/новое-имя-набора-данных # создать новую файловую систему или том на основе снимка; файловая система будет смонтирована по умолчанию в /имя-пула/новое-имя-файловой-системы с возможностью записи; снимок нельзя будет удалить без удаления клона; ключи:
zfs promote клонированная-файловая-система # исходная файловая система, с которой делался снимок, с которого делался клон становится клоном (его можно потом удалить, но снимок - нет!), клон становится самостоятельной файловой системой, а снимок привязывается к ней (origin и clone меняются местами), все предыдущие снимки также привязываются к бывшему клону, последующие остаются привязанными к бывшей исходной файловой системе. Предварительно необходимо разрешить все конфликты имён. Пример из документации
zfs create pool/project/production zfs snapshot pool/project/production@today zfs clone pool/project/production@today pool/project/beta zfs promote pool/project/beta zfs rename pool/project/production pool/project/legacy zfs rename pool/project/beta pool/project/production zfs destroy pool/project/legacy
zfs bookmark имя-пула/имя-набора-данных{@имя-снимка|#имя-закладки} имя-пула#имя-новой-закладки # создать закладку.
zfs rename имя-пула/имя-набора-данных[@имя-снимка] новое-имя; переименовать набор данных или снимок; при необходимости производится перемонтирование; ключи:
zfs list [имя-набора-данных|имя-снимка] ... # выдать список наборов данных и их свойств; ключи:
zfs mount # вывести список смонтированных файловых систем; временно смонтированные файловые системы для снимков не показывает.
zfs mount {имя-пула/имя-файловой-системы|-a} # смонтировать файловую систему или все; автоматически выполняется при импорте пула, если разрешено в mountpoint; ключи:
zfs unmount|umount {-a | имя-пула/имя-файловой-системы | точка-монтирования} # размонтирование файловой системы; ключи:
zfs share {-a | имя-пула/имя-файловой-системы} # выдаёт (экспортирует, расшаривает) файловую систему наружу для NFS, SMB или iSCSI (удалено) для файловых систем и томов с установленными свойствами sharenfs, sharesmb или shareiscsi (удалено); выполняется автоматически при импорте пула; шары создаются в подкаталоге .zfs/shares/ корня файловой системы (?); снимки экспортируются вместе с файловой системой (при первом обращении к .zfs/snapshot); можно экспортировать непосредственно .zfs/snapshot.
zfs unshare {-a | имя-пула/имя-файловой-системы | точка-монтирования} # закрывает файловую систему для экспорта; выполняется автоматически при завершении работы сервера.
zfs send имя-пула/имя-набора-данных@имя-снимка # вывести на stdout поток, представляющий содержимое снимка; этот поток можно сохранить или сразу использовать локально или удалённо (например, с помощью ssh, nc, mbuffer) командой "zfs receive"; формат потока стандартизован и зафиксирован; send делает hold на снимки; посмотреть заголовки и статистику можно с помощью утилиты zstreamdump; на передающем конце данные разжимаются (если не указано -c), на приёмном сжимаются обратно; ключи:
Пример копирования цепочки снимков (основанные на снимках клоны не копируются):
принимающий сервер (пул bigpool создан, а файловая система нет) mbuffer -I 7777 -m 1G -s 1048576| zfs receive -vd -F -s -o свойство ... -o mountpoint=/time_machine bigpool передающий сервер (имеются снимки и клоны с 20150101 по 20240131): zfs send -R -p -Lec -V bigpool/time_machine@20240131 | mbuffer -O принимающий-сервер:7777 -m 1G -s 1048576 создаются поштучно receiving full stream of bigpool/time_machine@20150101 into bigpool/time_machine@20150101 in @ 28.0 MiB/s, out @ 28.0 MiB/s, 11.2 TiB total, buffer 0% fullreceived 11.2T stream in 113336.17 seconds (104M/sec) receiving incremental stream of bigpool/time_machine@20150102 into bigpool/time_machine@20150102 in @ 53.9 MiB/s, out @ 49.9 MiB/s, 11.3 TiB total, buffer 0% fullreceived 29.1G stream in 145.54 seconds (205M/sec) ... клоны не дошли, пришлось воссоздавать for DATE in `ls /time_machine/.zfs/snapshot/`; do zfs clone -o mountpoint=/clones/$DATE -p bigpool/time_machine@$DATE bigpool/clones/$DATE; done следующая пачка (в промежутке на приёмном конце ничего не делать): mbuffer -I 7777 -m 1G -s 1048576| zfs receive -vd -F -o ... -o mountpoint=/time_machine bigpool zfs send -R -Lec -I bigpool/time_machine@20240131 bigpool/time_machine@20240229 | mbuffer -O принимающий-сервер:7777 -m 1G -s 1048576
zfs send имя-пула/имя-набора-данных|имя-пула # вывести на stdout поток, представляющий содержимое файловой системы; снимки и клоны не передаются; файловая система должна быть размонтирована или пул импортирован только на чтение; на приёмном конце создаётся искусственный снимок с именем "--head--" (не удаляется при завершении); ключи:
Пример копирования файловой системы целиком (без снимков и клонов)
принимающий сервер (пул bigpool создан, файловая система создана) mbuffer -I 7777 -m 1G -s 1048576| zfs receive -ve -F -s bigpool передающий сервер (клоны с 20150101 по 20240131, пришлось всё размонтировать): zfs send --Lec -V bigpool/time_machine| mbuffer -O принимающий-сервер:7777 -m 1G -s 1048576 summary: 36.8 TiByte in 52h 48min 30.1sec - average of 203 MiB/s receiving full stream of bigpool/time_machine@--head-- into bigpool/time_machine@--head-- ...
zfs send -t ключ-возобновления # возобновить прерванную ранее передачу; ключ брать в свойстве receive_resume_token на принимающем конце (см. "zfs receive -s"). Можно использовать только ключи -PVenv.
zfs send [-i снимок|закладка] -S набор-данных # выдать поток, который мы сами получили не полностью.
zfs send --redact имя-закладки имя-пула/имя-набора-данных@имя-снимка # вывести на stdout поток, представляющий содержимое снимка, отредактированный командами из закладки (записываются командой "zfs redact"); мутная вещь.
zfs redact снимок закладка редактирующий-снимок # создать закладку для последующего редактирования потока. Ещё более мутная вещь.
zfs receive имя-пула/имя-набора-данных[@имя-снимка] # принять поток от "zfs send" на stdin и создать из него снимок; для инкрементального потока файловая система должна существовать, самый свежий снимок на приёмном конце должен соответствовать опроному снимку на передающем; если имя-снимка указано в команде, то берётся из команды, иначе - из потока; при приёме полного потока создаются файловая система и снимок; при приёме пакета потоков (-R) на приёмном конце удаляются снимки, отсутствующие у источника ("zfs destroy -d"); при приёме тома ссылка на устройство пересоздаётся (не получится его использовать во время передачи); если не использован ключ "-s", то при прерывании передачи файловая система откатывается к моменту начала; после передачи первого снимка монтирования не произошло, попытался вручную - файловая система пуста, передача прервалась ("dataset is busy"), не трогайте приёмник до завершения всей передачи; пример send/receive с использованием mbuffer ключи:
Что происходит при передаче снимка на самом деле? Подсмотрено из "zpool events -v" и "zpool history -il":
"послойная" передача receive bigpool/time_machine (387) set bigpool/time_machine (387) $hasrecvd= set bigpool/time_machine (387) aclinherit=3 ... finish receiving bigpool/time_machine (387) snap=20150101 snapshot bigpool/time_machine@20150101 (44623) set bigpool/time_machine (387) sharesmb=off set bigpool/time_machine (387) sharesmb=off receive bigpool/time_machine/%recv (44746) set bigpool/time_machine (387) aclinherit=3 ... finish receiving bigpool/time_machine/%recv (44746) snap=20150102 clone swap bigpool/time_machine/%recv (44746) parent=time_machine snapshot bigpool/time_machine@20150102 (45407) destroy bigpool/time_machine/%recv (44746) (bptree, mintxg=44320) set bigpool/time_machine (387) sharesmb=off receive bigpool/time_machine/%recv (43639) set bigpool/time_machine (387) aclinherit=3 ... finish receiving bigpool/time_machine/%recv (2255790) snap=20240131 clone swap bigpool/time_machine/%recv (2255790) parent=time_machine snapshot bigpool/time_machine@20240131 (2258108) destroy bigpool/time_machine/%recv (2255790) (bptree, mintxg=1666790) set bigpool/time_machine (387) sharesmb=off zfs receive -vd -F -o ... bigpool создание клонов clone bigpool/clones/20150101 (2255968) origin=bigpool/time_machine@20150101 (44623) set bigpool/clones/20150101 (2255968) mountpoint=/clones/20150101 zfs clone -o mountpoint=/clones/20150101 -p bigpool/time_machine@20150101 bigpool/clones/20150101 ... целиковая передача receive bigpool/time_machine/%recv (390) finish receiving bigpool/time_machine/%recv (390) snap=--head-- clone swap bigpool/time_machine/%recv (390) parent=time_machine snapshot bigpool/time_machine@--head-- (115448) destroy bigpool/time_machine/%recv (390) (bptree, mintxg=1) ioctl receive input: snapname: 'bigpool/time_machine@--head--' begin_record[0]: 0 begin_record[1]: 0 ... begin_record[311]: 0 input_fd: 0 force resumable output: read_bytes: 40412783039912 error_flags: 0 errors: zfs receive -ve -F -s bigpool
zfs diff имя-пула/имя-файловой-системы@имя-снимка имя-пула/имя-файловой-системы[@имя-снимка] # вывести список файлов, изменившихся между снимками ("-" - удалён, "+" - добавлен, "M" - изменён, "R" - переименован); ключи:
zfs userspace имя-пула/имя-файловой-системы[@имя-снимка] # показать квоты и занимаемое место (см. свойства userused@имя-пользователя и userquota@имя-пользователя; ключи:
zfs groupspace имя-пула/имя-файловой-системы[@имя-снимка] # показать квоты и занимаемое место (см. свойства groupused@имя-группы и groupquota@имя-группы; ключи:
zfs projectspace имя-пула/имя-файловой-системы[@имя-снимка] # показать квоты и занимаемое место (см. свойства projectused@идентификатор-проекта и projectquota@идентификатор-проекта; ключи:
zfs allow и unallow позволяют передать непривилегированному пользователю (не uid 0) часть прав по администрированию файловой системы или тома. Без параметров выводит текущие права.
zfs hold [-r] метка имя-пула/имя-файловой-системы@имя-снимка ... # именованная блокировка не позволяет удалить снимок, каждый снимок имеет своё пространство имён. Этот механизм используется в send/receive. Клоны используют другой механизм.
zfs holds [-rHp] имя-пула/имя-файловой-системы@имя-снимка ... # вывести список блокировок.
zfs release [-r] метка имя-пула/имя-файловой-системы@имя-снимка ... # снять поименованную блокировку.
zfs upgrade [-v] # показать список файловых систем (не пулов!), которые можно улучшить. В настоящее время нет ничего кроме версии 5.
zfs upgrade {-a | имя-пула/имя-файловой-системы} # обновить версию файловой системы (не пула!); ключи:
zfs jail и unjail # только для FreeBSD.
zfs load-key и unload-key и change-key # манипуляции с ключами шифрования.
zfs zone файл-пространства-имён имя-пула/имя-файловой-системы # подключить файловую систему в пространство имён пользователя; требуется свойство zoned; определяется файлом /proc/номер-процесса/ns/user; в пользовательском пространстве имён требуется доступ к /dev/zfs; подчинённые файловые системы нельзя подключить к другому пользователю; нельзя поменять квоту.
zfs unzone файл-пространства-имён имя-пула/имя-файловой-системы # отключить файловую систему из пространства имён пользователя.
zfs wait [-t тип,...] # дождаться завершения указанной фоновой активности; пока только deleteq (дожидается завершения процессов с указателями на удалённые файлы).
zfs project # управление привязкой файлов к проектам.
zfs program имя-пула имя-скрипта-LUA [параметры] # запуск скрипта на LUA 5.2; выполнение атомарное; ключи:
Для 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: количество объектов в очереди на удаление
Тестирование производительности сжатия проводилось в основном на сервере с 2 Intel Xeon CPU E5-2637 v2 @ 3.50GHz, по 4 ядра.
ncat -l 7777 | dd bs=400000k | zfs receive -vd -F \ -o atime=off -o relatime=off -o compression=zstd-4 -o dnodesize=auto -o devices=off -o overlay=off \ -o primarycache=metadata -o secondarycache=metadata -o special_small_blocks=4096 time_machine receiving full stream of time_machine@20140901 into time_machine@20140901 time zfs send -Lev -c -R time_machine@20140901 | ncat grid0001 7777 сразу после начала копирования второго снимка kernel:VERIFY3(rrd->bytes_read >= rwa->bytes_read) failed (1 >= 18446744073709551137) kernel:PANIC at dmu_recv.c:2684:receive_process_record() метод обхода: разбиваем пересылку на 2 части база (11.1 TiByte): time zfs send -Lev -c -R time_machine@20140901 zfs receive -vd -F -o ... time_machine изменения (12.0 TiByte): time zfs send -Lev -c -I @20140901 time_machine@20150325 zfs receive -vd time_machine "ncat -l 7777 | dd bs=400000k" заменяем на "mbuffer -I 7777 -m 1G -s 1048576" "ncat grid0001 7777" заменяем на "mbuffer -O grid0001:7777 -m 1G -s 1048576"
первая часть: NAME LUSED USED COMPRESS RATIO DEDUP time_machine 30.5T 11.2T zstd-3 2.76x on NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT time_machine 110801566302208 9576284876800 101225281425408 - - 0 8 1.28 ONLINE - dm-name-tm-data 110002702385152 9506872832000 100495829553152 - - 0 8 - ONLINE special - - - - - - - - - ata-INTEL_SSDSC2BB800G4_BTWL4135013B800RGN 798863917056 69412044800 729451872256 - - 16 8 - ONLINE полностью по 20150325: NAME LUSED USED COMPRESS RATIO DEDUP time_machine 71.3T 23.1T zstd-3 3.14x on NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT time_machine 110801566302208 18097695977472 92703870324736 - - 0 16 1.40 ONLINE - dm-name-tm-data 110002702385152 17783079010304 92219623374848 - - 0 16 - ONLINE special - - - - - - - - - ata-INTEL_SSDSC2BB800G4_BTWL4135013B800RGN 798863917056 314616967168 484246949888 - - 40 39 - ONLINE или NAME LUSED USED COMPRESS RATIO DEDUP time_machine 71.3T 23.1T zstd-3 3.14x on NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT time_machine 101T 16.5T 84.3T - - 0% 16% 1.40x ONLINE - dm-name-tm-data 100T 16.2T 83.9T - - 0% 16.2% - ONLINE special - - - - - - - - - ata-INTEL_SSDSC2BB800G4_BTWL4135013B800RGN 744G 293G 451G - - 40% 39.4% - ONLINE
полностью по 20150325: NAME USED COMPRESS RATIO DEDUP time_machine 23.0T zstd-4 3.13x on NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT time_machine 101T 16.4T 84.3T - - 0% 16% 1.40x ONLINE - dm-name-tm-data 100T 16.1T 84.0T - - 0% 16.0% - ONLINE special - - - - - - - - - sde 744G 388G 356G - - 46% 52.1% - ONLINE
база: NAME USED COMPRESS RATIO DEDUP time_machine 11.2T zstd-6 2.76x on NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT time_machine 101T 8.70T 92.1T - - 0% 8% 1.28x ONLINE - dm-name-tm-data 100T 8.64T 91.4T - - 0% 8.63% - ONLINE special - - - - - - - - - sde 744G 65.0G 679G - - 15% 8.73% - ONLINE
база: NAME LUSED USED COMPRESS RATIO DEDUP time_machine 30.5T 11.2T zstd-8 2.76x on NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT time_machine 101T 8.70T 92.1T - - 0% 8% 1.28x ONLINE - dm-name-tm-data 100T 8.64T 91.4T - - 0% 8.63% - ONLINE special - - - - - - - - - ata-INTEL_SSDSC2BB800G4_BTWL4135013B800RGN 744G 65.0G 679G - - 15% 8.73% - ONLINE
база: NAME LUSED USED COMPRESS RATIO DEDUP time_machine 30.5T 11.2T zstd-12 2.76x on NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT time_machine 101T 8.70T 92.1T - - 0% 8% 1.28x ONLINE - dm-name-tm-data 100T 8.63T 91.4T - - 0% 8.63% - ONLINE special - - - - - - - - - ata-INTEL_SSDSC2BB800G4_BTWL4135013B800RGN 744G 64.8G 679G - - 13% 8.70% - ONLINE суммарно по 20150325: NAME LUSED USED COMPRESS RATIO DEDUP time_machine 71.3T 23.0T zstd-12 3.14x on NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT time_machine 101T 16.4T 84.3T - - 0% 16% 1.40x ONLINE - dm-name-tm-data 100T 16.2T 83.9T - - 0% 16.1% - ONLINE special - - - - - - - - - ata-INTEL_SSDSC2BB800G4_BTWL4135013B800RGN 744G 293G 451G - - 38% 39.4% - ONLINE .................................................................................................................. rsync с фильтрацией ненужного, recsize=16MB (блоки размером более 128KB занимают 95% места) база: NAME LUSED USED COMPRESS RATIO DEDUP bigpool/time_machine 28.3T 9.62T zstd-12 2.97x sha256 NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT bigpool 10.1T 7.63T 2.51T - - 3% 75% 1.26x ONLINE - scsi-3600605b008ca05c026d2c13b2b9980bc 3.27T 2.53T 752G - - 2% 77.5% - ONLINE scsi-3600605b008ca0520270f5bb8e7efaf61 4.08T 2.69T 1.39T - - 1% 65.9% - ONLINE scsi-3600605b008ca050026501b76a5a7dd68 2.45T 2.36T 93.2G - - 9% 96.3% - ONLINE special - - - - - - - - - nvme0n1 348G 51.2G 297G - - 26% 14.7% - ONLINE Block Size Histogram block psize lsize asize size Count Size Cum. Count Size Cum. Count Size Cum. 512: 19.9M 9.96G 9.96G 19.9M 9.96G 9.96G 0 0 0 1K: 9.24M 11.0G 21.0G 9.24M 11.0G 21.0G 0 0 0 2K: 7.60M 20.0G 40.9G 7.60M 20.0G 40.9G 0 0 0 4K: 17.0M 68.7G 110G 7.36M 38.4G 79.3G 47.1M 188G 188G 8K: 4.48M 41.4G 151G 4.93M 55.0G 134G 10.9M 95.3G 284G 16K: 1.74M 35.7G 187G 6.41M 125G 259G 1.92M 38.4G 322G 32K: 877K 36.9G 224G 2.44M 107G 365G 895K 37.3G 359G 64K: 704K 61.2G 285G 1.63M 141G 506G 715K 61.7G 421G 128K: 471K 82.5G 367G 1.12M 188G 694G 480K 83.6G 505G 256K: 364K 130G 498G 635K 235G 929G 365K 131G 635G 512K: 412K 302G 800G 471K 320G 1.22T 413K 302G 938G 1M: 439K 636G 1.40T 299K 420G 1.63T 438K 635G 1.54T 2M: 377K 991G 2.37T 273K 780G 2.39T 378K 992G 2.50T 4M: 158K 872G 3.22T 176K 1007G 3.37T 159K 872G 3.36T 8M: 156K 1.72T 4.94T 133K 1.43T 4.81T 156K 1.72T 5.08T 16M: 313K 4.89T 9.83T 1.56M 25.0T 29.8T 313K 4.89T 9.97T септимация (оставляем только воскресные снимки) экономит 10%
rsync с фильтрацией ненужного, recsize=16MB база: NAME LUSED USED COMPRESS RATIO DEDUP bigpool/time_machine 28.3T 9.58T zstd-14 2.99x sha256 NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT bigpool 119T 7.60T 111T - - 0% 6% 1.26x ONLINE - tm 118T 7.55T 111T - - 0% 6.38% - ONLINE special - - - - - - - - - ata-INTEL_SSDSC2BB800G4_BTWL4135013B800RGN 744G 51.1G 693G - - 11% 6.86% - ONLINE суммарно по 20150325: NAME LUSED USED COMPRESS RATIO DEDUP bigpool/time_machine 66.7T 20.3T zstd-14 3.33x sha256 NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT bigpool 119T 13.6T 105T - - 0% 11% 1.49x ONLINE - tm 118T 13.4T 105T - - 0% 11.3% - ONLINE special - - - - - - - - - ata-INTEL_SSDSC2BB800G4_BTWL4135013B800RGN 744G 184G 560G - - 31% 24.7% - ONLINE
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 позволяет узнать полезную информацию о текущем состоянии ZFS, базовые ключи ("-L" - не делать проверок):
bp count: 9491559 ganged count: 0 bp logical: 2377513919488 avg: 250487 bp physical: 829797686272 avg: 87424 compression: 2.87 bp allocated: 844293709824 avg: 88952 compression: 2.82 bp deduped: 144363376640 ref>1: 577485 deduplication: 1.17 SPA allocated: 700137218048 used: 7.08% additional, non-pointer bps of type 0: 819384 Dittoed blocks on same vdev: 797739 Blocks LSIZE PSIZE ASIZE avg comp %Total Type 8.98K 37.3M 36.2M 109M 12.1K 1.03 0.01 SPA space map 222K 3.46G 894M 1.75G 8.06K 3.97 0.22 DMU dnode 7.51M 2.16T 771G 780G 104K 2.87 99.15 ZFS plain file 1.19M 1.04G 457M 3.37G 2.82K 2.33 0.43 ZFS directory 122K 489M 489M 1.43G 12.0K 1.00 0.18 DDT ZAP algorithm 266 1.26M 1.04M 3.13M 12.0K 1.21 0.00 deferred free 9.05M 2.16T 773G 786G 86.9K 2.87 100.00 Total
zdb не согласует свои действия с модулем ядра, при активном использовании может показывать и делать всякое.
zfs_ids_to_path имя-пула идентификатор-набора идентификатор-объекта - преобразовать идентификаторы в имя файла и путь.
zinject - создаёт искусственные проблемы в пуле ZFS симулируя повреждение данных и сбой устройств.
arc_summary (ранее arc_summary.py) - статистика использования ARC. Ключи:
arcstat интервал количество (ранее arcstat.py) - iostat для кеша. Ключи:
dbufstat (ранее dbufstat.py) - статистика (ключ "-t") и содержимое объектов в памяти. Ключи:
zilstat - скрипт на python. Ключи:
Заглушка fsck.zfs. Некоторые дистрибутивы хотят утилиту fsck для каждого типа файловой системы, но имеющийся в ZFS scrub работает для всего пула и довольно долго, поэтому предоставляется заглушка в виде fsck.zfs, которая запрашивает текущий статус пула и может вернуть 4 (пул деградировал) и 8 (пул неисправен).
mount.zfs имя точка-монтирования - вспомогательная утилита для монтирования снимков или файловой системы в режиме mountpoint=legacy (/etc/fstab). Рекомендуется использовать mount или "zfs mount". Ключи:
zgenhostid - создать файл /etc/hostid и записать в него идентификатор хоста (бинарные случайные данные). Идентификатор хоста требуется для экспорта и импорта пула. См. параметры модуля spl: spl_hostid (0 - не использовать или случайное число?) и spl_hostid_path (/etc/hostid). Пакет initscripts имеет утилиту genhostid, которая делает тоже самое и утилиту hostid, которая выводит идентификатор хоста в виде IP адреса с переставленными байтами.
zpios - стресс-тестирование DMU.
zstream (она же zstreamdump) позволяет манипулировать потоком, создаваемым "zfs send", на стандартном вводе:
ztest - тесты регрессии для ZFS.
raidz_test - тест RAID-Z.
zvol_wait - ожидание появления блочных устройств в /dev/zvol после импорта пула.
Видимо, в Solaris нет udev и пришлось делать своё. vdev_id (vdev_id.8) используя /etc/zfs/vdev_id.conf (vdev_id.conf.5) создаёт "правильные" имена для устройств хранения в /dev/disk/by-vdev. Предлагаются примеры для multipath, sas_direct, sas_switch и scsi.
Используется в Linux подсистемой udev, для которой предоставляются правила udev в /usr/lib/udev/rules.d/: 60-zvol.rules (имена томов для блочных устройств в /dev/zvol/), 69-vdev.rules (слоты корзины) и 90-zfs.rules (загрузка модуля zfs).
Модули ядра генерируют сообщения (zpool-events.8) при наступлении событий. Сообщения обрабатываются сервисом zed (zed.8, ZFS Event Daemon), вызывает скрипты (bash), которые хранятся в /etc/zfs/zed.d/ (ссылки на /usr/libexec/zfs/zed.d/). Настройки: /etc/zfs/zed.d/zed.rc. Сигнал SIGHUP вызывает реконфигурацию сервиса. Мешает выгружать модуль zfs.
Службы (/usr/lib/systemd/system/) systemd (настройки в /usr/lib/systemd/system-preset/50-zfs.preset):
Цели: zfs.target (из multi-user.target), zfs-import.target (из zfs.target), zfs-volumes.target (из zfs.target, после zfs-volume-wait.service).
zfs-mount-generator - генератор юнитов systemd.mount(5) исходя из свойств наборов данных (mountpoint не legacy или none, canmount не off), обрабатывает noauto, atime=, relatime=, devices=, exec=, readonly=, setuid=, nbmand=. Хранит кеш в /etc/zfs/zfs-list.cache/poolname (не обнаружил). Тестовый пример не пройден.
Выделенный сервер архива без дедупликации: 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:При этом счётчик переданных байт застыл на 4.33TB, mpaths209 имеет 100% загрузки на случайной записи, "zpool destroy tm_tiny" не остановил случайную запись.[ ] 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]
Оказалось, что приёмник нельзя трогать до окончания передачи. Запустил заново с 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, но не успевает освободить (фрагментированность?), попытки понять и попбороть:
cgcreate -g memory:backup echo 4G > /sys/fs/cgroup/memory/backup/memory.limit_in_bytes # /sys/fs/cgroup/memory/backup/memory.memsw.limit_in_bytes # /sys/fs/cgroup/memory/backup/memory.kmem.limit_in_bytes echo номер-порождающего-процесса > /sys/fs/cgroup/memory/backup/tasks cache по-прежнему 55ГБ, а процессы из backup ни разу не упёрлись в 4ГБ cat /sys/fs/cgroup/memory/backup/memory.max_usage_in_bytes 3098968064 Опробовал методику на tarnull_common_all.sh - всё моментально умерло. Вывод - rsync в отличие от tar не раздувает системный страничный кеш при использовании zfs.
ARC Size: 122.06% 34.10 GiB Target Size: (Adaptive) 100.00% 27.94 GiB Min Size (Hard Limit): 0.11% 32.00 MiB Max Size (High Water): 894:1 27.94 GiB
В порыве борьбы за память: 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):
ncat -l номер-порта | zfs receive -vd -F tm_tiny receiving full stream of tm_small@20140801 into tm_tiny@20140801 received 26.7TB stream in 541046 seconds (51.7MB/sec) receiving incremental stream of tm_small@20140802 into tm_tiny@20140802 received 2.22TB stream in 169347 seconds (13.8MB/sec) receiving incremental stream of tm_small@20140803 into tm_tiny@20140803 received 176GB stream in 18100 seconds (9.97MB/sec)
zfs send -R -Le -v tm_small@20140803 | ncat имя-хоста номер-порта
Измерение скорости 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% по файлам, объёму и времени):
tm_tiny dedupratio 1.52x tm_tiny allocated 2297839255552 tm_tiny compressratio 3.69x zdb -L -bb tm_tiny bp count: 27461345 ganged count: 0 bp logical: 12836056087552 avg: 467422 bp physical: 3460343874560 avg: 126007 compression: 3.71 bp allocated: 3492625645568 avg: 127183 compression: 3.68 bp deduped: 1195390554112 ref>1: 2330471 deduplication: 1.34 SPA allocated: 2297235091456 used: 23.21% 591K 9.24G 2.37G 4.73G 8.19K 3.91 0.15 DMU dnode 22.3M 11.5T 3.12T 3.13T 144K 3.70 98.67 ZFS plain file 2.72M 2.36G 958M 6.60G 2.43K 2.52 0.20 ZFS directory 359K 1.40G 1.40G 4.21G 12.0K 1.00 0.13 DDT ZAP algorithm
tm_tiny dedupratio 1.52x tm_tiny allocated 2238066040832 tm_tiny compressratio 3.76x zdb -L -bb tm_tiny bp count: 27358848 ganged count: 0 bp logical: 12692608460288 avg: 463930 bp physical: 3369596236800 avg: 123162 compression: 3.77 bp allocated: 3402076622848 avg: 124350 compression: 3.73 bp deduped: 1164010582016 ref>1: 2297326 deduplication: 1.34 SPA allocated: 2238066040832 used: 22.46% additional, non-pointer bps of type 0: 2014185 Dittoed blocks on same vdev: 1946556 Blocks LSIZE PSIZE ASIZE avg comp %Total Type 583K 9.11G 2.32G 4.65G 8.17K 3.92 0.15 DMU dnode 22.3M 11.5T 3.06T 3.08T 141K 3.77 99.44 ZFS plain file 2.78M 2.50G 1.00G 7.03G 2.53K 2.49 0.22 ZFS directory 356K 1.39G 1.39G 4.17G 12.0K 1.00 0.13 DDT ZAP algorithm
tm_tiny dedupratio 1.52x - tm_tiny allocated 2205571149824 - tm_tiny compressratio 3.82x - zdb -L -bb tm_tiny bp count: 27397056 ganged count: 0 bp logical: 12693392496640 avg: 463312 bp physical: 3318542690304 avg: 121127 compression: 3.82 bp allocated: 3351140884480 avg: 122317 compression: 3.79 bp deduped: 1145675202560 ref>1: 2297343 deduplication: 1.34 SPA allocated: 2205465681920 used: 22.13% additional, non-pointer bps of type 0: 2010967 Dittoed blocks on same vdev: 1988016 Blocks LSIZE PSIZE ASIZE avg comp %Total Type 594K 9.29G 2.37G 4.75G 8.18K 3.91 0.15 DMU dnode 22.3M 11.5T 3.01T 3.03T 139K 3.83 99.42 ZFS plain file 2.81M 3.10G 1.19G 7.30G 2.60K 2.59 0.23 ZFS directory 356K 1.39G 1.39G 4.17G 12.0K 1.00 0.13 DDT ZAP algorithm
tm_tiny dedupratio 1.52x tm_tiny allocated 2152938479616 tm_tiny compressratio 3.92x zdb -L -bb tm_tiny bp count: 27395425 ganged count: 0 bp logical: 12693344324608 avg: 463338 bp physical: 3232032728576 avg: 117977 compression: 3.93 bp allocated: 3264629395456 avg: 119166 compression: 3.89 bp deduped: 1111690915840 ref>1: 2297343 deduplication: 1.34 SPA allocated: 2152938479616 used: 21.61% additional, non-pointer bps of type 0: 2010949 Dittoed blocks on same vdev: 1986403 Blocks LSIZE PSIZE ASIZE avg comp %Total Type 10.6K 1.30G 383M 1.12G 109K 3.47 0.04 bpobj 591K 9.24G 2.36G 4.72G 8.17K 3.91 0.16 DMU dnode 22.3M 11.5T 2.93T 2.95T 135K 3.93 99.41 ZFS plain file 2.81M 3.10G 1.19G 7.30G 2.60K 2.59 0.24 ZFS directory 356K 1.39G 1.39G 4.17G 12.0K 1.00 0.14 DDT ZAP algorithm
tm_tiny dedupratio 1.51x tm_tiny allocated 2115582078976 tm_tiny compressratio 3.99x zdb -L -bb tm_tiny bp count: 27398580 ganged count: 0 bp logical: 12693376887808 avg: 463285 bp physical: 3170244653568 avg: 115708 compression: 4.00 bp allocated: 3202858401792 avg: 116898 compression: 3.96 bp deduped: 1087276322816 ref>1: 2297343 deduplication: 1.34 SPA allocated: 2115582078976 used: 21.23% additional, non-pointer bps of type 0: 2010922 Dittoed blocks on same vdev: 1989585 Blocks LSIZE PSIZE ASIZE avg comp %Total Type 10.6K 1.30G 383M 1.12G 109K 3.47 0.04 bpobj 593K 9.26G 2.37G 4.73G 8.17K 3.91 0.16 DMU dnode 22.3M 11.5T 2.88T 2.90T 133K 4.01 99.39 ZFS plain file 2.81M 3.10G 1.19G 7.30G 2.60K 2.59 0.24 ZFS directory 356K 1.39G 1.39G 4.17G 12.0K 1.00 0.14 DDT ZAP algorithm
tm_tiny dedupratio 1.51x - - tm_tiny allocated 2093273051136 - tm_tiny compressratio 4.04x - zdb -L -bb tm_tiny bp count: 27399984 ganged count: 0 bp logical: 12693435492352 avg: 463264 bp physical: 3134082138624 avg: 114382 compression: 4.05 bp allocated: 3166689935360 avg: 115572 compression: 4.01 bp deduped: 1073416884224 ref>1: 2297343 deduplication: 1.34 SPA allocated: 2093273051136 used: 21.01% additional, non-pointer bps of type 0: 2010936 Dittoed blocks on same vdev: 1990975 Blocks LSIZE PSIZE ASIZE avg comp %Total Type 10.6K 1.30G 382M 1.12G 108K 3.48 0.04 bpobj 597K 9.33G 2.38G 4.77G 8.18K 3.91 0.16 DMU dnode 22.3M 11.5T 2.84T 2.86T 131K 4.05 99.39 ZFS plain file 2.81M 3.10G 1.19G 7.30G 2.60K 2.59 0.25 ZFS directory 356K 1.39G 1.39G 4.17G 12.0K 1.00 0.14 DDT ZAP algorithm
tm_tiny dedupratio 1.51x - tm_tiny allocated 2083115761664 tm_tiny compressratio 4.06x zdb -L -bb tm_tiny bp count: 27405209 ganged count: 0 bp logical: 12693558216704 avg: 463180 bp physical: 3117394068992 avg: 113751 compression: 4.07 bp allocated: 3150006472704 avg: 114941 compression: 4.03 bp deduped: 1066925805568 ref>1: 2297343 deduplication: 1.34 SPA allocated: 2083080667136 used: 20.91% additional, non-pointer bps of type 0: 2011108 Dittoed blocks on same vdev: 1996028 Blocks LSIZE PSIZE ASIZE avg comp %Total Type 10.6K 1.30G 381M 1.12G 108K 3.49 0.04 bpobj 605K 9.45G 2.42G 4.83G 8.17K 3.91 0.16 DMU dnode 22.3M 11.5T 2.83T 2.85T 131K 4.07 99.38 ZFS plain file 2.81M 3.10G 1.19G 7.30G 2.60K 2.59 0.25 ZFS directory 356K 1.39G 1.39G 4.17G 12.0K 1.00 0.14 DDT ZAP algorithm
tm_tiny dedupratio 1.51x tm_tiny allocated 2070754635776 - tm_tiny compressratio 4.09x zdb -L -bb tm_tiny bp count: 27419302 ganged count: 0 bp logical: 12693815265280 avg: 462951 bp physical: 3097623001600 avg: 112972 compression: 4.10 bp allocated: 3130284740608 avg: 114163 compression: 4.06 bp deduped: 1059530104832 ref>1: 2297343 deduplication: 1.34 SPA allocated: 2070754635776 used: 20.78% additional, non-pointer bps of type 0: 2011052 Dittoed blocks on same vdev: 2010177 Blocks LSIZE PSIZE ASIZE avg comp %Total Type 10.6K 1.30G 380M 1.11G 108K 3.51 0.04 bpobj 621K 9.7G 2.48G 4.95G 8.17K 3.92 0.17 DMU dnode 22.3M 11.5T 2.81T 2.83T 130K 4.10 99.38 ZFS plain file 2.81M 3.10G 1.19G 7.30G 2.60K 2.59 0.25 ZFS directory 356K 1.39G 1.39G 4.17G 12.0K 1.00 0.14 DDT ZAP algorithm
tm_tiny size 9964324126720 - tm_tiny free 7895386644480 tm_tiny dedupratio 1.51x - tm_tiny allocated 2068940627968 - tm_tiny compressratio 4.09x zdb -L -bb tm_tiny bp count: 27426552 ganged count: 0 bp logical: 12693967185920 avg: 462834 bp physical: 3094907451392 avg: 112843 compression: 4.10 bp allocated: 3127586385920 avg: 114034 compression: 4.06 bp deduped: 1058648903680 ref>1: 2297343 deduplication: 1.34 SPA allocated: 2068937482240 used: 20.76% additional, non-pointer bps of type 0: 2011058 Dittoed blocks on same vdev: 2017421 Blocks LSIZE PSIZE ASIZE avg comp %Total Type 10.6K 1.30G 379M 1.11G 107K 3.52 0.04 bpobj 630K 9.8G 2.51G 5.03G 8.17K 3.92 0.17 DMU dnode 22.3M 11.5T 2.81T 2.83T 130K 4.10 99.37 ZFS plain file 2.81M 3.10G 1.19G 7.30G 2.60K 2.59 0.25 ZFS directory 355K 1.39G 1.39G 4.16G 12.0K 1.00 0.14 DDT ZAP algorithm
tm_tiny size 11957188952064 tm_tiny free 9334419812352 tm_tiny dedupratio 1.54x tm_tiny allocated 2622769139712 tm_tiny compressratio 4.04x zdb -L -bb tm_tiny bp count: 27404976 ganged count: 0 bp logical: 12693421692928 avg: 463179 bp physical: 3134099891712 avg: 114362 compression: 4.05 bp allocated: 4014333050880 avg: 146481 compression: 3.16 bp deduped: 1391563911168 ref>1: 2297343 deduplication: 1.35 SPA allocated: 2622769139712 used: 21.93% additional, non-pointer bps of type 0: 2011046 Dittoed blocks on same vdev: 1995857 Blocks LSIZE PSIZE ASIZE avg comp %Total Type 10.6K 1.30G 381M 1.67G 162K 3.49 0.04 bpobj 594K 9.28G 2.37G 14.2G 24.5K 3.92 0.38 DMU dnode 22.3M 11.5T 2.84T 3.60T 165K 4.05 98.59 ZFS plain file 2.81M 3.10G 1.19G 21.9G 7.79K 2.59 0.59 ZFS directory 356K 1.39G 1.39G 12.5G 36.0K 1.00 0.33 DDT ZAP algorithm scrub: 2.17T scanned out of 2.39T at 85.0M/s, 0h44m to go Используемый SAN (Xyratex RS-1220-F4-5412E-DL-2) имеет аппаратное ограничение - FC 4Gb tarnull для 20160101: 2 потока - 117 MB/s 4 потока - 162 MB/s 6 потоков - 192 MB/s 8 потоков - 206 MB/s 10 потоков - 215 MB/s 12 потоков - 216 MB/s 16 потоков - 216 MB/s 20 потоков - 241 MB/s tarnull для 20160304 10 потоков - 219 MB/s 12 потоков - 220 MB/s 16 потоков - 218 MB/s 20 потоков - 246 MB/s tarnull для 20160304 (0.7.0-rc3) 2 потока - 166 MB/s 4 потока - 228 MB/s 6 потоков - 262 MB/s 8 потоков - 283 MB/s 10 потоков - 295 MB/s 12 потоков - 300 MB/s 16 потоков - 301 MB/s 20 потоков - 302 MB/s tarnull для 20160304 на сервере (0.7.0-rc3) с vdev для массива LSI MegaRAID RAID-6 из 15 SFF SAS 10k rpm, наполнение "send -cLeRp" 1 поток - 259 MB/s 2 потока - 418 MB/s 4 потока - 615 MB/s 6 потоков - 800 MB/s 8 потоков - 864 MB/s 10 потоков - 854 MB/s 12 потоков - 848 MB/s 16 потоков - 865 MB/s 20 потоков - 813 MB/s
zpool get -p size,free,allocated,dedupratio NAME PROPERTY VALUE SOURCE tm_tiny size 11957188952064 - tm_tiny free 9334041636864 - tm_tiny allocated 2623147315200 - tm_tiny dedupratio 1.54 - zfs get compressratio tm_tiny NAME PROPERTY VALUE SOURCE tm_tiny compressratio 4.04x - zdb -L -bb tm_tiny bp count: 27415469 ganged count: 0 bp logical: 12693457568256 avg: 463003 bp physical: 3134138611200 avg: 114320 compression: 4.05 bp allocated: 4014709604352 avg: 146439 compression: 3.16 bp deduped: 1391563911168 ref>1: 2297343 deduplication: 1.35 SPA allocated: 2623145693184 used: 21.94% additional, non-pointer bps of type 0: 2011122 Dittoed blocks on same vdev: 2006537 Blocks LSIZE PSIZE ASIZE avg comp %Total Type 10.5K 1.29G 377M 1.66G 161K 3.51 0.04 bpobj 76.3K 315M 307M 2.70G 36.3K 1.02 0.07 SPA space map 594K 9.28G 2.37G 14.2G 24.5K 3.92 0.38 DMU dnode 22.3M 11.5T 2.84T 3.60T 165K 4.05 98.58 ZFS plain file 2.81M 3.10G 1.19G 21.9G 7.79K 2.59 0.59 ZFS directory 356K 1.39G 1.39G 12.5G 36.0K 1.00 0.33 DDT ZAP algorithm 26.1M 11.5T 2.85T 3.65T 143K 4.05 100.00 Total tarnull для 20160304 (0.7.0-rc3) 12 потоков - 267 MB/s 16 потоков - 269 MB/s 20 потоков - 270 MB/s после повторного наполнения send/receive без проблем (а также 35000000 в zfs_arc_max и zfs_arc_meta_limit) tarnull для 20160304 (0.7.0-rc3) 1 поток - 121 MB/s 2 потока - 170 MB/s 4 потока - 236 MB/s 6 потоков - 270 MB/s 8 потоков - 291 MB/s 10 потоков - 299 MB/s 12 потоков - 303 MB/s 16 потоков - 304 MB/s 20 потоков - 295 MB/s
zpool get -p size,free,allocated,dedupratio NAME PROPERTY VALUE SOURCE tm_tiny size 11957188952064 - tm_tiny free 8727653990400 - tm_tiny allocated 3229534961664 - # перерасход в 1.5428 раза tm_tiny dedupratio 1.53 - zfs get compressratio tm_tiny NAME PROPERTY VALUE SOURCE tm_tiny compressratio 4.04x - zdb -L -bb tm_tiny bp count: 27445179 ganged count: 0 bp logical: 12693582608384 avg: 462506 bp physical: 3134269475840 avg: 114201 compression: 4.05 bp allocated: 4922956111872 avg: 179374 compression: 2.58 bp deduped: 1693421150208 ref>1: 2297343 deduplication: 1.34 SPA allocated: 3229534961664 used: 27.01% additional, non-pointer bps of type 0: 2011126 Dittoed blocks on same vdev: 1060267 Blocks LSIZE PSIZE ASIZE avg comp %Total Type 10.5K 1.29G 384M 1.80G 175K 3.44 0.04 bpobj 79.9K 332M 322M 2.83G 36.3K 1.03 0.06 SPA space map 594K 9.28G 2.37G 14.2G 24.5K 3.91 0.31 DMU dnode 22.3M 11.5T 2.84T 4.42T 203K 4.05 98.82 ZFS plain file 2.81M 3.10G 1.19G 21.9G 7.79K 2.59 0.48 ZFS directory 381K 1.49G 1.49G 13.4G 36.0K 1.00 0.29 DDT ZAP algorithm скорость проверки удвоилась scan: scrub in progress since Thu Apr 20 07:10:51 2017 2.93T scanned out of 2.94T at 159M/s, 0h1m to go 0 repaired, 99.61% done tarnull для 20160304 (0.7.0-rc3) 1 поток - 115 MB/s 2 потока - 167 MB/s 4 потока - 243 MB/s 6 потоков - 283 MB/s 8 потоков - 313 MB/s 10 потоков - 323 MB/s 12 потоков - 330 MB/s 16 потоков - 341 MB/s 20 потоков - 335 MB/s
zpool get -p size,free,allocated,dedupratio NAME PROPERTY VALUE SOURCE tm_tiny size 11957188952064 - tm_tiny free 7692747337728 - tm_tiny allocated 4264441614336 - # в 2.037 больше (в 1.2 для обычному RAID-6) tm_tiny dedupratio 1.52 - zfs get compressratio tm_tiny NAME PROPERTY VALUE SOURCE tm_tiny compressratio 4.04x - zdb -L -bb tm_tiny bp count: 27439175 ganged count: 0 bp logical: 12693555247616 avg: 462607 bp physical: 3134249929728 avg: 114225 compression: 4.05 bp allocated: 6477939830784 avg: 236083 compression: 1.96 bp deduped: 2213497663488 ref&1: 2297343 deduplication: 1.34 SPA allocated: 4264442167296 used: 35.66% additional, non-pointer bps of type 0: 2011134 Dittoed blocks on same vdev: 827925 Blocks LSIZE PSIZE ASIZE avg comp %Total Type 10.5K 1.29G 389M 2.36G 230K 3.40 0.04 bpobj 59.7K 249M 241M 2.12G 36.3K 1.03 0.04 SPA space map 594K 9.28G 2.37G 14.2G 24.5K 3.91 0.24 DMU dnode 22.3M 11.5T 2.84T 5.84T 268K 4.05 99.10 ZFS plain file 2.81M 3.10G 1.19G 21.9G 7.80K 2.59 0.36 ZFS directory 396K 1.55G 1.55G 13.9G 36.0K 1.00 0.23 DDT ZAP algorithm 26.2M 11.5T 2.85T 5.89T 231K 4.05 100.00 Total скорость проверки ещё возросла scan: scrub in progress since Mon Apr 24 00:40:55 2017 3.45T scanned out of 3.88T at 196M/s, 0h37m to go 0 repaired, 89.04% done tarnull для 20160304 (0.7.0-rc3) 1 поток - 97.7 MB/s 2 потока - 135 MB/s 4 потока - 197 MB/s 6 потоков - 235 MB/s 8 потоков - 268 MB/s 10 потоков - 285 MB/s 12 потоков - 299 MB/s 16 потоков - 314 MB/s 20 потоков - 305 MB/s
zpool get -p size,free,allocated,dedupratio NAME PROPERTY VALUE SOURCE tm_tiny size 11957188952064 - tm_tiny free 9863346946048 - tm_tiny allocated 2093842006016 - tm_tiny dedupratio 1.51 - zfs get compressratio tm_tiny NAME PROPERTY VALUE SOURCE tm_tiny compressratio 4.04x - zdb -L -bb tm_tiny 2.88T completed (8629MB/s) estimated time remaining: 566307hr 55min 16sec 294967261sec bp count: 27441235 ganged count: 0 bp logical: 12693576012800 avg: 462573 bp physical: 3134268470272 avg: 114217 compression: 4.05 bp allocated: 3167258890240 avg: 115419 compression: 4.01 bp deduped: 1073416884224 ref>1: 2297343 deduplication: 1.34 SPA allocated: 2093842006016 used: 17.51% additional, non-pointer bps of type 0: 2011164 Dittoed blocks on same vdev: 177854 Blocks LSIZE PSIZE ASIZE avg comp %Total Type 10.5K 1.29G 397M 1.16G 113K 3.33 0.04 bpobj 75.4K 322M 304M 911M 12.1K 1.06 0.03 SPA space map 594K 9.28G 2.37G 4.74G 8.18K 3.91 0.16 DMU dnode 22.3M 11.5T 2.84T 2.86T 131K 4.05 99.37 ZFS plain file 2.81M 3.10G 1.19G 7.30G 2.60K 2.59 0.25 ZFS directory 382K 1.49G 1.49G 4.47G 12.0K 1.00 0.15 DDT ZAP algorithm 26.2M 11.5T 2.85T 2.88T 113K 4.05 100.00 Total scan: scrub in progress since Thu Apr 27 13:23:40 2017 1.86T scanned out of 1.90T at 248M/s, 0h3m to go 0 repaired, 97.61% done tarnull для 20160304 (0.7.0-rc3) 1 поток - 113 MB/s 2 потока - 161 MB/s 4 потока - 251 MB/s 6 потоков - 308 MB/s 8 потоков - 353 MB/s 10 потоков - 375 MB/s 12 потоков - 403 MB/s 16 потоков - 421 MB/s 20 потоков - 416 MB/s
zpool get -p size,free,allocated,dedupratio NAME PROPERTY VALUE SOURCE tm_tiny size 5978594476032 - tm_tiny free 3884873994240 - tm_tiny allocated 2093720481792 - tm_tiny dedupratio 1.51 - zfs get compressratio tm_tiny NAME PROPERTY VALUE SOURCE tm_tiny compressratio 4.04x - zdb -L -bb tm_tiny bp count: 27432865 ganged count: 0 bp logical: 12693535600128 avg: 462712 bp physical: 3134227532288 avg: 114250 compression: 4.05 bp allocated: 3167137366016 avg: 115450 compression: 4.01 bp deduped: 1073416884224 ref>1: 2297343 deduplication: 1.34 SPA allocated: 2093720481792 used: 35.02% additional, non-pointer bps of type 0: 2011140 Dittoed blocks on same vdev: 519105 Blocks LSIZE PSIZE ASIZE avg comp %Total Type 10.5K 1.29G 391M 1.15G 111K 3.38 0.04 bpobj 69.9K 293M 282M 846M 12.1K 1.04 0.03 SPA space map 594K 9.28G 2.37G 4.74G 8.17K 3.91 0.16 DMU dnode 22.3M 11.5T 2.84T 2.86T 131K 4.05 99.37 ZFS plain file 2.81M 3.10G 1.19G 7.30G 2.60K 2.59 0.25 ZFS directory 379K 1.48G 1.48G 4.44G 12.0K 1.00 0.15 DDT ZAP algorithm 26.2M 11.5T 2.85T 2.88T 113K 4.05 100.00 Total scrub 1.88T scanned out of 1.90T at 128M/s, 0h3m to go 0 repaired, 98.84% done tarnull для 20160304 (0.7.0-rc3) 1 поток - 108 MB/s 2 потока - 164 MB/s 4 потока - 252 MB/s 6 потоков - 306 MB/s 8 потоков - 356 MB/s 10 потоков - 384 MB/s 12 потоков - 403 MB/s 16 потоков - 421 MB/s 20 потоков - 414 MB/s
В связи с проблемами в реализации дельта алгоритма в 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
Статистика по [почти] всему массиву данных при тестовом восстановлении (compression=lz4, dedup=on):
zfs get compressratio,logicalused;zpool get dedupratio restore NAME PROPERTY VALUE SOURCE restore compressratio 2.32x - restore logicalused 67.9T - NAME PROPERTY VALUE SOURCE restore dedupratio 1.38x -
Статистика по time_machine (compression=gzip-6, dedup=on, 1691 снимок):
NAME PROPERTY VALUE SOURCE time_machine compressratio 3.30x - time_machine logicalused 696T NAME PROPERTY VALUE SOURCE time_machine dedupratio 1.49x -
Время идёт, появляются новые возможности, выявляются недостатки. Например, нельзя исключить "вредные" файлы из экспорта потребителям. Выделенный сервер архива с дедупликацией: CentOS 7.9, zfs 2.1.7, 8 ядер по 3.5GHz, 128 ГиБ ОП, сеть 2x10 Gbps, локальный массив среднего размера (LSI MEGARAID RAID-6 of 18 HDD LFF 10 TB 7200 rpm и RAID-6 of 8 HDD LFF 10 TB 7200 rpm).
Параметры модуля spl (/etc/modprobe.d/spl.conf): отсутствуют.
Параметры модуля zfs (/etc/modprobe.d/zfs.conf):
# большой архив (300ТБ) с дедупликацией options zfs zfs_max_recordsize=16777216 # пусть импортирует из кеша options zfs zfs_autoimport_disable=1 # для исследования options zfs spa_load_print_vdev_tree=1 # от греха подальше options zfs ignore_hole_birth=1 # выделение свободного места options zfs metaslab_lba_weighting_enabled=0 options zfs spa_asize_inflation=3 #options zfs spa_slop_shift=6 options zfs spa_slop_shift=7 # архиву больше заняться нечем options zfs zio_taskq_batch_pct=85 # потеря части наливаемых данных не страшна options zfs zfs_txg_timeout=30 options zfs zfs_nocacheflush=1 options zfs zil_nocacheflush=1 # глубина очереди на MegaRAID и SSD может быть больше options zfs zfs_vdev_async_write_max_active=16 options zfs zfs_vdev_async_write_min_active=4 # всю память под кеш! #options zfs zfs_arc_max=80000000000 options zfs zfs_arc_max=40000000000 options zfs zfs_arc_meta_limit_percent=100 options zfs zfs_arc_average_blocksize=65536 options zfs zfs_arc_grow_retry=5 # и агрессивно чистить кеш options zfs zfs_arc_lotsfree_percent=5 options zfs zfs_arc_meta_prune=100000 options zfs zfs_scan_strict_mem_lim=1
Создание пула (оглавление на SSD, bin/zfs_tm.sh)
zpool create -f -o ashift=12 -o autoexpand=on \ -d \ -o feature@allocation_classes=enabled \ -o feature@async_destroy=enabled \ -o feature@bookmarks=enabled -o feature@bookmark_v2=enabled -o feature@bookmark_written=enabled \ -o feature@device_rebuild=enabled -o feature@device_removal=enabled \ -o feature@edonr=enabled -o feature@sha512=enabled -o feature@skein=enabled \ -o feature@embedded_data=enabled \ -o feature@empty_bpobj=enabled \ -o feature@enabled_txg=enabled -o feature@extensible_dataset=enabled \ -o feature@encryption=enabled \ -o feature@large_blocks=enabled \ -o feature@large_dnode=enabled \ -o feature@livelist=enabled \ -o feature@log_spacemap=enabled \ -o feature@lz4_compress=enabled -o feature@zstd_compress=enabled \ -o feature@redacted_datasets=enabled -o feature@redaction_bookmarks=enabled \ -o feature@resilver_defer=enabled \ -o feature@spacemap_histogram=enabled -o feature@spacemap_v2=enabled \ -o feature@zpool_checkpoint=enabled \ -O aclinherit=passthrough -O aclmode=passthrough -O acltype=posix -O xattr=sa \ -O atime=off -O relatime=off \ -O checksum=sha256 \ -O compression=zstd-12 \ -O dedup=sha256 \ -O dnodesize=legacy \ -O devices=off \ -O overlay=off \ -O primarycache=metadata -O secondarycache=metadata \ -O recordsize=16777216 \ -O redundant_metadata=none \ -O sharenfs=off -O sharesmb=off \ -O snapdir=visible \ -O special_small_blocks=0 \ -O sync=disabled -O logbias=throughput \ -O mountpoint=none \ bigpool /dev/data/tm /dev/data/tm2 special /dev/disk/by-id/ata-INTEL_SSDSC2KB038T8_PHYF020300AY3P8EGN zfs create bigpool/time_machine \ -o aclinherit=passthrough -o aclmode=passthrough -o acltype=posix -o xattr=sa \ -o atime=off -o relatime=off \ -o checksum=sha256 \ -o compression=zstd-12 \ -o dedup=sha256 \ -o dnodesize=legacy \ -o devices=off \ -o overlay=off \ -o primarycache=metadata -o secondarycache=metadata \ -o recordsize=16777216 \ -o redundant_metadata=none \ -o sharenfs=off -o sharesmb=off \ -o snapdir=visible \ -o special_small_blocks=0 \ -o sync=disabled -o logbias=throughput \ -o mountpoint=/time_machine mkdir /time_machine/{colddata,raid,share4h,share4s,share4x,share5c,share5d,share5e,share5f,xeon01,xeon04}
Наполнение архива с помощью rsync каталогами в параллель из предыдущего архива, дневная часть, делается клон (его можно почистить и экспортировать), полный суточный архив getall_snapshot.sh:
#!/bin/bash DATE=$1 echo $DATE snap=`ssh старый-архив ls -1d '/time_machine/.zfs/snapshot/'$DATE 2>&1` if [ "$snap" = "/time_machine/.zfs/snapshot/$DATE" ] then ls -1d /time_machine/*/*|awk -F/ '{print $3 "/" $4}' |LANG= sort > /tmp/getall.current.list (ssh старый-архив ls -1d '/time_machine/.zfs/snapshot/'$DATE'/*/*';)|awk -F/ '{print $6 "/" $7}'|LANG= sort > /tmp/getall.new.list LANG= comm -23 /tmp/getall.current.list /tmp/getall.new.list | awk '{print "/time_machine/" $1}' | xargs --verbose --no-run-if-empty --max-args=1 --max-procs=1 rm -r 2>&1 | cat --squeeze-blank > /root/rsync/rsync.$DATE.deleted.log rm /tmp/getall.current.list /tmp/getall.new.list if [ ! -s /root/rsync/rsync.$DATE.deleted.log ] then rm /root/rsync/rsync.$DATE.deleted.log fi (ssh старый-архив ls -d '/time_machine/.zfs/snapshot/'$DATE'/*/*'; )|awk -F/ '{print $5 "/" $6 "/" $7}' | xargs --verbose --max-args=1 --max-procs=20 getdir_snapshot.sh 2>&1 | xz > /root/rsync/rsync.$DATE.log.xz fi zfs snapshot bigpool/time_machine@$DATE zfs clone -o mountpoint=/clones/$DATE -p bigpool/time_machine@$DATE bigpool/clones/$DATE
копирование каталога getdir_snapshot.sh:
#!/bin/bash if [ -z "$1" ] then echo empty exit else DATE=`echo $1|awk -F/ '{print $1}'` DIR=`echo $1|awk -F/ '{print $2 "/" $3}'` FILESYSTEM=`echo $1|awk -F/ '{print $2}'` if [ -z `ssh старый-архив ls -ld /time_machine/.zfs/snapshot/$DATE/$DIR|grep '^d.*'|awk '{print $1}'` ]; then echo $DIR is nodir rm -rf /time_machine/$DIR else rsync --password-file=/root/rsync.password -vas -HAX --inplace --ignore-errors --delete --max-size=100G --exclude '*.da_vinci_code' --exclude '.mozilla/**/Cache' --exclude .Trash --exclude .local/share/Trash --exclude /temp/ --exclude .local/share/gvfs-metadata --exclude ... --delete-excluded --stats --whole-file --numeric-ids btrfs@старый-архив::time_machine_copy/$DATE/$DIR/ /time_machine/$DIR/ fi fi
Выделенный сервер архива с дедупликацией: CentOS 7.9 (8.9?), zfs 2.2.2, 36 ядер по 3.0GHz, 512 ГиБ ОП, сеть 2x40 Gbps, локальный массив большого размера (2 x LSI/Broadcom MegaRAID RAID-6 of 17 HDD SAS LFF 16 TB 7200 rpm) и зеркало из частей INTEL D7-P5620.
Сборка сервера SuperMicro SSG-640P-E1CR36L.
Настройка BIOS/UEFI SuperMicro X12DPi-NT6
Настройка контроллера LSI/Broadcom MegaRAID 9560-8i (суперконденсатор CV на месте):
/opt/MegaRAID/storcli/storcli64 /c0 set bios Mode=SOE # стоять, если что не так /opt/MegaRAID/storcli/storcli64 /c0 set coercion=0 # были проблемы с вычислениями /opt/MegaRAID/storcli/storcli64 /c0 set copyback=off type=all # без неожиданностей /opt/MegaRAID/storcli/storcli64 /c0 set dimmerswitch=off type=4 # не спать! /opt/MegaRAID/storcli/storcli64 /c0 start dpm # сбор статистики /opt/MegaRAID/storcli/storcli64 /c0 set foreignautoimport=off # без неожиданностей /opt/MegaRAID/storcli/storcli64 /c0 set loadbalancemode=on # хотя тут 1 порт /opt/MegaRAID/storcli/storcli64 /c0 set patrolread=off # везде CC /opt/MegaRAID/storcli/storcli64 /c0 set perfmode=1 # не поддерживается, но Support Perf Tuning = Yes
Создание массива
/opt/MegaRAID/storcli/storcli64 /c0 add vd type=raid6 size=all name=first drives=250:0-11,251:0-4 pdcache=off wb nora direct Strip=64 /opt/MegaRAID/storcli/storcli64 /c0 add vd type=raid6 size=all name=second drives=251:5-15,18-23 pdcache=off wb nora direct Strip=64 # и немедленно /opt/MegaRAID/storcli/storcli64 /c0/vall set autobgi=off /opt/MegaRAID/storcli/storcli64 /c0/vall start init full pvcreate /dev/sdc pvcreate /dev/sdd vgcreate data /dev/sdc /dev/sdd lvcreate -n tm --stripes 2 --stripesize 64K -l +100%FREE data
Раздел зеркала под special vdev на частях INTEL D7-P5620 (SSDPF2KE064T1, U.2, PCIe 4 x4, 3D TLC, 3DWPD - 35PBW, конденсаторы для защиты от пропадания питания на месте)
mdadm --create /dev/md/SSD --verbose --raid-devices=2 --level=raid1 --name=zfsmeta /dev/nvme0n1 /dev/nvme1n1 pvcreate /dev/md/SSD vgcreate SSD /dev/md/SSD lvcreate -n zfsmeta -L 2T SSD
Настройки системы:
modprobe acpi_cpufreq x86_energy_perf_policy performance for cpu in /sys/devices/system/cpu/cpu[0-9]* do echo performance > $cpu/cpufreq/scaling_governor done
Параметры модуля spl (/etc/modprobe.d/spl.conf): отсутствуют.
Параметры модуля zfs (/etc/modprobe.d/zfs.conf):
# у нас большие батальоны options zfs zfs_max_recordsize=16777216 # всё вручную options zfs zfs_autoimport_disable=1 # от греха подальше options zfs zfs_bclone_enabled=0 options zfs ignore_hole_birth=1 # для совместимости DDT с исходным архивом options zfs zstd_earlyabort_pass=0 # выделение свободного места options zfs metaslab_lba_weighting_enabled=0 options zfs spa_asize_inflation=3 options zfs spa_slop_shift=7 options zfs zfs_fallocate_reserve_percent=100 # архиву больше заняться нечем options zfs zio_taskq_batch_pct=85 # потеря части наливаемых в архив данных не страшна options zfs zfs_txg_timeout=30 options zfs zfs_nocacheflush=1 options zfs zil_nocacheflush=1 # глубина очереди на MegaRAID и SSD моожет быть больше options zfs zfs_vdev_async_write_max_active=16 options zfs zfs_vdev_async_write_min_active=4 options zfs zfs_vdev_sync_read_max_active=40 # всю память под кеш! ну не совсем options zfs zfs_arc_max=80000000000 options zfs zfs_arc_average_blocksize=65536 options zfs zfs_arc_grow_retry=5 # и агрессивно чистить кеш options zfs zfs_vdev_async_write_active_min_dirty_percent=10 # если интенсивное чтение (параллельный rsync) #options zfs zfs_prefetch_disable=1 options zfs zfs_scan_strict_mem_lim=1
Свойства пула:
-d \ -o feature@allocation_classes=enabled \ -o feature@async_destroy=enabled \ -o feature@device_removal=enabled \ -o feature@embedded_data=enabled \ -o feature@empty_bpobj=enabled \ -o feature@enabled_txg=enabled -o feature@extensible_dataset=enabled \ -o feature@head_errlog=enabled \ -o feature@large_blocks=enabled \ -o feature@large_dnode=enabled \ -o feature@livelist=enabled \ -o feature@log_spacemap=enabled \ -o feature@lz4_compress=enabled -o feature@zstd_compress=enabled \ -o feature@resilver_defer=enabled \ -o feature@spacemap_histogram=enabled -o feature@spacemap_v2=enabled \ -o feature@userobj_accounting=enabled \ -o feature@zpool_checkpoint=enabled \ -o ashift=12 -o autoexpand=on \ bigpool /dev/data/tm special /dev/SSD/zfsmeta
Свойства набора данных:
-O aclinherit=passthrough -O aclmode=passthrough -O acltype=posix -O xattr=sa \ -O atime=off -O relatime=off \ -O checksum=sha256 \ -O compression=zstd-12 \ -O dedup=sha256 \ -O dnodesize=legacy \ -O devices=off \ -O overlay=off \ -O primarycache=metadata -O secondarycache=none \ -O recordsize=16777216 \ -O redundant_metadata=none \ -O sharenfs=off -O sharesmb=off \ -O snapdir=visible \ -O special_small_blocks=0 \ -O sync=disabled -O logbias=throughput \ -O mountpoint=none \
Заливка копии по частям - цепочки снимков (основанные на снимках клоны не копируются):
имеются снимки и клоны с 20150101 по 20240131 zfs send -R -Lec bigpool/time_machine@20240131| mbuffer -O приёмник:7777 -m 1G -s 1048576 пул bigpool создан, а файловая система нет mbuffer -I 7777 -m 1G -s 1048576| zfs receive -vd -F -o aclinherit=passthrough -o aclmode=passthrough -o acltype=posix -o xattr=sa \ -o atime=off -o relatime=off -o checksum=sha256 -o compression=zstd-12 -o dedup=sha256 -o dnodesize=legacy -o devices=off \ -o overlay=off -o primarycache=metadata -o secondarycache=none -o recordsize=16777216 -o redundant_metadata=none\ -o sharenfs=off -o sharesmb=off -o snapdir=visible -o special_small_blocks=0 -o sync=disabled -o logbias=throughput \ -o mountpoint=/time_machine bigpool receiving full stream of bigpool/time_machine@20150101 into bigpool/time_machine@20150101 in @ 28.0 MiB/s, out @ 28.0 MiB/s, 11.2 TiB total, buffer 0% fullreceived 11.2T stream in 113336.17 seconds (104M/sec) receiving incremental stream of bigpool/time_machine@20150102 into bigpool/time_machine@20150102 in @ 53.9 MiB/s, out @ 49.9 MiB/s, 11.3 TiB total, buffer 0% fullreceived 29.1G stream in 145.54 seconds (205M/sec) ... summary: 374 TiByte in 464h 34min 55.0sec - average of 234 MiB/s # повторно с правильными настройками приёмника summary: 374 TiByte in 395h 20min 46.6sec - average of 275 MiB/s for DATE in `ls /time_machine/.zfs/snapshot/`; do zfs clone -o mountpoint=/clones/$DATE -p bigpool/time_machine@$DATE bigpool/clones/$DATE; done
Конечный результат
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT bigpool 439T 244T 195T - - 0% 55% 1.53x ONLINE - data/tm 437T 243T 194T - - 0% 55.6% - ONLINE special - - - - - - - - - SSD/zfsmeta 2T 941G 1.07T - - 39% 46.3% - ONLINE COMPRESS RATIO USED LUSED AVAIL zstd-12 3.42x 374T 1.24P 193T
DDT ~40GB в памяти
zdb -L -bb bigpool 374T completed (18186MB/s) bp count: 1428006631 ganged count: 0 bp logical: 1401826123974656 avg: 981666 bp physical: 408889790567424 avg: 286336 compression: 3.43 bp allocated: 411025536360448 avg: 287831 compression: 3.41 bp deduped: 0 ref>1: 0 deduplication: 1.00 bp cloned: 0 count: 0 Normal class: 266855525736448 used: 55.60% Special class 1011439149056 used: 46.36% Embedded log class 0 used: 0.00% additional, non-pointer bps of type 0: 155840545 Dittoed blocks on same vdev: 3253922 средний размер блока 287831 Blocks LSIZE PSIZE ASIZE avg comp %Total Type - - - - - - - unallocated 2 32K 8K 24K 12K 4.00 0.00 object directory 440 348K 248K 5.23M 12.2K 1.40 0.00 object array 1 16K 4K 12K 12K 4.00 0.00 packed nvlist - - - - - - - packed nvlist size 1.79M 229G 40.1G 120G 67.3K 5.70 0.03 bpobj - - - - - - - bpobj header - - - - - - - SPA space map header 28.3K 3.52G 187M 561M 19.8K 19.30 0.00 SPA space map - - - - - - - ZIL intent log 86.6M 1.68T 433G 433G 5.00K 3.99 0.11 DMU dnode 3.23K 12.9M 12.9M 12.9M 4.00K 1.00 0.00 DMU objset - - - - - - - DSL directory 3.27K 2.09M 176K 540K 165 12.13 0.00 DSL directory child map 3.27K 2.09M 176K 528K 161 12.16 0.00 DSL dataset snap map 6.49K 104M 25.9M 77.8M 12.0K 4.00 0.00 DSL props - - - - - - - DSL dataset - - - - - - - ZFS znode - - - - - - - ZFS V0 ACL 1.03G 1.24P 371T 373T 363K 3.43 99.76 ZFS plain file 196M 451G 90.4G 207G 1.05K 4.99 0.05 ZFS directory 3 1.50K 1.50K 16K 5.33K 1.00 0.00 ZFS master node - - - - - - - ZFS delete queue - - - - - - - zvol object - - - - - - - zvol prop - - - - - - - other uint8[] - - - - - - - other uint64[] - - - - - - - other ZAP - - - - - - - persistent error log 294 36.8M 2.47M 7.41M 25.8K 14.89 0.00 SPA history - - - - - - - SPA history offsets - - - - - - - Pool properties - - - - - - - DSL permissions - - - - - - - ZFS ACL - - - - - - - ZFS SYSACL - - - - - - - FUID table - - - - - - - FUID table size - - - - - - - DSL dataset next clones - - - - - - - scan work queue 6.45K 119M 38.7M 38.7M 6.00K 3.08 0.00 ZFS user/group/project used - - - - - - - ZFS user/group/project quota - - - - - - - snapshot refcount tags 1.17M 37.3G 22.3G 66.9G 57.4K 1.67 0.02 DDT ZAP algorithm 2 32K 12K 36K 18K 2.67 0.00 DDT statistics 23.2M 11.6G 11.6G 92.7G 4.00K 1.00 0.02 System attributes - - - - - - - SA master node 3 4.50K 4.50K 16K 5.33K 1.00 0.00 SA attr registration 8 128K 32K 40K 5K 4.00 0.00 SA attr layouts - - - - - - - scan translations - - - - - - - deduplicated block 53.7K 1.25G 389M 1.14G 21.8K 3.29 0.00 DSL deadlist map - - - - - - - DSL deadlist map hdr 23 464K 168K 504K 21.9K 2.76 0.00 DSL dir clones - - - - - - - bpobj subobj - - - - - - - deferred free - - - - - - - dedup ditto 9.74K 5.47M 51.5K 180K 18 108.71 0.00 other 1.33G 1.25P 372T 374T 281K 3.43 100.00 Total 314M 2.97T 618G 942G 3.00K 4.93 0.25 Metadata Total Block Size Histogram block psize lsize asize size Count Size Cum. Count Size Cum. Count Size Cum. 512: 335M 167G 167G 335M 167G 167G 0 0 0 1K: 165M 201G 368G 165M 201G 368G 0 0 0 2K: 124M 331G 699G 124M 331G 699G 0 0 0 4K: 343M 1.36T 2.04T 116M 624G 1.29T 955M 3.73T 3.73T 8K: 89.5M 821G 2.84T 93.8M 1.03T 2.32T 97.7M 882G 4.59T 16K: 35.8M 736G 3.56T 159M 2.90T 5.22T 36.4M 738G 5.31T 32K: 20.6M 874G 4.41T 52.3M 2.19T 7.41T 21.4M 912G 6.20T 64K: 12.8M 1.10T 5.52T 29.7M 2.61T 10.0T 13.8M 1.18T 7.38T 128K: 10.2M 1.81T 7.32T 28.6M 4.43T 14.4T 10.6M 1.87T 9.25T 256K: 11.1M 4.02T 11.3T 10.5M 3.73T 18.2T 11.2M 4.02T 13.3T 512K: 14.9M 10.9T 22.2T 7.89M 5.71T 23.9T 14.9M 10.9T 24.2T 1M: 15.1M 22.6T 44.8T 6.44M 9.08T 33.0T 15.1M 22.6T 46.7T 2M: 12.2M 32.6T 77.4T 5.49M 14.8T 47.7T 12.2M 32.7T 79.4T 4M: 7.09M 41.9T 119T 3.22M 18.5T 66.3T 7.09M 41.9T 121T 8M: 5.83M 66.2T 186T 2.36M 26.5T 92.7T 5.83M 66.2T 187T 16M: 11.6M 186T 372T 73.9M 1.15P 1.25P 11.6M 186T 374T zdb -L -MM bigpool vdev 0 metaslabs27940 fragmentation 0% 30: 4103 ******* 31: 57 * 32: 23779 **************************************** vdev 1 metaslabs 127 fragmentation 39% 12: 924926 ************* 13: 737630 ********** 14: 2954248 **************************************** 15: 1775606 ************************* 16: 1223379 ***************** 17: 724551 ********** 18: 437028 ****** 19: 274588 **** 20: 143446 ** 21: 49990 * 22: 10918 * 23: 1209 * 24: 8 *
|
Bog BOS: Файловая система ZFS |
Последние изменения: |