Pull to refresh

Разрабатываем новый формат файла для бэкапа сайтов

Reading time 5 min
Views 25K
Сейчас работаю над новым PHP-скриптом, который будет бэкапить не только базу данных, но и все файлы сайта.

Изначально планировалось использовать один из распространённых форматов архивов. В данном случае, первое, что приходит в голову — ZIP и TAR. Для них есть множество готовых классов, а расширение ZIP даже входит в стандартную поставку PHP. Но изучив спецификации форматов, а также опробовал готовые решения, склонился к изобретению своего велосипеда.

Просьба «велосипедохейтеров» воздержаться от комментариев в стиле «хватит нам велосипедов». В конце концов, без создания «велосипедов» не было бы ни Google, ни Google Chrome, ни Facebook, ни WinRAR и 7-Zip.

Почему не TAR?


TAR является наиболее распространенным форматом в unix-системах. И любой админ, не задумываясь, для бэкапа файлов напишет сам или скопирует один из множества готовых скриптов из интернета, которые используют системную программу tar. Но TAR был разработан очень давно, и кроме того, изначально предназначался для создания архивов на ленте. В связи с этим, у него есть следующие недостатки.

Отсутствие индекса
В TAR отсутствует каталог с содержимым архива. Поэтому для просмотра содержимого архива нужно сканировать архив, пройдясь по всем заголовкам файлов. Что на больших архивах может занимать значительное время.

Невозможно использовать смещение (fseek) внутри контейнера
Поскольку TAR не поддерживает сжатия, то его обычно целиком сжимают с помощью gzip или bzip2. В связи с этим, если нужно достать файл из конца архива, то нужно, по сути, распаковать все сжатые данные из архива, пока не дойдем до нужного файла.

Нельзя записывать поток в архив
Так как в TAR в заголовке файла хранится размер файла (без него мы не сможем найти заголовок следующего файла). То мы не можем напрямую в архив писать поток (т.е. еще несуществующий файл, размеры которого вначале неизвестны). Потому при бэкапе того же MySQL, сначала отдельно делают дамп базы, а только потом его вместе с остальными файлами упаковывают в TAR.

Отсутствует контроль целостности файлов
Не хранятся контрольные суммы для файлов.

Почему не ZIP?


ZIP является самым распространенным форматом на Windows, да и, наверное, вообще в мире. Он, как и TAR, является выходцем из 80-х, но при этом последний раз обновлялся в 2007 году. У него есть отсутствующие в TAR индекс, возможность быстро перемещаться по контейнеру, контроль целостности файлов, даже запись потока. Но у него также есть недостатки.

Нет поддержки непрерывных (Solid) архивов
Что весьма плохо сказывается на сжимаемости, когда много мелких файлов.

Время хранится в MS-DOS формате
А это значит, что даты хранятся с точностью до 2 секунд, плюс в случае с PHP это лишние преобразования из unix timestamp в MS-DOS формат и обратно.

Отсутствует шифрование названий файлов в архиве
Шифруется только содержимое файлов, заголовки и центральный каталог в открытом виде.

В принципе недостатки значительно менее существенные, чем у TAR, и я уже собирался использовать ZIP. Но ситуацию омрачал тот факт, что некоторые расширенные возможности (запись потока, unix атрибуты файлов) готовые библиотеки, включая стандартный класс ZipArchive – не поддерживают. А, следовательно, для их поддержки пришлось бы писать свою реализацию ZIP.

В общем, решил рассмотреть другие варианты. После гугления, удалось найти документацию по форматам RAR, 7Z, DAR, ACE, также поковырял немного закрытые CBU и TIB. В процессе закрались мысли о построении собственного велосипеда.

Новый формат файла для бэкапа сайтов


Итак, новый формат (недолго думая он был назван SXB от Sypex Backup) представляет собой компиляцию из идей, подсмотренных в различных форматах плюс несколько своих.

Основные задачи, которые ставились при разработке формата SXB:
  • Блочная дедупликация данных
  • Инкрементальный бэкап на блочном уровне
  • Сохранение потоков в архив
  • Дополнительные типы данных (а не только файлы и каталоги)
  • Непрерывный архив
  • Наличие индекса
  • Быстрый случайный доступ к содержимому
  • Может содержать как сжатые, так и не сжатые данные (для плохо сжимаемых файлов, типа фоток, архивов и т.п.)
  • Многотомность
  • Шифрование, как содержимого, так и заголовков файлов
  • Поддержка версионности
  • Контроль целостности содержимого

Также при разработке учитывается специфика PHP для работы с файлами больше 2 ГБ.
Некоторых пункты опишу подробнее.

Блочная дедупликация данных


Дедупликация данных – это технология, при помощи которой из архива исключаются повторяющиеся данные, что позволяет уменьшить его размер. Существует дедупликация на уровне файлов и на уровне блоков. В первом случае сравниваются хэши файлов, во втором – хэши отдельных блоков файлов.

Для SXB формата была выбрана блочная дедупликация так как она лучше подходит для бэкапа сайтов. К примеру, это позволяет при инкрементальных бэкапах, постоянно растущих, логов или таблиц БД сохранять их не полностью, а только небольшой блок с добавленными данными.

Сохранение потоков в архив

Эта фича нужна для того, чтобы бэкап MySQL можно было сохранять сразу в архив, без создания временных файлов. Что кроме ускорения работы, уменьшает требования к свободному месту, а также позволяет применять дедупликацию на уровне отдельных таблиц, а не всего SQL-файла.

Дополнительные типы данных

Cложно представить современный сайт не использующий БД. И поскольку разрабатывается новый формат, то возникла идея отойти от стандартного бэкапа MySQL в SQL-файл.

В формат SXB кроме файлов и каталогов, добавлены специальные типы данных для бэкапа БД (структура таблицы, содержимое таблицы, триггеры, функции и т.п.). Структура MySQL объектов будет храниться в виде соответствующих CREATE запросов, а содержимое таблиц — в виде текста с табуляцией в качестве разделителя (такой формат компактнее и позволяет значительно быстрее дампить/восстанавливать данные).

В общем, на этом пока закругляюсь, а то и так уже много написал, если будет интересно могу добавить больше технических подробностей.

А теперь о том, для чего затевалась статья


Хотелось проверить дедупликацию на реальных сайтах. Из тех крупных сайтов, что были под рукой, один на собственном движке (206 МБ), второй на vbulletin (934 МБ), дедупликация показала весьма воодушевляющие результаты.

WinRAR запускался в режиме непрерывный архив (так быстрее и компактнее файл). Для 7-Zip тестировался старый алгоритм LZMA, и новый LZMA2 который загружает все 4 ядра процессора. Использовался PHP 5.4.10 под Win 7 x64.

Да, естественно, при максимальном сжатии WinRAR и 7-Zip покажут более высокое сжатие, но при этом они жрут гигабайты памяти и по полной нагружают все 4 ядра на значительное время. Тягаться по степени сжатия в принципе с ними не нужно, тут немного другая задача. Но то, что php скрипт может показывать близкие результаты к многопоточным сишным программам — вселяет оптимизм.

Желающие помочь в разработке, и кому просто интересно, как много на вашем сайте дубликатов, прошу протестить специальный упрощенный PHP-скриптик.

Интересует количество исключенных дедупликацией данных, размеры и желательно сравнение с другими архиваторами (размер и время, режим, достаточно самый быстрый). В результате выдается вот такая инфа:
dirs         162
files        6811
full_size    206.133
dup_size     28.721
archive_size 152.277
duplicates   3119
bigfiles     477
bf_blocks    5220
bf_dup       316
bf_size      154.426
bf_dup_size  8.027
time         13.53622

Ну и напоследок, в качестве справочной информации, ссылки на спецификации форматов
ZIP File Format Specification
TAR File Format Specification
RAR File Format Specification
7Z File Format Specification
DAR File Format Specification
ACE File Format Specification
Tags:
Hubs:
+71
Comments 143
Comments Comments 143

Articles