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

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

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

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

8 ответов

Решение

Вы можете использовать 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

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

Например использовать:

tar -c --use-compress-program=pigz -f tar.file dir_to_zip 

Общий подход

Есть вариант для 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

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

tar -I pbzip2 -cf OUTPUT_FILE.tar.bz2 DIRECTORY_TO_COMPRESS/

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

Вы можете ускорить распаковку, используя многопоточный декодер gzip, например Rapidgzip . Вы можете использовать его с tar следующим образом:

      python3 -m pip install --user rapidgzip
tar -x --use-compress-program=rapidgzip -f archive.tar

Благодаря 12-ядерному процессору Ryzen 3900X он может легко добиться 12-кратного ускорения для простой распаковки gzip, не учитывая GNU tar. Это результаты для большого файла размером 4 ГиБ (размер в сжатом виде: 3,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

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

Вот пример дляtarс современным компрессором, так как найти хорошие примеры на этом было сложно:

  • Делайте рекурсивные и направляющие (автономный не может этого сделать)
  • aptстихотворение для установкиzstdи утилиты для Ubuntu
  • Сжимайте несколько файлов и папок (одна только команда zstd может работать только с отдельными файлами)
  • Отображение прогресса с помощьюpv- показывает общее количество сжатых байтов и скорость сжатия ГБ/сек в режиме реального времени
  • Используйте все физические ядра с-T0
  • Установите уровень сжатия выше, чем по умолчанию, с помощью-8
  • Отображение результирующих настенных часов и времени процессора, использованного после завершения операции, с помощьюtime
      apt install zstd pv
DATA_DIR=/path/to/my/folder/to/compress
TARGET=/path/to/my/arcive.tar.zst

time (cd $DATA_DIR && tar -cf - * | pv  | zstd -T0 -8 -o $TARGET)
Другие вопросы по тегам