Рано или поздно настройкой резервного копирования рабочих файлов озадачивается любой уважающий себя современный IT специалист. После ряда опечаток/ошибок программистов нашлось время для этого и у меня. Специфика веб-приложения такова, что рабочий каталог занимает более 50ГБ на жестких дисках, включая в себя около 900 тысяч мелких файлов (картинки, превьюшки, …). Поэтому в лоб решить задачу с помощью tar и аналогов не вышло. Да и хотелось бы иметь некоторую вариативность хранимых данных, а в случае с полным бэкапом реализация требовала больших затрат на хранение по сути одинаковых данных с небольшими изменениями. Плюс неплохо было бы дублировать копии на удаленном сервере бэкапов для снижения риска потери критической информации в результате краха железа. После скрупулезного анализа поисковых выдач и отбрасывания заведомо неподходящих мне методов, остановился на паре вариантов, навязываемых чаще всего в комментариях к самописным shell-велосипедам энтузиастов.
rdiff-backup
rdiff-backup показался с виду более подходящим и удобным. Написанный на python, он хранит данные инкрементально, позволяя получить состояние файла или директории в любой момент времени (в обозримом прошлом, учитывая время хранения снимков). Гибкое управление из консоли дает полную свободу действий и предоставляет полный контроль за ситуацией. Автоматическое создание бэкапов требует добавления в планировщик пары команд (вторая для подчистки старых снимков, не несущих какой-либо ценности в силу давности изменений). Но тестирование показало, что утилита весьма прожорлива и справляется с моей задачей крайне неохотно. Дело в том, что ежедневно изменяется небольшой объем данных (300МБ), но изменения затрагивают около 30 тысяч файлов. На выявление измененных файлов, судя по всему, тратится бОльшая часть времени работы программы. После часа наблюдений на увеличившийся до неприличных 20% iowait во время очередного запуска скрипта было принято решение попробовать другой софт и сравнить их между собой.
rsnapshot
rsnapshot, написанный на Perl, базируется на rsync. В рабочей директории программы (назовём так место, куда складываются бэкапы), создается ряд папок с индексом, который при каждом следующем запуске программы увеличивается до указанного в конфигурации значения. Затем устаревшая копия удаляется. Если пройти в любую из созданных папок, то внутри можно найти полную копию резервируемых данных. На это указывает и общий размер папки (при просмотре стандартными средствами Midnight Commander, например) — он равен сумме всех папок. На самом деле это не так. Программа создает жесткие ссылки между одинаковыми данными в пределах рабочего каталога. Таким образом, последняя актуальная копия является самой «тяжелой», а размер всех остальных составляет разницу в измененных данных.
Тестирование
Так, как оба варианта используют приблизительно одинаковый размер для хранения, пришло время проверить скорость выполнения заданий по созданию резервных копий. Для тестов была взята случайная папка проекта размером 11ГБ, содержащая 593 подкаталога разной степени вложенности и 230911 файлов. Размер файлов плавает от 4 до 800КБ, как указано выше, это в графический материал. Обе утилиты тестировались поочередно, внешние факторы практически полностью отсутствовали (нет других пользователей, нагрузки и тяжелых процессов). С помощью утилиты time было подсчитано время выполнения каждого из тестовых заданий, а также для сравнения копирование всего каталога средствами cp:
Первый бэкап — полное копирование в место бэкапа 11090МБ
real | user | sys | |
cp | 6m30.885s | 0m1.068s | 0m24.554s |
rsnapshot | 7m53.879s | 1m57.299s | 1m22.441s |
rdiff-backup | 10m50.314s | 3m26.073s | 1m0.928s |
Повторный запуск (в папке не было изменений)
real | user | sys | |
rsnapshot | 0m10.129s | 0m4.936s | 0m6.708s |
rdiff-backup | 1m3.969s | 1m0.616s | 0m2.048s |
Внутри каталога одна случайная папка дублируется (общий размер увеличивается до 13267МБ)
real | user | sys | |
rsnapshot | 0m31.175s | 0m22.001s | 0m17.365s |
rdiff-backup | 27m53.517s | 1m58.819s | 0m19.005s |
Повторный запуск после увеличения размера каталога (с последнего выполнения изменений нет)
real | user | sys | |
rsnapshot | 0m11.477s | 0m5.748s | 0m7.368s |
rdiff-backup | 1m16.366s | 1m13.713s | 0m1.912s |
Удаляем сдублированную папку, уменьшая размер каталога до первоначального
real | user | sys | |
rsnapshot | 0m13.885s | 0m6.388s | 0m9.077s |
rdiff-backup | 52m55.794s | 2m1.560s | 0m21.941s |
Контрольный повторный запуск без внесения изменений
real | user | sys | |
rsnapshot | 0m11.250s | 0m5.132s | 0m7.068s |
rdiff-backup | 1m2.380s | 1m0.088s | 0m1.792s |
Итоги
Как видно из таблиц сравнительного тестирования, rdiff-backup тяжело переваривает изменение большого количества мелких файлов, следовательно, рентабельнее использовать rsnapshot, дабы не тратить бОльшую часть времени работы сервера на пустое ковыряние в файловой системе. Возможно кому-то будет полезным увидеть результат тестирования и сэкономить затраченное мною время на поиск оптимального для описанных в статье случаев резервного копирования файлов.