Использование многоядерных процессоров для сжатия / распаковки 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)