Это обзорная статья для описания возможностей. Само использование hashget (довольно простое) описано в
Сравнение
По закону жанра, начну сразу с интриги — сравнения результатов:
Data sample
unpacked size
.tar.gz
hashget .tar.gz
WordPress-5.1.1
43 Mb
11 Mb ( 26% )
155 Kb ( 0.3% )
Linux kernel 5.0.4
934 Mb
161 Mb ( 20% )
4.7 Mb ( 0.5% )
Debian 9 (LAMP) LXC VM
724 Mb
165 Mb ( 23% )
4.1 Mb ( 0.5% )
Предыстория, каким должен быть идеальный и эффективный бэкап
Каждый раз, когда я делал бэкап свежесозданной виртуалки, мне не давало покоя чувство, что я что-то делаю не так. Почему у меня получается увесистый бэкап от системы, где моего бесценного нетленного творчества — однострочный index.html с текстом «Hello world»?
Почему в моем бэкапе есть 16-мегабайтный /usr/sbin/mysqld? Неужели в этом мире именно мне выпала честь хранить этот важный файл, и если я не справлюсь — он будет потерян для человечества? Скорее всего нет. Он хранится на высоконадежных серверах debian (надежность и бесперебойность которых ни в какое сравнение не идет с тем, что могу обеспечить я), а также в резервных копиях (миллионах их) других админов. Точно ли нам нужно создавать для повышения надежности 10 000 000 + 1’ую копию этого важного файла?
В общем-то tar -c
/ tar -x
. (Иными словами, это lossless упаковка)
Как работает hashget
В hashget есть понятия Package и HashPackage, с их помощью он выполняет дедупликацию.
Package (пакет). Файл (обычно архив .deb или .tar.gz), который можно надежно скачать из сети, и из которого можно получить один или более файлов.
HashPackage — небольшой JSON файл, представляющий Package, в том числе содержащий URL пакета и хеш-суммы (sha256) файлов из него. Например, для пакета mariadb-server-core размером 5 мегабайт размер hashpackage всего 6 килобайт. Примерно в тысячу раз меньше.
Дедупликация — создание архива без дублированных файлов (если дедупликтор знает, где может быть скачан оригинал пакета, он сокращает дубли из архива).
Запаковка
При запаковке просматриваются все файлы из пакуемого каталога, считаются их хеш-суммы, и если сумма найдена в одном из известных HashPackage, то метаданные о файле (имя, хеш, права доступа итд) сохраняются в особый файл .hashget-restore.json, который тоже будет включен в архив.
Сама запаковка в простейшем случае выглядит не сложнее tar’а:
hashget -zf /tmp/mybackup.tar.gz --pack /path/to/data
Распаковка
Распаковка делается в два этапа. Сначала обычная tar распаковка:
tar -xf mybackup.tar.gz -C /path/to/data
затем восстановление из сети:
hashget -u /path/to/data
При восстановлении hashget читает файл .hashget-restore.json, скачивает необходимые пакеты, распаковывает их, и извлекает необходимые файлы, устанавливая их на нужные пути, с нужными owner/group/permissions.
Более сложные вещи
То, что описано выше — уже достаточно, для тех, кому «хочу как tar, но чтобы упаковал мой Debian в 4 мегабайта». Дальше посмотрим более сложные вещи.
Индексирование
Если у hashget совсем не было б ни одного HashPackage, то он просто не смог бы ничего дедуплицировать.
Создать HashPackage можно и вручную (просто: hashget --submit https://wordpress.org/wordpress-5.1.1.zip -p my
), но есть путь удобнее.
Для того чтобы получить нужные hashpackage, есть этап индексирования (он автоматически выполняется при команде --pack
) и эвристики. При индексировании hashget «скармливает» каждый найденный файл всем имеющимся эвристикам, которым он интересен. Эвристики затем могут проиндексировать какой-либо Package, чтобы создать HashPackage.
Например, дебиановская эвристика любит файл /var/lib/dpkg/status и обнаруживает установленные debian пакеты, и если они не проиндексированы (для них не созданы HashPackage), скачивает и индексирует их. Получается очень приятный эффект — hashget всегда будет эффективно дедуплицировать дебиановские ОС, даже если на них есть самые новые пакеты.
Файлы-подсказки (хинты)
Если в вашей сети используется какой-то ваш проприетарный пакет или публичный пакет, который не включен в эвристики hashget, вы можете добавить в него простой hint-файл hashget-hint.json по образцу:
{
"project": "wordpress.org",
"url": "https://ru.wordpress.org/wordpress-5.1.1-ru_RU.zip"
}
Далее, каждый раз при создании архива пакет будет проиндексирован (если не был ранее), и файлы пакета будут дедуплицированы из архива. Не нужно никакого программирования, все можно сделать из vim и сэкономить в каждом бэкапе. Заметьте, что благодаря подходу через хешсуммы, если какие-то файлы из пакета будут изменены локально (например, изменен файл конфигурации) — то измененные файлы сохранятся в архиве «как есть» не буду сокращены.
Если какой-то ваш собственный пакет обновляется периодически, но изменения не очень большие, можно делать hint только для основных версий. Например, в версии 1.0 сделали хинт с указанием на mypackage-1.0.tar.gz, и она будет полностью дедуплицироваться, затем выпустили версию 1.1, которая немного отличается, а хинт не обновили. Ничего страшного. Дедуплицируются только файлы, которые совпадают (которые можно восстановить) с версией 1.0.
Эвристика, которая обрабатывает hint-файл — хороший пример для понимания внутреннего механизма работы эвристик. Он обрабатывает только файлы hashget-hint.json (или .hashget-hint.json с точкой) и игнорирует все остальные. По этому файлу он определяет, какой URL пакета должен быть проиндексирован, и hashget его индексирует (если этого не было сделано раньше)
HashServer
Было бы довольно трудоемко при создании бэкапов полностью выполнять индексирование. Для этого нужно скачать каждый пакет, распаковать, проиндексировать. Поэтому hashget использует схему с
HashServer — не обязательный элемент схемы, не критичный, служит исключительно для ускорения и снижения нагрузки на репозитории. Легко отключается (опцией --hashserver
без параметров). Кроме того, легко можно
Инкрементальные и дифференциальные бэкапы, запланированное устаревание
--submit
и все готово! Следующий бэкап, который создаст hashget, не будет включать файлы из этого архива.
Но это не очень хороший подход, потому что может оказаться так, что при восстановлении нам придется дергать все hashget-бэкапы за всю историю (если в каждом будет хотя бы один уникальный файл). Для этого есть механизм --expires 2019-06-01
, и по наступлению этой даты (c 00:00), он не будет использован. Сам архив можно после этой даты не удалять (Хотя hashget может удобно показать URLы всех бекапов, которые у нас протухли/протухнут на данный момент или на любую дату).
Например, если 1го числа делать фулл бэкап, и индексировать его со временем жизни до конца месяца — мы получим схему дифференциального бэкапа.
Если так же будем индексировать и новые бэкапы — будет схема инкрементальных бэкапов.
В отличие от традиционных схем, hashget позволяет использовать несколько базовых источников. Бекап будет сокращен и за счет сокращения файлов из предыдущих бэкапов (если они есть), и за счет публичных файлов (то, что можно выкачать).
Если мы по какой-то причине не доверяем надежности дебиановских ресурсов (
Hashget опирается только на надежные источники восстановления по ВАШЕМУ усмотрению. Какие вы считаете надежными — те и будут использованы.
FilePool и Glacier
Механизм
$ hashget -u . --pool /tmp/pool
или
$ hashget -u . --pool http://myhashdb.example.com/
Чтобы сделать пул в локальном каталоге — достаточно просто создать каталог и накидать в него файлов, hashget сам по хешам найдет то, что ему нужно. Чтобы сделать пул доступным через HTTP, нужно специальным образом создать симлинки, это делается одной командой (hashget-admin --build /var/www/html/hashdb/ --pool /tmp/pool
). Сам HTTP FilePool — это статичные файлы, так что обслуживать его может любой простейший вебсервер, нагрузка на сервер почти нулевая.
Благодаря FilePool в качестве базовых ресурсов можно использовать не только ресурсы на http(s), но и,
После аплоада бэкапа на гласьер получаем его Upload ID и используем его в качестве URL. Например:
hashget --submit Glacier_Upload_ID --file /tmp/my-glacier-backup.tar.gz --project glacier --hashserver --expires 2019-09-01
Теперь новые (дифференциальные) бэкапы будут опираться на этот бэкап и будут короче. После tar распаковки диффбэкапа мы можем посмотреть, на какие ресурсы он опирается:
hashget --info /tmp/unpacked/ list
и просто шелл-скриптом скачать из гласьера все эти файлы в pool и запустить обычное восстановление: hashget -u /tmp/unpacked —pool /tmp/pool
Стоит ли овчинка выделки
В простейшем случае — вы просто будете меньше платить за бэкапы (если вы их храните где-то в облаке за деньги). Может быть — гораздо-гораздо меньше.
Но это не единственное. Количество переходит в качество. Можете использовать это, чтобы получить качественный апгрейд схемы бэкапов. Например, раз бэкапы у нас теперь короче — можно делать не ежемесячный бэкап, а ежедневный. Хранить их не полгода, как ранее, а 5 лет. Раньше хранили в медленном но дешевом «холодном» хранилище (Glacier), теперь можете хранить в горячем, откуда можно всегда быстро скачать бэкап и восстановиться за минуты, а не за день.
Можно увеличить надежность хранения бэкапов. Если сейчас мы их храним в одном хранилище, то сократив объем бэкапов — сможем хранить в 2-3 хранилищах и безболезненно пережить, если одно из них повредится.
Как попробовать и начать пользоваться?
Заходим на гитлаб страничку pip3 install hashget[plugins]
) и просто читаем-выполняем quick-start. Думаю, все простые вещи сделать — займет минут 10-15. Затем можно попробовать пожать свои виртуалки, сделать, если надо, хинт-файлы, чтобы ужималось сильнее, поиграться с пулами, локальной базой хешей и хешсервером, если интересно будет, а на следующий день посмотреть, каков будет размер инкрементального бэкапа поверх вчерашнего.
Источник: habr.com