Пока делал все тесты и писал статью меня так и преследовало устойчивое выражение.
Когда коту делать нефиг, он яйца лижет.
Вот так и я.
Что имеем или наша лаба.
Для тестов я буду использовать Virtualbox 7.0.4 и установленные в ней виртуальные машины.
Host PC:
Intel Core i7-10510U CPU 1.80GHz / 2.30 GHz
4 CPU (8 CPU with HT)
32GB RAM
NVME Samsung SSD 970 EVO Plus 1TB
Windows Server 2022
2 vCPU
4GB RAM
Официальная документация по настройке deduplication доступна по ссылке:
https://learn.microsoft.com/en-us/windows-server/storage/data-deduplication/install-enable
Ubuntu Server 23.04 ZFS
2 vCPU
4GB RAM
Официальная документация по настройке ZFS deduplication доступна по ссылке:
https://ubuntu.com/tutorials/setup-zfs-storage-pool#1-overview
Ubuntu Server 23.04 BTRFS
2 vCPU
4GB RAM
Официальная документация по настройке BTRFS deduplication доступна по ссылкам:
https://btrfs.readthedocs.io/en/latest/Deduplication.html
https://github.com/Zygo/bees
Zabbix Appliance 6.4.3
2 vCPU
4GB RAM
Официальная документация доступна по ссылке:
https://www.zabbix.com/download_appliance
Размер датасета:
103.50 GB (111,144,359,353 bytes)
Внутри tar.gz архивы с бэкапами сайта.
Для мониторинга и сборки метрик мы будем использовать Zabbix Appliance, поднятый там же в VirtualBox.
Все машины объединены в общую NAT network для удобства работы Zabbix и проброса портов в хост машину.
Для минимального влияния просадки производительности хост машины все тесты я проводил поочередно, то есть включенными одновременно были только VM Zabbix и текущая VM с тестом дедупликации, другие 2 VM были выключены.
Два слова про дедупликацию как таковую:
Дедупликация данных - это процесс удаления дубликатов данных в базе данных или файловой системе. Дедупликация может помочь уменьшить размер базы данных или занимаемое место на дисковом массиве.
Под дедупликацией может подразумеваться сканирование файлов в файловой системе или записей в БД с последующим удалением одинаковых значений с или без создания ссылок на оставшееся уникальное значение.
Мне же интересна реализация уменьшения размера занимаемого места на дисках путем дедуплицирования на уровне блоков файловой системы так, что для пользователя визуально ничего не меняется, как были видны файлы на диске так и остались на тех же местах, но вот вместо условных 10GB стали занимать 5Gb.
Понеслась:
Linux ZFS
Ставим нужные пакеты:
sudo apt install zfsutils-linux
Проверяем, что бинарники были установлены в наши каталоги
~$ whereis zfs
zfs: /usr/bin/zfs /usr/sbin/zfs /etc/zfs /usr/share/zfs
Теперь добавим 2 диска - для тестов я буду использовать RAID0 пул для экономии места на ПК, в реальном использовании я крайне не рекомендую использовать RAID0, особенно для критичных данных, наподобие резервных копий.
Краткая справка о том, почему RAID0 может быть опасен:
RAID 0 (Redundant Array of Independent Disks 0) - это метод объединения нескольких физических дисков в логический объем с целью повышения производительности. Данные разбиваются на блоки и параллельно записываются на все диски в массиве, что позволяет достичь более высокой скорости передачи данных.
Однако важно отметить, что RAID 0 не предоставляет отказоустойчивости. Поскольку данные не дублируются и не используется информация о четности, отказ одного из дисков в массиве приводит к недоступности всего RAID 0 и потере данных. Если один диск выходит из строя, все данные, распределенные по всем дискам, становятся непригодными к использованию.
Поэтому RAID 0 применяется тогда, когда главным является повышение производительности, а отказоустойчивость не является приоритетом. Он наиболее полезен для задач, требующих высоких скоростей передачи данных, таких как обработка больших файлов или видеомонтаж.
Важно помнить, что при использовании RAID 0 необходимо регулярно создавать резервные копии данных, так как отказ даже одного диска может привести к потере всех данных на массиве.
Прежде чем добавить диски в виртуальную машину нам нужно ее отключить.
sudo shutdown now
Я добавляю 2 диска по 60 GB (объем тестового датасета чуть больше 100GB)
Вот что у нас должно получиться:
Включаем машину и проверяем, что добавленные диски видны в системе:
sudo fdisk -l
Мы должны увидеть следующий вывод:
Disk /dev/sdb: 60 GiB, 64424509440 bytes, 125829120 sectors
Disk model: VBOX HARDDISK
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk /dev/sdc: 60 GiB, 64424509440 bytes, 125829120 sectors
Disk model: VBOX HARDDISK
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Теперь создадим ZFS пул из 2х наших дисков.
sudo zpool create dedup-pool /dev/sdb /dev/sdc
Для создания RAID1 нужно также добавить keyword “mirror”, но для достижения нужного объема тогда потребуется N*2 количество дисков/места.
Какого-либо вывода мы не получим, но введя команду:
zpool list
Мы должны увидеть наш свежесозданный пул
~$ zpool list
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
dedup-pool 119G 110K 119G - - 0% 0% 1.00x ONLINE -
Так же мы можем проверить статус нашего пула командой:
sudo zpool status
Получаем вывод:
~$ sudo zpool status
pool: dedup-pool
state: ONLINE
config:
NAME STATE READ WRITE CKSUM
dedup-pool ONLINE 0 0 0
sdb ONLINE 0 0 0
sdc ONLINE 0 0 0
errors: No known data errors
Итак, ZFS пул мы создали, проверим, включена ли там дедупликация:
~$ sudo zfs get dedup dedup-pool
NAME PROPERTY VALUE SOURCE
dedup-pool dedup off default
По умолчанию дедупликация выключена, поэтому ее надо включить до перемещения данных на пул!
~$ sudo zfs set dedup=on dedup-pool
Немного о том, как работает дедупликация в ZFS:
ZFS выполняет дедупликацию на уровне блоков и не дедуплицирует данные, которые уже находятся на дисках.
Когда дедупликация в ZFS включена, она работает путем сравнения блоков данных, которые записываются на диск, с уже существующими блоками в таблице дедупликации. Если найдено совпадение, ZFS сохраняет ссылку на существующий блок вместо записи нового блока. Это позволяет снизить использование пространства хранения путем устранения избыточных блоков данных.
Однако ZFS не выполняет дедупликацию данных, которые уже присутствуют на дисках до включения дедупликации. Дедупликация применяется только к данным, записываемым в файловую систему после включения дедупликации. Это связано с тем, что выполнение дедупликации для уже существующих данных потребовало бы обширного и ресурсоемкого процесса сканирования и сравнения всех существующих блоков данных, что могло бы существенно повлиять на производительность.
Если вы хотите воспользоваться дедупликацией ZFS для существующих данных, то один из вариантов - скопировать данные на новую файловую систему ZFS с включенной дедупликацией, либо скопировать на временный диск и потом снова перенести в пул с включенной дедупликацией.
Так же есть интересная команда для просмотра назгрузки на пул и занятого места.
zpool iostat dedup-pool
~$ zpool iostat dedup-pool
capacity operations bandwidth
pool alloc free read write read write
---------- ----- ----- ----- ----- ----- -----
dedup-pool 110K 119G 0 0 32 2.09K
Закидывать датасет для дедупликации я буду используя возможности VirtualBox shared folders (не забудьте установить guest tools в VM до монтирования директории).
Перезагружаем нашу VM и видим нужные нам директории:
$ cd /
$ ls | grep -i "ff_bak\|dedup"
dedup-pool
ff_bak
$ ls /dedup-pool/
$ sudo ls -la /ff_bak
total 221
drwxrwx--- 1 root vboxsf 131072 Jun 5 16:05 .
drwxr-xr-x 21 root root 4096 Jun 9 12:25 ..
drwxrwx--- 1 root vboxsf 0 Jun 5 16:04 20221116
drwxrwx--- 1 root vboxsf 0 Jun 5 16:04 20221119
…
Так же проверим размер содержимого чтобы знать как оно у нас сожмется:
$ sudo du -sh /ff_bak
104G /ff_bak
$ sudo du -s /ff_bak
108540471 /ff_bak
Копируем все содержимое из каталога /ff_bak
И сразу видим, как подскакивает нагрузка на диски
И так датасет скопирован, смотрим что у нас со статистикой zpool:
~$ zpool list
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
dedup-pool 119G 104G 15.4G - - 2% 87% 1.00x ONLINE -
Специально для тестирования деградации скорости копирования датасета я провел первое копирование на пул когда опция дедупликации была выключена:
Данные скопировались примерно за 18 минут, а вот с дедупликацией потребовалось уже около 30:
Так же посмотрим на процессор:
Процессору так же сложнее, он загружен операциями связанными с дедупликацией.
По оперативной памяти особой разницы нет, у нас довольно небольшой датасет, на графике видны небольшие подергивания когда работает система дедупликации, но на этом все отличия заканчиваются.
Но вот где те самые отличия, ради которых все затевалось:
df -h показывает странную картину, ему явно неизвестно про то, как показывать дедуплицированный диск
$ df -h
Filesystem Size Used Avail Use% Mounted on
dedup-pool 189G 104G 85G 56% /dedup-pool
А вот zpool list уже показывает корректные данные:
Мы видим, что реально занято около 33 Gb дискового пространства, коэффициент дедупликации 3.39!
$ zpool list
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
dedup-pool 119G 30.6G 88.4G - - 1% 25% 3.39x ONLINE -
Забавно, что в Zabbix мы видим картину похожую на df -h, с другой стороны, с чего бы ей быть другой.
Но в процентах картина ближе к правде, хотя тоже врет:
Итого дедупликация на zpool дала нам следующую статистику:
Было занято 103.5 GB, стало 30.6G.
Коэффициент дедупликации: 3.39 !!!
Инфографика не вошедшая в текст:
Выводы.
ZFS действительно может неплохо сэкономить место на дисках, вопрос конечно что дешевле - оператива или hdd, ну и тип данных, который мы собираемся там “хоронить” и дедуплицировать.
В целом оно работает и даже за вполне приемлемое время.
Имхо в качестве secondary non production backup storage подойдет, как некий домашний аналог Amazon S3 Glacier.
Плюсы и минусы.
Плюсы:
zpool легко настраивается.
Нет каких-либо лицензионных отчислений и платных фич.
Экономит огромное количество места на дисках, особенно если данные однотипные.
Минусы:
Сжимаются данные, которые будут записаны в zpool только после включения дедупликации.
Требуется огромное количество RAM, так как zfs и online deduplication очень требовательны к объемам оперативной памяти - на 1TB сжимаемого объема данных рекомендуется уже 5GB RAM и более (хорошая статья на тему https://constantin.glez.de/2011/07/27/zfs-to-dedupe-or-not-dedupe/).
Производительность записи на диски существенно снижается.
И самое главное - снижается надежность хранения данных (поврежденную файловую систему практически невозможно восстановить).
Linux BTRFS
BTRFS - позволяет нам использовать дедупликацию на одном томе, без необходимости собирать пул из нескольких дисков.
Добавляем один диск в систему объемом 120GB.
Включаем машину и проверяем, что диск виден в системе:
~$ sudo fdisk -l
Disk /dev/sdb: 120 GiB, 128849018880 bytes, 251658240 sectors
Disk model: VBOX HARDDISK
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Теперь необходимо создать на новом диске файловую систему, делаем это командой:
~$ sudo mkfs.btrfs /dev/sdb -L btrfs_disk
Получаем вывод с информацией о нашей файловой системе:
Скопируем к себе UUID, он нам еще пригодится.
STDOUT:
btrfs-progs v6.2
See http://btrfs.wiki.kernel.org for more information.
NOTE: several default settings have changed in version 5.15, please make sure
this does not affect your deployments:
- DUP for metadata (-m dup)
- enabled no-holes (-O no-holes)
- enabled free-space-tree (-R free-space-tree)
Label: btrfs_disk
UUID: 22b5c24c-621f-4f19-aa27-8a756adde9c7
Node size: 16384
Sector size: 4096
Filesystem size: 120.00GiB
Block group profiles:
Data: single 8.00MiB
Metadata: DUP 1.00GiB
System: DUP 8.00MiB
SSD detected: no
Zoned device: no
Incompat features: extref, skinny-metadata, no-holes
Runtime features: free-space-tree
Checksum: crc32c
Number of devices: 1
Devices:
ID SIZE PATH
1 120.00GiB /dev/sdb
Если по какой-то причине UUID скопировать не удалось, то его можно будет узнать командой:
$ sudo blkid /dev/sdb
/dev/sdb: LABEL="btrfs_disk" UUID="22b5c24c-621f-4f19-aa27-8a756adde9c7" UUID_SUB="48d82394-3fa4-4215-98d6-2b389bc4444b" BLOCK_SIZE="4096" TYPE="btrfs"
Создаем директорию и маунтим в нее нашу btrfs.
~$ sudo mkdir /mnt/btrfs_disk
~$ sudo mount /dev/sdb /mnt/btrfs_disk
И сразу добавляем нашу файловую систему в fstab для автоматического mount:
~$ sudo vi /etc/fstab
Последней строкой добавляем:
/dev/disk/by-uuid/22b5c24c-621f-4f19-aa27-8a756adde9c7 /mnt/btrfs_disk btrfs defaults 0 0
Можно
Сохраняем и выходим из файла:
:wq enter
Можем сразу же применить наш фалик fstab командой:
sudo mount -a
Теперь нам нужно установить утилиту для дедупликации, BTRFS как бы поддерживает дедупликацию, но не реализует функционал из коробки.
Есть несколько вариантов, но я остановился на BEES, так как хотел проверить именно filesystem block-level deduplication.
Установка зависимостей и сборка из сорсов:
$ cd /tmp
$ sudo apt -y install git build-essential btrfs-progs markdown uuid-runtime
$ git clone https://github.com/Zygo/bees.git
$ cd ./bees && sudo make install
Далее нам необходимо поправить конфигурационный файл:
Копируем шаблон:
$ sudo cp /etc/bees/beesd.conf.sample /etc/bees/beesd.conf
Раскомментируем две строки, 9 и 34.
$ sudo vi /etc/bees/beesd.conf
Пример моего файла конфигурации:
1 ## Config for Bees: /etc/bees/beesd.conf.sample
2 ## https://github.com/Zygo/bees
3 ## It's a default values, change it, if needed
4
5 # How to use?
6 # Copy this file to a new file name and adjust the UUID below
7
8 # Which FS will be used
9 UUID=22b5c24c-621f-4f19-aa27-8a756adde9c7
10
11 ## System Vars
12 # Change carefully
13 # WORK_DIR=/run/bees/
14 # MNT_DIR="$WORK_DIR/mnt/$UUID"
15 # BEESHOME="$MNT_DIR/.beeshome"
16 # BEESSTATUS="$WORK_DIR/$UUID.status"
17
18 ## Options to apply, see `beesd --help` for details
19 # OPTIONS="--strip-paths --no-timestamps"
20
21 ## Bees DB size
22 # Hash Table Sizing
23 # sHash table entries are 16 bytes each
24 # (64-bit hash, 52-bit block number, and some metadata bits)
25 # Each entry represents a minimum of 4K on disk.
26 # unique data size hash table size average dedupe block size
27 # 1TB 4GB 4K
28 # 1TB 1GB 16K
29 # 1TB 256MB 64K
30 # 1TB 16MB 1024K
31 # 64TB 1GB 1024K
32 #
33 # Size MUST be multiple of 128KB
34 DB_SIZE=$((1024*1024*1024)) # 1G in bytes
Теперь нужно скопировать датасет из host машины на наш том BTRFS.
Для этого воспользуемся возможностями VirtualBox guest tools - подключим директорию с файлами к нашей VM (не забудьте установить guest tools в VM до монтирования директории).
Копируем файлы:
$ sudo cp -R /ff_bak/ /mnt/btrfs_disk/
Посмотрим статистику по файловой системе:
$ sudo btrfs filesystem df /mnt/btrfs_disk
Data, single: total=105.00GiB, used=103.51GiB
System, DUP: total=8.00MiB, used=16.00KiB
Metadata, DUP: total=1.00GiB, used=113.28MiB
GlobalReserve, single: total=112.08MiB, used=0.00B
И чуть детальнее:
$ sudo btrfs fi usage /mnt/btrfs_disk
Overall:
Device size: 120.00GiB
Device allocated: 107.02GiB
Device unallocated: 12.98GiB
Device missing: 0.00B
Device slack: 0.00B
Used: 103.73GiB
Free (estimated): 14.47GiB (min: 7.98GiB)
Free (statfs, df): 14.47GiB
Data ratio: 1.00
Metadata ratio: 2.00
Global reserve: 112.08MiB (used: 0.00B)
Multiple profiles: no
Data,single: Size:105.00GiB, Used:103.51GiB (98.58%)
/dev/sdb 105.00GiB
Metadata,DUP: Size:1.00GiB, Used:113.28MiB (11.06%)
/dev/sdb 2.00GiB
System,DUP: Size:8.00MiB, Used:16.00KiB (0.20%)
/dev/sdb 16.00MiB
Unallocated:
/dev/sdb 12.98GiB
Как видим занято 103.73GiB
Каких-либо других откровений у нас там не будет, но для дальнейшего референса интересно посмотреть, как система выглядела “ДО”.
Запускаем выполнение bees командой “beesd UUID”.
Данная команда запускает интерактивный режим. Для маленького теста подойдет, но для реального использования лучше запускать в screen или создать системный сервис.
$ sudo beesd 22b5c24c-621f-4f19-aa27-8a756adde9c7
Создание системного сервиса для работы bees в фоне (для теста не требуется):
$ sudo vi /etc/systemd/system/beesd-22b5c24c-621f-4f19-aa27-8a756adde9c7.service
###################################################
[Unit]
Description=Deduplication service for sdb with specific UUID
[Service]
User=root
WorkingDirectory=/usr/sbin
ExecStart=/usr/sbin/beesd 22b5c24c-621f-4f19-aa27-8a756adde9c7
[Install]
WantedBy=multi-user.target
###################################################
$ systemctl daemon-reload
$ sudo systemctl start beesd-22b5c24c-621f-4f19-aa27-8a756adde9c7.service
$ sudo systemctl status --no-pager --full beesd-22b5c24c-621f-4f19-aa27-8a756adde9c7.service
###################################################
● beesd-b5f0aeba-7fc7-4ffa-958e-0c1f42adde70.service - Deduplication service for sdb with specific UUID
Loaded: loaded (/etc/systemd/system/beesd-b5f0aeba-7fc7-4ffa-958e-0c1f42adde70.service; enabled; preset: enabled)
Active: active (running) since Tue 2023-06-13 08:20:24 +07; 2h 8min ago
Main PID: 545 (bees)
Tasks: 9 (limit: 4518)
Memory: 1.0G
CPU: 10.977s
CGroup: /system.slice/beesd-b5f0aeba-7fc7-4ffa-958e-0c1f42adde70.service
└─545 /usr/lib/bees/bees /run/bees/mnt/b5f0aeba-7fc7-4ffa-958e-0c1f42adde70
Jun 13 08:23:26 home-ubuntu beesd[545]: 2023-06-13 08:23:26 545.622<7> crawl_transid: Clearing open FD cache with size 1 to enable file delete
Jun 13 08:23:26 home-ubuntu beesd[545]: 2023-06-13 08:23:26 545.622<7> crawl_transid: Clearing resolve cache with size 0
Jun 13 08:23:26 home-ubuntu beesd[545]: 2023-06-13 08:23:26 545.622<7> crawl_transid: Polling 59.9353s for next transid RateEstimator { count = 1023, raw = 2.9701 / 178.014, ratio = 2.9701 / 178.014, rate = 0.0166846, duration(1) = 59.9355, seconds_for(1) = 59.9353 }
Jun 13 08:23:26 home-ubuntu beesd[545]: 2023-06-13 08:23:26 545.617<6> crawl_new: Crawl started BeesCrawlState 5:0 offset 0x0 transid 1022..1023 started 2023-06-13-08-23-26 (0s ago)
Jun 13 08:23:26 home-ubuntu beesd[545]: 2023-06-13 08:23:26 545.617<6> crawl_new: Crawl finished BeesCrawlState 5:0 offset 0x0 transid 1022..1023 started 2023-06-13-08-23-26 (0s ago)
Jun 13 08:23:26 home-ubuntu beesd[545]: 2023-06-13 08:23:26 545.617<6> crawl_new: Crawl started BeesCrawlState 256:0 offset 0x0 transid 1022..1023 started 2023-06-13-08-23-26 (0s ago)
Jun 13 08:23:26 home-ubuntu beesd[545]: 2023-06-13 08:23:26 545.617<6> crawl_more: Crawl finished BeesCrawlState 256:258 offset 0xffffffffffff0000 transid 1022..1023 started 2023-06-13-08-23-26 (0s ago)
Jun 13 08:23:26 home-ubuntu beesd[545]: 2023-06-13 08:23:26 545.617<6> crawl_more: crawl_more ran out of data after 59.9351s
###################################################
$ systemctl enable --now beesd@22b5c24c-621f-4f19-aa27-8a756adde9c7.service
Наблюдать за ходом выполнения можно командой:
watch -n5 sudo btrfs fi usage /mnt/btrfs_disk
STDOUT:
Every 5.0s: sudo btrfs fi usage /mnt/btrfs_disk home-ubuntu: Mon Jun 12 04:23:55 2023
Overall:
Device size: 120.00GiB
Device allocated: 96.02GiB
Device unallocated: 23.98GiB
Device missing: 0.00B
Device slack: 0.00B
Used: 76.05GiB
Free (estimated): 42.10GiB (min: 30.11GiB)
Free (statfs, df): 42.10GiB
Data ratio: 1.00
Metadata ratio: 2.00
Global reserve: 116.25MiB (used: 0.00B)
Multiple profiles: no
Data,single: Size:94.00GiB, Used:75.88GiB (80.73%)
/dev/sdb 94.00GiB
Metadata,DUP: Size:1.00GiB, Used:87.27MiB (8.52%)
/dev/sdb 2.00GiB
System,DUP: Size:8.00MiB, Used:16.00KiB (0.20%)
/dev/sdb 16.00MiB
Unallocated:
/dev/sdb 23.98GiB
Как видим процесс пошел, место освобождается.
Идем пить кофе.
По окончании работы beesd в логе будет сообщение (при запуске в скрине или интерактивно):
2023-06-13 10:00:33 13602.13625<6> crawl_more: crawl_more ran out of data after 7461.16s
Результаты:
$ sudo btrfs fi usage /mnt/btrfs_disk
Overall:
Device size: 120.00GiB
Device allocated: 108.02GiB
Device unallocated: 11.98GiB
Device missing: 0.00B
Device slack: 0.00B
Used: 82.30GiB
Free (estimated): 35.88GiB (min: 29.89GiB)
Free (statfs, df): 35.87GiB
Data ratio: 1.00
Metadata ratio: 2.00
Global reserve: 97.64MiB (used: 0.00B)
Multiple profiles: no
Data,single: Size:106.01GiB, Used:82.11GiB (77.46%)
/dev/sdb 106.01GiB
Metadata,DUP: Size:1.00GiB, Used:100.41MiB (9.81%)
/dev/sdb 2.00GiB
System,DUP: Size:8.00MiB, Used:16.00KiB (0.20%)
/dev/sdb 16.00MiB
Unallocated:
/dev/sdb 11.98GiB
Весь процесс занял более 7 часов!
До дедупликации было занято 103.73GiB, после 82.30GiB, результат дедупликации всего лишь ~20.66%, учитывая, как долго проходил процесс, как-то негусто.
Инфографика:
Выводы:
На мой взгляд дедупликация в связке BTRFS с BEES оказалась не так интересна и эффективна, как на ZFS. Да, у них разные принципы, но конечный результат на ZFS как-то поинтереснее и достигается за более короткое время.
С другой стороны BTRFS как видим по метрикам не так требовательна к RAM, хотя при таких результатах сжатия объема лично для меня это уже не так важно.
Плюсы и минусы.
Плюсы:
Сжимает данные, которые уже были записаны на диск.
Нет каких-либо лицензионных отчислений и платных фич.
Экономит некоторое количество места на дисках, особенно если данные однотипные.
Не требовательна к RAM.
Минусы:
BTRFS дедупликация не совсем простая в настройке.
Очень требовательна к CPU, процесс дедупликации намного дольше чем на ZFS.
Производительность системы в целом снижается в разы во время дедупликации, можно поиграться настройками beesd, но тогда сам процесс дедупликации может стать крайне долгим.
Снижает надежность данных (поврежденную файловую систему практически не возможно восстановить).
Windows NTFS
Дедупликация в Windows работает к сожалению только на файловом уровне, но довольно хитро. Подробнее можно прочитать тут: https://learn.microsoft.com/en-us/windows-server/storage/data-deduplication/understand
Для того чтобы воспользоваться дедупликацией нам потребуется установить компоненты Windows Fileserver, сделать это можно через Server Manager:
Далее нам необходимо добавить диск для датасета.
Выключаем VM.
Добавляем диск.
Теперь нужно добавить диск в самой системе, включаем VM и открываем мастер управления дисками:
Нас сразу встретит мастер разметки новой партиции:
Для диска с дедупликацией какой-либо разницы в разметке MBR или GPT нет, поэтому я выбрал GPT, как более современную и надежную разметку.
Из описания:
GPT (GUID Partition Table) включает в себя избыточность, храня несколько копий таблицы разделов на всем диске, что снижает риск потери данных из-за повреждения таблицы разделов.
В отличии от разметки, тип файловой системы для дедупликации очень важен, так как Windows Server реализует дедупликацию только на NTFS файловых системах (в документации есть описание что начиная с версии Windows Server 2019 дедупликация теперь поддерживается и на ReFS, протестирую это в следующий раз), создаем раздел и форматируем его в NTFS:
Раздел готов, теперь необходимо включить на нем дедупликацию.
В отличии от ZFS, Windows делает offline дедупликацию, а значит ему все равно включим мы дедупликацию до или после помещения данных на том.
Предлагаю включить ее сейчас.
Идем в Server Manager и настраиваем дедупликацию на диске:
Так как дедупликация сильно снижает производительность системы в целом, в настройках предусмотрены многочисленные опции для настройки расписания и исключений из дедупликации.
Для нашего теста я поставлю 0 дней и уберу расписание оптимизации нагрузки.
Закидывать датасет для дедупликации я буду используя возможности VirtualBox shared folders.
Практически сразу в системе мы увидим “сетевой диск”:
Копируем датасет на наш диск с дедупликацией:
Пока копируются файлы можно воспользоваться PS и посмотреть статус дедупликации:
PS C:\Windows\system32> Get-DedupStatus
FreeSpace SavedSpace OptimizedFiles InPolicyFiles Volume
--------- ---------- -------------- ------------- ------
94.94 GB 0 B 0 0 E:
PS C:\Windows\system32> Get-DedupVolume -Volume E:
Enabled UsageType SavedSpace SavingsRate Volume
------- --------- ---------- ----------- ------
True Default 0 B 0 % E:
PS C:\Windows\system32> Get-DedupProperties -DriveLetter E
InPolicyFilesCount : 0
InPolicyFilesSize : 0
OptimizedFilesCount : 0
OptimizedFilesSavingsRate : 0
OptimizedFilesSize : 0
SavingsRate : 0
SavingsSize : 0
UnoptimizedSize : 56822681600
PSComputerName :
Как мы видим пока что ничего не происходит.
Но мы можем “попросить” систему начать оптимизацию данных.
Выведем информацию о дедупликации по завершении копирования всех файлов:
PS C:\Windows\system32> Get-DedupStatus
FreeSpace SavedSpace OptimizedFiles InPolicyFiles Volume
--------- ---------- -------------- ------------- ------
16.38 GB 0 B 0 0 E:
PS C:\Windows\system32> Get-DedupVolume -Volume E:
Enabled UsageType SavedSpace SavingsRate Volume
------- --------- ---------- ----------- ------
True Default 0 B 0 % E:
PS C:\Windows\system32> Get-DedupProperties -DriveLetter E
InPolicyFilesCount : 0
InPolicyFilesSize : 0
OptimizedFilesCount : 0
OptimizedFilesSavingsRate : 0
OptimizedFilesSize : 0
SavingsRate : 0
SavingsSize : 0
UnoptimizedSize : 111247380480
PSComputerName :
Также можно посмотреть статус Volume в UI:
Теперь запустим процесс дедупликации, чтобы не ждать когда система сама запустит его:
Start-DedupJob -Volume E: -Type Optimization
Type ScheduleType StartTime Progress State Volume
---- ------------ --------- -------- ----- ------
Optimization Manual 0 % Queued E:
Можно идти пить чай.
Итак результаты:
PS C:\Windows\system32> Get-DedupStatus
FreeSpace SavedSpace OptimizedFiles InPolicyFiles Volume
--------- ---------- -------------- ------------- ------
112.85 GB 98.11 GB 377 377 E:
PS C:\Windows\system32> Get-DedupVolume -Volume E:
Enabled UsageType SavedSpace SavingsRate Volume
------- --------- ---------- ----------- ------
True Default 98.11 GB 93 % E:
PS C:\Windows\system32> Get-DedupProperties -DriveLetter E
InPolicyFilesCount : 377
InPolicyFilesSize : 111144308918
OptimizedFilesCount : 377
OptimizedFilesSavingsRate : 94
OptimizedFilesSize : 111144308918
SavingsRate : 93
SavingsSize : 105341122774
UnoptimizedSize : 112999258326
PSComputerName :
Сжатие размера аж на 93%!
Занимаемое место на диске 7.13GB (вместо 103.5 GB)
Инфографика:
Вот тут было неожиданно для меня - дедупликация потребовала меньше RAM чем копирование файлов.
Выводы:
Под мой датасет винда оказалась крайне эффективна, о таком коэффициенте сжатия данных можно было только мечтать!
Ах если бы не проприетарность и прочие ограничения и нюансы Майкрософт, но нет, дедупликация от MS доступна только на Windows Server.
Плюсы и минусы:
Плюсы:
Сжимает данные, которые уже были записаны на диск.
Экономит огромное количество места на дисках, особенно если данные однотипные.
Не требовательна к RAM.
Минусы:
Функционал доступен только в платных серверных версиях Windows Server.
Снижается надежность хранения данных (поврежденную файловую систему практически невозможно восстановить)
Производительность системы несколько снижается при больших объемах.
До данного тестирования я много раз пробовал погрузиться в различные реализации дедупликации данных - конечно же хотелось показать поганому Майкрософту силушку Linux ZFS, BTRFS, но, как мы видим, в этот раз Microsoft таки и правда удивил, без какого-либо стеба (где мой чемодан деняг, вносите).
Также постфактум хочу отметить, что данную статью можно бесконечно много расширять - попробовать другие реализации дедупликации BTRFS, либо протестировать дедупликацию меняя множество настроек ZFS, вероятно можно также попробовать другой формат архивов с данными датасета, мне же хотелось найти максимально доступный вариант, не требующий многомесячных тестирований и подбора настроек под разные типы данных.
Собственно, если у вас есть опыт использования других систем дедупликации на базе linux, то я буду благодарен за советы и комментарии к данной статье!
Холивары и срач можно туда же ;)
И напоследок - был у меня когда-то сервер на котором со временем накопился очень неплохой датасет (сжатие 98%, вместо 5.52TB занято чуть больше 100GB):
Файловая система |
Объем до дедупликации |
Объем после дедупликации |
Коэффициент дедупликации |
ZFS |
103.5 GB |
30.6 GB |
3.39 |
BTRFS |
103.5 GB |
82.30 GiB |
1.26 |
NTFS |
103.5 GB |
7.13 GB |
14.51 |
Комментарии (23)
13werwolf13
20.06.2023 04:38+5позволю себе вставить свои 5 копеек по поводу bees, а то глаз дёргается когда так пишут systemd юниты.
1) у systemd для сервисов могут быть аргументы (передаются через @ при вызове сервиса) не обязательно создавать свой юнит для каждого uuid
2) не указан type юнита
3) учитывая что такой сервис может знатно так нагрузить систему неплохо было бы его ограничить по ресурсамс этими мыслями я пошёл посмотреть а что предлагается вместе с пакетом:
довольно большая портянка
[werwolf@power] ~ ❯ rpm -ql bees | grep systemd ⏎ /usr/lib/systemd/system/beesd@.service [werwolf@power] ~ ❯ systemctl cat beesd@.service # /usr/lib/systemd/system/beesd@.service [Unit] Description=Bees (%i) Documentation=https://github.com/Zygo/bees After=sysinit.target [Service] Type=simple ExecStart=/usr/sbin/beesd --no-timestamps %i CPUAccounting=true CPUSchedulingPolicy=batch CPUWeight=12 IOSchedulingClass=idle IOSchedulingPriority=7 IOWeight=10 KillMode=control-group KillSignal=SIGTERM MemoryAccounting=true Nice=19 Restart=on-abnormal RuntimeDirectory=bees StartupCPUWeight=25 StartupIOWeight=25 # Hide other users' process in /proc/ ProtectProc=invisible # Mount / as read-only ProtectSystem=strict # Forbidden access to /home, /root and /run/user ProtectHome=true # Mount tmpfs on /tmp/ and /var/tmp/. # Cannot mount at /run/ or /var/run/ for they are used by systemd. PrivateTmp=true # Disable network access PrivateNetwork=true # Use private IPC namespace, utc namespace PrivateIPC=true ProtectHostname=true # Disable write access to kernel variables throug /proc ProtectKernelTunables=true # Disable access to control groups ProtectControlGroups=true # Set capabilities of the new program # The first three are required for accessing any file on the mounted filesystem. # The last one is required for mounting the filesystem. AmbientCapabilities=CAP_DAC_OVERRIDE CAP_DAC_READ_SEARCH CAP_FOWNER CAP_SYS_ADMIN # With NoNewPrivileges, running sudo cannot gain any new privilege NoNewPrivileges=true [Install] WantedBy=basic.target
не скажу что в этом юните 100% то что написал бы я, но мейнтейнерам виднее
к своему удивлению не нашёл в пакете .timer юнита для этого .service юнита но это уже лирика.
Iliya_karin Автор
20.06.2023 04:38+2Спасибо за технический комментарий.
Я привел пример минимального рабочего варианта, честно, статья отняла сильно больше сил и времени чем я планировал, поэтому пример сервиса/юнита получился довольно кривой, я старался сфокусироваться больше на теме стати и результатах.
Хотел еще подтащить OpenDedup, но с ним по быстрому не вышло, да и так портянка получилась не маленькая.
selivanov_pavel
20.06.2023 04:38+1Сравнивалась работа блочной и файловой дедупликации, что не совсем корректно. Хорошо бы тогда под линукс какой-нибудь sdfs или lessfs протестировать, они на файловом уровне работают.
Iliya_karin Автор
20.06.2023 04:38Я на самом деле ожидал что блочная дедупликация будет эффективнее чем файловая, вообще детального описания алгоритма от MS я не нашел, за исключением того самого описания на оффсайте, больше похоже что все таки оно работает на гибридном уровне.
khajiit
20.06.2023 04:38+3Ну, судя по документации, реализация файловой дедупликации на NTFS — та же блочная, вид сбоку. Напоминает разбиение рекордов в ZFS, только offline и с постобработкой.
На ZFS, фактически, тестировалось совпадение попаданий кусков немного отличающихся файлов в txg, так как recordsize не ограничивался.Проблемы с дедупликацией tar-архивов заметили в Proxmox еще несколько лет назад — и запилили pxar и использующий его pbs, что позволяет достигать коэффициента дедупликации за 100.
Ну и для дедупликации интереснее было бы передавать не архив а его содержимое, там результаты были бы наверняка веселее.
Опять же, для дедуплицированных блоков NTFS, судя по документации, может использовать компрессию — ZFS умеет zstd, который не включался.
Опять же, ZFS позволет дедуплицировать диски работающих ВМ, а не просто какие-то архивы.
Ремарки про невозможность восстановления ФС тоже требуют раскрытия, особенно для ZFS с ее тремя копиями метаданных.В общем, модель сферического коня в вакууме вызывает сплошные вопросы…
select26
20.06.2023 04:38+5Вот ради таких стаей стоит заходить на Хабр!
Cпасибо большое за такое детальное исследование и подробное описание результатов! Очень полезно и читается приятно и легко.
AntonVirtual
20.06.2023 04:38Интересно, сколько нужно времени, чтобы "обнаружить" специализированные дедуплицирующие СХД для резервного копирования типа DataDomain или StoreOnce?
Или например СРК (системы резервного копирования) с встроенной дедупликацией, как например Veeam?Iliya_karin Автор
20.06.2023 04:38Не совсем понимаю как трактовать ваш комментарий, если возможно ответьте более развернуто.
Vasily_Pechersky
20.06.2023 04:38DataDomain — это отличная дедупликация но очень дорого.
Veeam — его эффективность достаточно хромает.
Есть ещё Avamar — это тоже не дёшево но достаточно геморно в настройке.Хотя! DataDomain есть community edition — 600 gb (до дедупликации) бесплатно.
AntonVirtual
20.06.2023 04:38А вы данные свои оценивали, чтобы можно было утверждать что продукт Х дорого / не дорого?
Vasily_Pechersky
20.06.2023 04:38Всё можно поставить под сомнение. Зависит от позиционирования.
$500 за 1 тб сырой ёмкости для виртуалки для разных бизнесов могут быть и много и мало.AntonVirtual
20.06.2023 04:38Еще ни один человек, который огульно судит "это дорого, это слишком дорого" не показал мне экономических расчетов стоимости простоев или потери данных.
Но мнение имеет.
За 10 с лишним лет.
Vasily_Pechersky
20.06.2023 04:38Илья, я был бы очень рад если бы вы написали от тестировании VDO (Идут в комплекте со всеми RedHat компиляциями). В настройке сложнее ZFS но много проще BTRFS. Производительность в моих экспериментах была не высокой, но я тестировал на Centos 7. Может современные версии шустрее ?
Iliya_karin Автор
20.06.2023 04:38Возьму на заметку.
Интересно будет написать вторую часть статьи, когда найду в себе силы.
Может быть как раз добавить VDO, sdfs, lessfs.
Nikitin
20.06.2023 04:38+1Кстати, под винду есть утилита https://dupecare.com которая делает дедупликацию с компрессией для отдельной папки
Merlin5004
20.06.2023 04:38Я ведь правильно понимаю, что для прочтения дедуплицированных данных нужна будет эта-же утилита? Т.е. вариант записать с её помощью кучу инфы на флешку, а потом где-то в другом месте считать - не сработает, так?
zzzzzzzzzzzz
20.06.2023 04:38Как по мне, в статье очень не хватает краткого сравнения принципов дедупликации. Уж слишком удивляет такая разница в результатах. Может, где-то надо настройки подкрутить, или ещё что-то. Очень подозрительно.
Также любопытно, насколько дедупликация замедляет доступ к файлам. Но тут всё очень от железа должно зависеть, поэтому чужой эксперимент - не показатель.
Iliya_karin Автор
20.06.2023 04:38Для сравнения алгоритмов дедупликации пришлось бы провести полноценное исследование, включая сорсы zfs/btrfs bees, для подобной статьи потребуется затратить около 2х месяцев по вечерам и выходным, в данный момент я к сожалению не располагаю таким ресурсом.
Да и в целом мне хотелось сравнить и показать "а чё там из коробки доступно?"
Большинство пользователей или ИТ специалистов не хотят тратить дни и недели на допиливание кода и сборку на арчах под свои нужды.
Но в целом соглашусь что было бы интересно сделать прям научную статью со сравнением алгоритмов и разбором на разных дата сетах.
khajiit
20.06.2023 04:38+3С этим — легко помочь, научное исследование тут не нужно.
Начнем с базы.
Любое хранилище с рандомным доступом способно адресовать сырое пространство ровно одном способом: разбивая его на блоки. Соответственно, любой алгоритм любой постобработки — шифрование, сжатие, дедупликация — не сможет оперивать произвольными смещениями и длинами: они всегда будут кратны базовому блоку хранилища. То есть, дедупликация на хранилище всегда блочная.
Далее, сам поиск одинаковых блоков, тут вариантов совсем немного:- поиск по полному совпадению (медленно)
- поиск по хешу (очевидно, тут все отличия будут в хеш-функции)
- поиск по хешу И проверка на полное совпадение (можно форсировать в ZFS)
Интерфейс доступа к хралищу (ФС) может оперировать как базовыми блоками так и цепочками блоков (экстентами, рекордами, etc).
Архив, в отличие от, можно рассматривать как поток обработанных (или нет) данных, разделенных промежутками с метаданными самого архива — оглавлением, таблицой смещений, словарем и т.д., где минимальное смещение/длина данных принципиально снизу не ограничены (обычно кратны байту или машинному слову).
Соответственно:- смещение файла внутри архива не обязано совпадать с началом блока хранилища
- последовательность блоков контента внутри архива может иметь разные по величине гапы
Из чего есть два следствия:
- на хранилище соседние архивы могут лечь совершенно разными последовательностями байт — как следствие, дедуплицировать там будет нечего, блоки будут уникальными
- при определенных условиях (архив не сильно меняющегося набора файлов в формате, хранящем сильно меняющиеся части в конце архива) можно будет получить достаточно пригодный для дедупликации архив. При этом эффективность дедупликации будет зависеть от размера блока (что и показало ваше тестирование, у NTFS размер блока — 4кБ по дефолту)
Если вы хотите получить высокий коэффициент дедупликации — ваши данные должны быть к ней пригодны. Это значит:
- или сырые, без контейнеров (архивов), файлы
- или вам нужен специальный формат контейнера, который вы можете подтюнить под особенности хранилища (вроде уже упомянутого pxar)
- или (если вы дедуплицируете ФС) размеры экстентов/рекодов/etc дочерних ФС должны соответсвовать размеру блока хранилища
MountainGoat
Если, как вы сказали, это у вас бэкапы, то используйте restic или borg, и нижележащие файловые системы вообще не будут иметь влияния, хоть на FAT храните.
Iliya_karin Автор
Если брать чисто кейс с моим дата сетом, то да согласен, но мне хотелось покопаться и сравнить именно разные варианты дедупликации.
У меня в проде был когда то массив от PureStorage, уж не знаю на базе чего у них была построена FS, но массив дедупил на лету все и вся с очень хорошими коэффициентами, я надеялся что найду +- похожее решение на Linux.
trublast
Неудобно (хоть и не критично), что нужно использовать рестик или борг, вместо того чтобы "просто скопировать файлы"
Плюс к тому и рестик и борг делают дедуп в рамках одного бэкап-архива. Если у вас бэкап двух почти одинаковых БД, то дедупликации не будет (между ними). В случае с ФС дедеп применяется для всех записанных данных.
С другой стороны в borg/restic дедупликация со сжатием может более эффективная, чем дедупликация сжатых файлов на ФС. Так же при бэкапе боргом по сети сначала производится дедупликация (подсчет хэшей блоков), а потом передача измененных блоков данных. Это может быть полезно, так меньше нагружает сеть, она не будет узким местом при терабайтных бэкапах повторяющихся данных, ведь на удаленный сервер будут переданы только изменённые блоки.