Использование нескольких ядер для сжатия / распаковки tar + gzip / bzip

225

Я обычно сжимаю использование tar zcvfи распаковываю использование tar zxvf(используя gzip по привычке).

Недавно я получил четырехъядерный процессор с гиперпоточностью, поэтому у меня 8 логических ядер, и я заметил, что многие из ядер не используются во время сжатия / распаковки.

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

user1118764
источник
Решение, предложенное Xiong Chiamiov выше, прекрасно работает. Я только что зарезервировал свой ноутбук с помощью .tar.bz2, и это заняло 132 минуты, используя только одну нить процессора. Затем я скомпилировал и установил tar из источника: gnu.org/software/tar. Я включил параметры, упомянутые на шаге настройки: ./configure --with-gzip = pigz --with-bzip2 = lbzip2 --with-lzip = plzip Я снова запустил резервное копирование, и это заняло всего 32 минуты. Это лучше, чем улучшение в 4 раза! Я наблюдал за системным монитором, и все 4 процессора (8 потоков) все время оставались ровными на уровне 100%. Это лучшее решение.
Уоррен Северин

Ответы:

309

Вы можете использовать pigz вместо gzip, который выполняет сжатие gzip на нескольких ядрах. Вместо использования опции -z вы должны передать это через pigz:

tar cf - paths-to-archive | pigz > archive.tar.gz

По умолчанию pigz использует количество доступных ядер, или восемь, если не может запросить это. Вы можете запросить больше с -pn, например, -p 32. pigz имеет те же параметры, что и gzip, поэтому вы можете запросить лучшее сжатие с -9. Например

tar cf - paths-to-archive | pigz -9 -p 32 > archive.tar.gz
Марк Адлер
источник
3
Как вы используете PIGZ для декомпрессии таким же образом? Или это работает только на сжатие?
user788171
42
pigz использует несколько ядер для декомпрессии, но только с ограниченным улучшением по сравнению с одним ядром. Формат deflate не поддается параллельной декомпрессии. Распаковка должна выполняться последовательно. Другие ядра для Pigz-декомпрессии используются для чтения, записи и вычисления CRC. При сжатии с другой стороны, pigz приближается к фактору п улучшения с п ядер.
Марк Адлер
7
Дефис здесь - это стандартный вывод (см. Эту страницу ).
Гаррет
3
Да. 100% совместимость в обоих направлениях.
Марк Адлер
4
Фактически, процессинг тратится на процессорное время, поэтому это не сильно поможет. Формат tar - это просто копия входного файла с блоками заголовков между файлами.
Марк Адлер
324

Вы также можете использовать tar-флаг "--use-compress-program =", чтобы указать tar, какую программу сжатия использовать.

Например, используйте:

tar -c --use-compress-program=pigz -f tar.file dir_to_zip 
Джен
источник
21
Это удивительный маленький кусочек знаний и заслуживает большего количества голосов. Я понятия не имел, что этот вариант вообще существует, и я читал справочную страницу несколько раз за эти годы.
Рэндалл Хант
2
@ValerioSchiavoni: Не здесь, я получаю полную нагрузку на все 4 ядра (Ubuntu 15.04 'Vivid').
Bovender
8
Я предпочитаю tar - dir_to_zip | pv | pigz > tar.filePV помогает мне оценить, вы можете пропустить это. Но все же легче написать и запомнить.
Оффенсо
@ NathanS.Watson-Haigh Да, ты. Просто заключите имя программы и аргументы в кавычки. man tarговорит так, как и это .
23 марта,
1
В 2020 году zstdэто самый быстрый инструмент для этого. Заметное ускорение при сжатии и распаковке. Используйте tar -cf --use-compress-program=zstdmtдля этого многопоточность.
Jadelord
112

Общий подход

Есть вариант для tarпрограммы:

-I, --use-compress-program PROG
      filter through PROG (must accept -d)

Вы можете использовать многопоточную версию архиватора или утилиту сжатия.

Самые популярные многопоточные архиваторы - это pigz (вместо gzip) и pbzip2 (вместо bzip2). Например:

$ tar -I pbzip2 -cf OUTPUT_FILE.tar.bz2 paths_to_archive
$ tar --use-compress-program=pigz -cf OUTPUT_FILE.tar.gz paths_to_archive

Архиватор должен принять -d. Если ваша утилита замены не имеет этого параметра и / или вам нужно указать дополнительные параметры, используйте каналы (добавьте параметры при необходимости):

$ tar cf - paths_to_archive | pbzip2 > OUTPUT_FILE.tar.gz
$ tar cf - paths_to_archive | pigz > OUTPUT_FILE.tar.gz

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

p7zip

Для сжатия p7zip вам понадобится небольшой скрипт оболочки, подобный следующему:

#!/bin/sh
case $1 in
  -d) 7za -txz -si -so e;;
   *) 7za -txz -si -so a .;;
esac 2>/dev/null

Сохраните его как 7zhelper.sh. Вот пример использования:

$ tar -I 7zhelper.sh -cf OUTPUT_FILE.tar.7z paths_to_archive
$ tar -I 7zhelper.sh -xf OUTPUT_FILE.tar.7z

XZ

Что касается многопоточной поддержки XZ. Если вы используете версию 5.2.0 или выше XZ Utils, вы можете использовать несколько ядер для сжатия, установив -Tили --threadsустановив соответствующее значение с помощью переменной среды XZ_DEFAULTS (например XZ_DEFAULTS="-T 0").

Это фрагмент man для версии 5.1.0alpha:

Многопоточное сжатие и распаковка еще не реализованы, поэтому этот параметр пока не действует.

Однако это не будет работать для распаковки файлов, которые также не были сжаты с включенной многопоточностью. От человека для версии 5.2.2:

Потоковая декомпрессия еще не была реализована. Он будет работать только с файлами, которые содержат несколько блоков с информацией о размере в заголовках блоков. Все файлы, сжатые в многопоточном режиме, соответствуют этому условию, но файлы, сжатые в однопоточном режиме, не работают, даже если используется --block-size = size.

Перекомпиляция с заменой

Если вы собираете tar из исходников, вы можете перекомпилировать с параметрами

--with-gzip=pigz
--with-bzip2=lbzip2
--with-lzip=plzip

После перекомпиляции tar с этими опциями вы можете проверить вывод справки tar:

$ tar --help | grep "lbzip2\|plzip\|pigz"
  -j, --bzip2                filter the archive through lbzip2
      --lzip                 filter the archive through plzip
  -z, --gzip, --gunzip, --ungzip   filter the archive through pigz
Максим Суслов
источник
1
Это действительно лучший ответ. Я определенно восстановлю свою смолу!
1
Я только что нашел pbzip2 и mpibzip2 . mpibzip2 выглядит очень многообещающе для кластеров или, например, если у вас есть ноутбук и многоядерный настольный компьютер.
Это отличный и продуманный ответ. Можно упомянуть, что многопоточное сжатие (например, с помощью pigz) включено только при чтении из файла. Обработка STDIN на самом деле может быть медленнее.
oᴉɹǝɥɔ
3
Плюс 1 за xzвариант. Это самый простой, но эффективный подход.
selurvedu
2
export XZ_DEFAULTS="-T 0"перед вызовом tarс опцией -Jдля xz сжатие работает как шарм.
Scai
13

Вы можете использовать ярлык -Iдля --use-compress-programпереключения tar и вызывать pbzip2сжатие bzip2 на нескольких ядрах:

tar -I pbzip2 -cf OUTPUT_FILE.tar.bz2 DIRECTORY_TO_COMPRESS/
panticz
источник
Хороший TL; DR для ответа @ MaximSuslov .
einpoklum
Это возвращает tar: home/cc/ziptest: Cannot stat: No such file or directory tar: Exiting with failure status due to previous errors`
Араш
1

Если вы хотите иметь больше гибкости с именами файлов и параметрами сжатия, вы можете использовать:

find /my/path/ -type f -name "*.sql" -o -name "*.log" -exec \
tar -P --transform='s@/my/path/@@g' -cf - {} + | \
pigz -9 -p 4 > myarchive.tar.gz

Шаг 1: find

find /my/path/ -type f -name "*.sql" -o -name "*.log" -exec

Эта команда будет искать файлы, которые вы хотите заархивировать, в этом случае /my/path/*.sqlи /my/path/*.log. Добавьте столько, -o -name "pattern"сколько хотите.

-execвыполнит следующую команду, используя результаты find:tar

Шаг 2: tar

tar -P --transform='s@/my/path/@@g' -cf - {} +

--transformпростой параметр замены строки Он удалит путь к файлам из архива, так что корень архива становится текущим каталогом при извлечении. Обратите внимание, что вы не можете использовать -Cопцию для изменения каталога, поскольку вы потеряете преимущества find: все файлы каталога будут включены.

-Pговорит tarиспользовать абсолютные пути, поэтому не вызывает предупреждение «Удаление начального` / 'из имен членов ». В --transformлюбом случае ведущий '/' должен быть удален .

-cf -говорит tarиспользовать имя тарбола, которое мы укажем позже

{} +использует все findнайденные ранее файлы

Шаг 3: pigz

pigz -9 -p 4

Используйте столько параметров, сколько хотите. В данном случае -9это уровень сжатия и -p 4количество ядер, выделенных для сжатия. Если вы запустите это на сильно загруженном веб-сервере, вы, вероятно, не захотите использовать все доступные ядра.

Шаг 4: имя архива

> myarchive.tar.gz

В заключение.

завывания
источник
0

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

pgebhard
источник