Хабрахабр

Сократить бэкапы на 99.5% с hashget

hashget — это бесплатный, оперсорсный дедупликатор — похожая на архиватор утилита, которая позволяет значительно сократить размер бэкапов, а так же организовать схемы инкрементального и дифференциального бэкапа и не только.

Само использование hashget (довольно простое) описано в README проекта и wiki-документации. Это обзорная статья для описания возможностей.

По закону жанра, начну сразу с интриги, сравнения результатов:

Почему у меня получается увесистый бэкап от системы, где моего бесценного нетленного творчества — однострочный index.html с текстом "Hello world"? Каждый раз когда я делал бэкап свежесозданной виртуалки мне не давало покоя чувство, что я что-то делаю не так.

Неужели в этом мире именно мне выпала честь хранить этот важный файл, и если я не справлюсь — он будет потерян для человечества? Почему в моем бэкапе есть 16мегабайтный /usr/sbin/mysqld? Он хранится на высоконадежных серверах debian (надежность и бесперебойность которых — ни в какое сравнение не идет с тем, что могу обеспечить я), а так же в резервных копиях (миллионах их) других админов. Скорее всего нет. Точно ли нам нужно создавать для повышения надежности 10 000 000 + 1'ую копию этого важного файла?

При запаковке — он создает очень маленький бэкап. В общем-то hashget и решает эту проблему. (Иными словами, это lossless упаковка) При распаковке — полностью распакованную систему, аналогичную той, которая была бы при tar -c / tar -x.

В hashget есть понятия Package и HashPackage, с их помощью он выполняет дедупликацию.

Файл (обычно архив .deb или .tar.gz), который можно надежно скачать из сети, и из которого можно получить один или более файлов. Package (пакет).

Например, для пакета mariadb-server-core размером 5 мегабайт, размер hashpackage всего 6 килобайт. HashPackage — небольшой JSON файл, представляющий Package, в том числе содержащий URL пакета и хеш-суммы (sha256) файлов из него. Примерно, в тысячу раз меньше.

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

Запаковка

При запаковке просматриваются все файлы из пакуемого каталога, считаются их хеш-суммы, и если сумма найдена в одном из известных 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, то он просто не смог бы ничего дедуплицировать.

1. Создать HashPackage можно и вручную (просто: hashget --submit https://wordpress.org/wordpress-5. 1.zip -p my), но есть путь удобнее.

При индексировании, hashget "скармливает" каждый найденный файл всем имеющимся эвристикам, которым он интересен. Для того чтобы получить нужные hashpackage, есть этап индексирования (он автоматически выполняется при команде --pack) и эвристики. Эвристики затем могут проиндексировать какой-либо Package чтобы создать HashPackage.

Получается очень приятный эффект — hashget всегда будет эффективно дедуплицировать дебиановские ОС, даже если на них есть самые новые пакеты. Например, дебиановская эвристика любит файл /var/lib/dpkg/status и обнаруживает установленные debian пакеты, и если они не проиндексированы (для них не созданы HashPackage), скачивает и индексирует их.

Файлы-подсказки (хинты)

Если в вашей сети используется какой-то ваш проприетарный пакет или публичный пакет, который не включен в эвристики hashget, вы можете добавить в него простой hint-файл hashget-hint.json, по образцу:

{ "project": "wordpress.org", "url": "https://ru.wordpress.org/wordpress-5.1.1-ru_RU.zip"
}

Не нужно никакого программирования, все можно сделать из vim и сэкономить в каждом бэкапе. Далее, каждый раз при создании архива пакет будет проиндексирован (если не был ранее), и файлы пакета будут дедуплицированы из архива. Заметьте, что благодаря подходу через хешсуммы, если какие-то файлы из пакета будут изменены локально (например, изменен файл конфигурации) — то измененные файлы сохранятся в архиве "как есть", не буду сокращены.

Например, в версии 1. Если какой-то ваш собственный пакет обновляется периодически, но изменения не очень большие, можно делать hint только для основных версий. 0.tar.gz, и она будет полностью дедуплицироваться, затем выпустили версию 1. 0 сделали хинт с указанием на mypackage-1. Ничего страшного. 1, которая немного отличается, а хинт не обновили. 0. Дедуплицируются только файлы, которые совпадают (которые можно восстановить) с версией 1.

Он обрабатывает только файлы hashget-hint.json (или .hashget-hint.json с точкой) и игнорирует все остальные. Эвристика, которая обрабатывает hint-файл — хороший пример для понимания внутреннего механизма работы эвристик. По этому файлу он определяет, какой URL пакета должен быть проиндексирован, и hashget его индексирует (если этого не было сделано раньше)

HashServer

Для этого нужно скачать каждый пакет, распаковать, проиндексировать. Было бы довольно трудоемко при создании бэкапов полностью выполнять индексирование. При обнаружении установленного debian'овского пакета, если он не найдется в локальных HashPackage, сначала делается попытка просто скачать HashPackage с хеш-сервера. Поэтому hashget использует схему с HashServer. И только если это не получается — hashget сам скачивает и хеширует пакет (и загружает на hashserver, чтобы в дальнейшем hashserver его предоставлял).

Легко отключается (опцией --hashserver без параметров). HashServer — не обязательный элемент схемы, не критичный, служит исключительно для ускорения и снижения нагрузки на репозитории. Кроме того, легко можно сделать свой собственный hashserver.

Инкрементальные и дифференциальные бэкапы, запланированное устаревание

Почему бы нам не проиндексировать сам наш бэкап (со всеми нашими уникальными файлами)? hashget позволяет очень просто сделать схему инкрементальных и дифференциальных бэкапов. Следующий бэкап, который создаст hashget, не будет включать файлы из этого архива. Одна команда --submit и все готово!

Для этого есть механизм запланированного устаревания бэкапов. Но это не очень хороший подход, потому что может оказаться так, что при восстановлении нам придется дергать все hashget-бэкапы за всю историю (если в каждом будет хотя бы один уникальный файл). Сам архив можно после этой даты не удалять (Хотя hashget может удобно показать URLы всех бекапов, которые у нас протухли/протухнут на данный момент или на любую дату). При индексировании можно указать дату устаревания HashPackage --expires 2019-06-01, и по наступлению этой даты (c 00:00), он не будет использован.

Например, если 1го числа делать фулл бэкап, и индексировать его со временем жизни до конца месяца — мы получим схему дифференциального бэкапа.

Если так же будем индексировать и новые бэкапы — будет схема инкрементальных бэкапов.

Бекап будет сокращен и за счет сокращения файлов из предыдущих бэкапов (если они есть), и за счет публичных файлов (то, что можно выкачать). В отличие от традиционных схем, hashget позволяет использовать несколько базовых источников.

Теперь, если все сервера наших дистрибутивов окажутся нам недоступны (в сувенирном Интернете или при зомби-апокалипсисе), но наши бэкапы будут в порядке — мы сможем восстановиться из любого короткого дифф-бэкапа, опирающегося только на наши более ранние бэкапы. Если мы по какой-то причине не доверяем надежности дебиановских ресурсов (https://snapshot.debian.org/) или использует другой дистрибутив, мы просто можем один раз сделать полный бэкап со всеми пакетами, и далее опираться уже на него (отключив эвристику).

Какие вы считаете надежными — те и будут использованы. Hashget опирается только на надежные источники восстановления по ВАШЕМУ усмотрению.

FilePool и Glacier

Механизм FilePool позволяет не обращаться постоянно к внешним серверам для скачивания пакетов, а использовать пакеты из локального каталога или корпоративного сервера, например:

$ hashget -u . --pool /tmp/pool

или

$ hashget -u . --pool http://myhashdb.example.com/

Чтобы сделать пул доступным через HTTP, нужно специальным образом создать симлинки, это делается одной командой (hashget-admin --build /var/www/html/hashdb/ --pool /tmp/pool). Чтобы сделать пул в локальном каталоге — достаточно просто создать каталог и накидать в него файлов, hashget сам по хешам найдет то, что ему нужно. Сам HTTP FilePool — это статичные файлы, так что обслуживать его может любой простейший вебсервер, нагрузка на сервер почти нулевая.

Благодаря FilePool, в качестве базовых ресурсов можно использовать не только ресурсы на http(s), но и, к примеру, Amazon Glacier.

Например: После аплоада бэкапа на гласьер, получаем его 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

Стоит ли овчинка выделки

Может быть — гораздо-гораздо меньше. В простейшем случае — вы просто будете меньше платить за бэкапы (если вы их храните где-то в облаке за деньги).

Количество переходит в качество. Но это не единственное. Например, раз бэкапы у нас теперь короче — можно делать не ежемесячный бэкап, а ежедневный. Можете использовать это, чтобы получить качественный апгрейд схемы бэкапов. Раньше хранили в медленном но дешевом "холодном" хранилище (Glacier), теперь можете хранить в горячем, откуда можно всегда быстро скачать бэкап и восстановиться за минуты, а не за день. Хранить их не полгода, как ранее, а 5 лет.

Если сейчас мы их храним в одном хранилище, то сократив объем бэкапов — сможем хранить в 2-3 хранилищах и безболезненно пережить, если одно из них повредится. Можно увеличить надежность хранения бэкапов.

Как попробовать и начать пользоваться?

Думаю, все простые вещи сделать — займет минут 10-15. Заходим на гитлаб страничку https://gitlab.com/yaroslaff/hashget, устанавливаем одной командой (pip3 install hashget[plugins]) и просто читаем-выполняем quick-start. Затем можно попробовать пожать свои виртуалки, сделать, если надо, хинт-файлы, чтобы ужималось сильнее, поиграться с пулами, локальной базой хешей и хешсервером, если интересно будет, а на следующий день посмотреть, каков будет размер инкрементального бэкапа поверх вчерашнего.

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть