Дедупликация и инкременты: как мы перестали гонять по сети одни и те же файлы дважды
Бэкап 50 ГБ занимал полсуток по WAN. Пока промышленная дедупликация стоит как самолёт, собрали схему на инкрементах с хардлинками - объём хранения упал в разы, окно резко сократилось.
В индустрии начинают обсуждать дедупликацию данных как следующий шаг в резервном копировании
У одного из клиентов - два офиса, между ними VPN-канал на 2 Мбит/с. Основной файлач в головном, бэкап-сервер в резервном. Казалось бы, нормальная схема - про disk-to-disk мы уже писали, диски дешевеют, всё хорошо. Но когда данных стало за 50 ГБ, ночное окно бэкапа начало выпрыгивать в день. Полный бэкап в 50 ГБ через 2 Мбит/с - это физически около 55 часов. Даже если канал свободен и ни один другой процесс не лезет - никакое ночное окно такое не вмещает.
Решение напрашивалось: инкрементальный бэкап. Копируй не всё, а только то, что изменилось. Но здесь начинается ловушка.
Инкрементальный бэкап - это не так просто, как звучит
Классический инкрементальный бэкап - это набор полного образа плюс цепочка изменений. Для восстановления нужно поднять всю цепочку в правильном порядке: полный, потом каждый инкремент. Цепочка за две недели - это четырнадцать операций вместо одной. Восстановление превращается в квест. А ещё если в середине цепочки какой-то архив повреждён - дальше не читается ничто.
Были варианты покупки нормального enterprise-решения с дедупликацией. Тогда это стоило столько, что разговор быстро заканчивался. Data Domain только появился, Avamar был для другого масштаба и бюджета. Покупать ради одного клиента - смысла нет.
В итоге нашли другой путь, который сложился из двух вещей вместе.
Хардлинки как дешёвая дедупликация
Идея простая. Делаем полный бэкап в каталог, скажем, backup/2005-10-16. На следующий день запускаем rsync с ключом --link-dest, который указывает на предыдущий снимок. Rsync сравнивает файлы на целевой стороне с предыдущей копией: если файл не изменился - не копирует его снова, а создаёт хардлинк на тот же самый inode. Если изменился - копирует новую версию.
В результате каждый каталог backup/2005-10-17, backup/2005-10-18 и так далее выглядит как полный снимок всей файловой системы за ту дату. Но фактически на диске хранится только то, что реально поменялось. Неизменные файлы занимают место ровно один раз - сколько бы снимков ни было.
Для восстановления - никаких цепочек. Заходишь в нужный каталог, берёшь нужный файл. Всё.
По сети гоняем только дельту - то, что реально изменилось с прошлой ночи. У этого клиента ежедневно менялось от силы 3-5% данных. Вместо 50 ГБ по WAN - полтора-два гигабайта. Окно бэкапа сжалось до полутора часов.
Что по хранению
Посчитали за первый месяц работы. Тридцать снимков, каждый выглядит как 50 ГБ - итого по наивному расчёту 1,5 ТБ. По факту на диске заняли около 120 ГБ: первый полный плюс накопленные изменения за месяц. Примерно двенадцатикратная разница.
Это и есть суть: платишь за хранение изменений, а видишь полный снимок на каждую дату.
Где эта схема ломается
Несколько граблей нашли сразу, несколько - позже.
Хардлинки работают только в пределах одного раздела. Если бэкап-диск - это отдельная смонтированная файловая система, всё нормально. Если начнёшь мудрить с несколькими разделами для разных клиентов - хардлинки через границу раздела не перейдут, rsync будет копировать целиком.
Файлы с частыми малыми изменениями жрут место честно. База данных, которая меняет несколько блоков каждую минуту - это каждый раз новый файл в снимке. Базы мы выносим отдельно: dump, архив, потом уже rsync. Иначе схема с хардлинками им не поможет.
Удаление старых снимков нетривиально. Нельзя просто снести каталог самого старого снимка - на часть файлов могут держаться хардлинки из более новых снимков. Удалять надо через find -inum или специальный скрипт, иначе место не освободится корректно. Мы написали небольшой скрипт, который сначала считает ссылки, потом аккуратно чистит.
rsync и Windows-шары дружат не всегда. Когда источником был файловый сервер на Windows, подключали через Samba или rsync-сервер на стороне источника. В некоторых конфигурациях метаданные файлов (временные метки, права) слегка расходятся между копиями, и rsync начинает думать, что файл изменился, хотя содержимое то же самое. Лечится флагом --checksum, но это уже медленнее.
Промышленная дедупликация делает то же самое, только лучше
Идея дедупликации - разбить данные на блоки, посчитать хэши, хранить уникальные блоки один раз - работает и внутри одного файла, и между разными файлами, и между разными клиентами. Наши хардлинки умеют только на уровне целых файлов. Если файл изменился хотя бы на байт - он хранится заново целиком.
Для большинства файловых данных это работает нормально: документы, фотографии, конфиги меняются целиком или не меняются вовсе. Но для баз данных, образов виртуальных машин, почтовых ящиков - блочная дедупликация выиграет с разгромным счётом.
Когда это станет доступно по цене для среднего бизнеса - вопрос открытый. Пока берём то, что есть.
Итог
Для инфраструктуры, где мы ведём сопровождение, эта схема стала стандартной для клиентов с медленными каналами и файловыми данными. rsync плюс --link-dest плюс скрипт ротации снимков - никаких лицензий, никаких vendor lock-in, работает на любом Linux.
Главный вывод такой: если канал узкий, а данных много, вопрос не в том, брать ли инкременты - вопрос в том, как организовать хранение так, чтобы из инкрементов можно было восстанавливаться без боли. Хардлинки дают полный снимок на каждую дату за цену изменений. Это не магия - это просто честный способ не гонять по сети одни и те же байты дважды.