Сжатие многих похожих больших файлов

18

У меня есть сотни похожих больших файлов (30 мегабайт каждый), которые я хочу сжать. Каждая пара файлов содержит 99% одинаковых данных (разница менее 1%), поэтому я ожидаю, что у меня будет архив не более 40-50 мегабайт.

Один файл может быть сжат от 30 МБ до 13-15 МБ (с xz -1, gz -1, bzip2 -1), но при сжатии два или более файлов , которые я хочу иметь архив с размером 13-15MB + N*0.3MBгде N является количеством файлов.

При использовании tar(для создания сплошного архива) и xz -6(для определения словаря сжатия больше одного файла - Обновить - этого было недостаточно! ), У меня все еще есть архив с размером N*13MB.

Я думаю, что и то gzipи другое bzip2мне не поможет, потому что у них словарь меньше 1 МБ, а мой поток tar имеет повторения каждые 30 МБ.

Как мне заархивировать мою проблему в современном Linux, используя стандартные инструменты?

Можно ли настроить xzсжатие быстро, но использовать словарь размером более 30-60 МБ?

Обновление : сделал трюк с tar c input_directory | xz --lzma2=dict=128M,mode=fast,mf=hc4 --memory=2G > compressed.tar.xz. Не уверен насчет необходимости mf=hc4и --memory=2Gвариантов; но dict=128Mустановите словарь достаточно большим (больше, чем один файл) и mode=fastсделайте процесс немного быстрее, чем -e.

osgx
источник
Запуск xz -1 --memory=2Gне помог, проверено на 2 и 4 файлах из набора.
osgx

Ответы:

12

Учитывая ваши данные, я предполагаю, что вы убедились, что ваши файлы действительно содержат 99% общих данных с непрерывной (или почти непрерывной) разницей в них 1%.

Во-первых, вы должны использовать tar для создания одного архива с вашими файлами внутри. Для тестов я бы создал .tar с 10 файлами, размером 300 МБ.

Затем, используя xz, вы должны установить его так, чтобы словарь был больше, чем размер одного файла. Поскольку вы не говорите, если у вас есть ограничения памяти, я бы пошел с xz -9. Нет смысла не использовать всю доступную память.

Я бы также использовал предустановку --extreme, чтобы проверить, имеет ли это значение.

Размер словаря

В одной имеющейся у меня документации - site - сказано, что размер словаря примерно равен использованию памяти декомпрессором. А параметр -1 означает 1 ДБ, -6 означает 10 МБ (или 8 МБ в другой части того же руководства). Вот почему вы не получаете никаких преимуществ, собирая эти файлы вместе. Использование -9 сделает декомпрессор (и, следовательно, словарь) 64 МБ, и я думаю, что это то, что вы хотели.

редактировать

Другая возможность будет использовать другой компрессор. Я бы пошел с 7zip, но сначала скопировал бы эти файлы, а затем 7zip.

В зависимости от содержимого ваших файлов, возможно, вы могли бы использовать 7zip с методом PPM-D (вместо LZMA или LZMA2, который используется по умолчанию и используется в xz)

Не хорошо: Zip (dict = 32 кБ), Bzip (dict = 900 кБ).

woliveirajr
источник
И Xz, и 7-Zip используют LZMA2, так что в этом нет никакой пользы. PPMD оптимизирован для чрезвычайно медленного, но с высокой степенью сжатия извлечения энтропии из уже сжатых носителей (например, MP3 и видео). Маловероятно, чтобы найти большое сходство между этими двумя файлами и сохранить их в словаре - не более вероятно, чем LZMA2.
allquixotic
woliveirajr, как насчет использования not -1или -9preset, но указать dict=64MBили dict=128MBи установить mode=fast?
osgx
Использование dict = xxMB вместо -1 или -9 пошло бы прямо в точку, но, поскольку я не знаю, как xz устанавливает другие параметры, когда вы просто используете -9, я не знаю, пропустите ли вы что-нибудь остальное. Я думаю, что вы в правильном направлении, и только тестирование даст вам точный ответ.
woliveirajr
3
С помощью xz --lzma2=dict=128M,mode=fast,mf=hc4 --memory=2Gя смог сжать 250 файлов (7,5 ГБ) до 18 МБ архива tar.xz.
osgx
@osgx :) это очень мило. Если это не заняло слишком много времени (т. Е. Это соответствует вашим потребностям), проблема решена! :) Таким образом, вы получили final_size = 13MB + x * 6kB, более или менее.
woliveirajr
9

Если они действительно на 99% похожи, как вы говорите, вы сможете использовать bsdiff или аналогичный алгоритм для расчета различий между файлами. Является ли разница кумулятивной (т. Е. Каждый файл немного отличается от первого) или разница между любыми двумя файлами почти одинакова?

Если это не кумулятивно, вы должны быть в состоянии:

  • Возьмите любой произвольный файл в качестве «базового уровня»
  • Запустите bsdiffсравнение базового файла с каждым дополнительным файлом
  • Храните каждый diff как отдельный файл вместе с базовым файлом
  • Запустите компрессор, как xzпо результатам (базовая линия + различия).

Результат должен быть намного меньше, чем просто xzвесь архив.

Затем вы можете «восстановить» исходные файлы, «применив» diff к базовой линии, чтобы получить все остальные файлы.

allquixotic
источник
Не накопительно. («Каждая пара файлов содержит 99% одинаковых данных ...»)
osgx
1
Если различия не накапливаются, то это должно быть хорошим применением bsdiffалгоритма. Попробуйте.
allquixotic
Спасибо за ваш ответ, но я уже выполнил задачу с помощью xz: tar c directory|xz --lzma2=dict=128M,mode=fastи удалил входные файлы. На самом деле мои входные файлы были текстовыми, поэтому я даже могу использовать diff вместо bsdiff(который не установлен на моем ПК).
osgx
5

Вы (I) можете использовать tar с каким-либо архиватором, способным обнаруживать паттерны на большом расстоянии, например, rzip или lrzip ( Readme ). Оба используют обнаружение / дедупликацию дальнего радиуса действия, тогда rzip использует bzip2, а lrzip использует xz (lzma) / ZPAQ:

rzip - это программа сжатия, похожая по функциональности на gzip или bzip2, но способная использовать избыточность на больших расстояниях в файлах, что иногда позволяет rzip создавать гораздо лучшие коэффициенты сжатия, чем другие программы. ... Основным преимуществом rzip является то, что он имеет эффективный буфер истории 900 Мбайт. Это означает, что он может найти совпадающие фрагменты входного файла на огромных расстояниях по сравнению с другими обычно используемыми программами сжатия. Программа gzip для сравнения использует буфер истории 32 кбайт, а bzip2 использует буфер истории 900 кбайт

lrzip имеет больший буфер и может использовать многие алгоритмы сжатия (очень быстрый, быстрый, хороший и один из лучших - ZPAQ) после дедупликации:

Lrzip использует расширенную версию rzip, которая в первом проходе уменьшает избыточность на большие расстояния. Модификации lrzip позволяют масштабировать его в соответствии с объемом памяти.

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

Другой способ - использовать программу резервного копирования bup с дедупликацией на уровне блоков / сегментов, основанную на git packfile:

Он использует алгоритм скользящей контрольной суммы (аналогично rsync) для разделения больших файлов на куски.

osgx
источник