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

3179
osgx

У меня есть сотни похожих больших файлов (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.

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

3 ответа на вопрос

12
woliveirajr

Учитывая ваши данные, я предполагаю, что вы убедились, что ваши файлы действительно содержат 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 кБ).

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

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

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

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

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

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

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

Вы (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) для разделения больших файлов на куски.

Похожие вопросы