Зменшити бекапи на 99.5% з hashget

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

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

Порівняння

За законом жанру почну відразу з інтриги — порівняння результатів:

Вибірка даних
unpacked size
.tar.gz
hashget .tar.gz

WordPress-5.1.1
43 Mb
11 Mb ( 26% )
155 Kb ( 0.3% )

Ядро Linux 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'ую копію цього важливого файлу?

Взагалі-то hashget та вирішує цю проблему. При упаковці він створює дуже маленький бекап. При розпакуванні — повністю розпаковану систему, аналогічну до тієї, яка була б при tar -c / tar -x. (Іншими словами, це lossless упаковка)

Як працює hashget

У hashget є поняття Package та HashPackage, з їх допомогою він виконує дедуплікацію.

пакет (Пакет). Файл (зазвичай архів .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 читає файл.

Більш складні речі

Те, що описано вище, вже достатньо, для тих, кому «хочу як 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. При виявленні встановленого debian'івського пакету, якщо він не знайдеться в локальних HashPackage, спочатку робиться спроба просто завантажити HashPackage з хеш-сервера. І тільки якщо це не виходить - hashget сам завантажує та хешує пакет (і завантажує на hashserver, щоб надалі hashserver його надавав).

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

Інкрементальні та диференціальні бекапи, заплановане старіння

hashget дозволяє дуже просто зробити схему інкрементальних та диференціальних бекапів. Чому б нам не проіндексувати сам наш бекап (з усіма нашими унікальними файлами)? Одна команда --submit і все готове! Наступний бекап, який створить hashget, не включатиме файли з цього архіву.

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

Наприклад, якщо 1го числа робити фулл бекап, і індексувати його з часом життя до кінця місяця - ми отримаємо схему диференціального бекапу.

Якщо так само індексуватимемо і нові бекапи — буде схема інкрементальних бекапів.

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

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

Hashget спирається тільки на надійні джерела відновлення на Ваш розсуд. Які ви вважаєте надійними – ті й будуть використані.

FilePool та Glacier

механізм FilePool дозволяє не звертатися постійно до зовнішніх серверів для завантаження пакетів, а використовувати пакети з локального каталогу або корпоративного сервера, наприклад:

$ 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), а й, наприклад, 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

Чи коштує овчинка вичинки

У найпростішому випадку — ви просто менше платитимете за бекапи (якщо ви їх зберігаєте десь у хмарі за гроші). Можливо — набагато менше.

Але це єдине. Кількість перетворюється на якість. Ви можете використовувати це, щоб отримати якісний апгрейд схеми бекапів. Наприклад, якщо бекапи у нас тепер коротші — можна робити не щомісячний бекап, а щоденний. Зберігати їх не півроку, як раніше, а 5 років. Раніше зберігали в повільному але дешевому холодному сховищі (Glacier), тепер можете зберігати в гарячому, звідки можна завжди швидко завантажити бекап і відновитися за хвилини, а не за день.

Можна збільшити надійність зберігання бекапів. Якщо зараз ми їх зберігаємо в одному сховищі, то скоротивши обсяг бекапів – зможемо зберігати у 2-3 сховищах та безболісно пережити, якщо одне з них пошкодиться.

Як спробувати та почати користуватися?

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

Джерело: habr.com

Додати коментар або відгук