Stream rdiff - дельта-дифференцирование?

У меня есть продукт, который делает онлайн-резервное копирование с использованием rdiff. В настоящее время происходит следующее:

  1. Скопируйте файл в промежуточную область (чтобы файл не исчезал и не изменялся, пока мы над ним работаем)

  2. Хеширует исходный файл и вычисляет сигнатуру rdiff (используется для разностного различия). Вычисляет разность дельты rdiff (если у нас нет предыдущей версии, этот шаг пропускается).

  3. Сжимает и шифрует полученную разницу дельты

В настоящее время эти этапы выполняются в отрыве друг от друга. В результате мы перебираем файл несколько раз. Для небольших файлов это не имеет большого значения (особенно с учетом кэширования диска), но для больших файлов (10 или даже 100 ГБ) это реальное снижение производительности.

Я хочу объединить все эти шаги в один этап чтения / записи.

Для этого мы должны иметь возможность выполнять все вышеперечисленные шаги в потоковом режиме, сохраняя при этом все "выходные данные" - хэш файла, сигнатура rdiff, сжатый и зашифрованный файл разностных разностей. Это повлечет за собой чтение блока данных из исходного файла (скажем, 100k?), Затем итерацию по файлу в памяти, чтобы обновить хеш, сигнатуру rdiff, выполнить разностное различие, а затем записать вывод в поток сжатия / шифрования., Цель состоит в том, чтобы значительно минимизировать объем работы диска.

В настоящее время мы используем rdiff.exe (который представляет собой тонкий слой поверх базовой библиотеки librsync) для вычисления сигнатур и генерирования двоичных дельт. Это означает, что они выполняются в отдельном процессе и выполняются в один прием, а не в потоковом режиме.

Как я могу получить это, чтобы сделать то, что мне нужно, с помощью библиотеки librsync?

1 ответ

Решение

Вы, вероятно, можете полностью пропустить шаг 1. Файл нельзя удалить, пока он открыт, и выбор соответствующих флагов блокировки при открытии может также помешать его изменению. Например, функция CreateFile принимает аргумент dwShareMode.

Вам нужно вычислить всю сигнатуру rdiff, прежде чем вы сможете начать создавать дельту rdiff. Вы можете избежать чтения всего файла, вычисляя подписи и затем дельты для каждого (скажем) блока размером 100 МБ за раз. Таким образом, вы потеряете некоторую эффективность сжатия *. Вы также можете подумать о переключении с rdiff на xdelta, который может создать дельта-файл за один проход по вводу.

Сжатие и шифрование могут выполняться параллельно с вычислением дельты. Если сжатие и шифрование выполняются отдельными программами, они часто допускают чтение со стандартного ввода и запись в стандартный вывод. Это может быть проще всего использовано конвейерами в командном файле, например:

rdiff signature oldfile oldfile.sig
rdiff delta oldfile.sig newfile | gzip -c | gpg -e -r ... > compressed_encrypted_delta

Если вы используете библиотеки для сжатия / шифрования в своей программе, вам нужно будет выбрать библиотеки, которые поддерживают потоковую работу.

* или потерять большую эффективность, если данные перемещаются в файле. Если кто-то добавит 100 МБ к файлу 10 ГБ, rdiff создаст дельта-файл размером около 100 МБ. rdiff, выполненный в блоках по 100 МБ или меньше, будет производить около 10 ГБ дельты. Блоки размером 200 МБ будут давать около 5 ГБ дельты, поскольку только половина данных в каждом блоке относится к соответствующему блоку старой версии файла.

Другие вопросы по тегам