Hora de compactar arquivos muito grandes (100G)

27

Eu tenho que compactar vários arquivos muito grandes (80 GB ish) e estou surpreso com a (falta de) velocidade que meu sistema está exibindo. Eu recebo cerca de 500 MB / min de velocidade de conversão; usando top, parece que estou usando uma única CPU em aproximadamente 100%.

Tenho certeza de que não é (apenas) a velocidade de acesso ao disco, pois a criação de um tararquivo (foi assim que o arquivo 80G foi criado) levou apenas alguns minutos (talvez 5 ou 10), mas depois de mais de 2 horas meu comando gzip simples ainda está não realizado.

Em suma:

tar -cvf myStuff.tar myDir/*

Levou <5 minutos para criar um arquivo tar de 87 G

gzip myStuff.tar

Levou duas horas e 10 minutos, criando um arquivo zip 55G.

Minha pergunta: isso é normal? Existem certas opções gzippara acelerar as coisas? Seria mais rápido concatenar os comandos e usar tar -cvfz? Vi referências a pigz- Implementação Paralela do GZip - mas infelizmente não consigo instalar o software na máquina que estou usando, portanto isso não é uma opção para mim. Veja, por exemplo, esta pergunta anterior .

Pretendo tentar algumas dessas opções e cronometrá-las - mas é bem provável que não atinja "a combinação mágica" de opções. Espero que alguém neste site conheça o truque certo para acelerar as coisas.

Quando tiver os resultados de outros estudos disponíveis, atualizarei esta pergunta - mas se alguém tiver um truque particularmente bom disponível, eu realmente aprecio isso. Talvez o gzip leve mais tempo de processamento do que eu imaginava ...

ATUALIZAR

Conforme prometido, tentei os truques sugeridos abaixo: altere a quantidade de compactação e o destino do arquivo. Obtive os seguintes resultados para um alcatrão de cerca de 4,1 GB:

flag    user      system   size    sameDisk
-1     189.77s    13.64s  2.786G     +7.2s 
-2     197.20s    12.88s  2.776G     +3.4s
-3     207.03s    10.49s  2.739G     +1.2s
-4     223.28s    13.73s  2.735G     +0.9s
-5     237.79s     9.28s  2.704G     -0.4s
-6     271.69s    14.56s  2.700G     +1.4s
-7     307.70s    10.97s  2.699G     +0.9s
-8     528.66s    10.51s  2.698G     -6.3s
-9     722.61s    12.24s  2.698G     -4.0s

Então, sim, alterar o sinalizador do padrão -6para o mais rápido -1me dá uma aceleração de 30%, com (para os meus dados) praticamente nenhuma alteração no tamanho do arquivo zip. Se eu estou usando o mesmo disco ou outro não faz essencialmente nenhuma diferença (eu precisaria executar isso várias vezes para obter alguma significância estatística).

Se alguém estiver interessado, gerei esses benchmarks de tempo usando os dois scripts a seguir:

#!/bin/bash
# compare compression speeds with different options
sameDisk='./'
otherDisk='/tmp/'
sourceDir='/dirToCompress'
logFile='./timerOutput'
rm $logFile

for i in {1..9}
  do  /usr/bin/time -a --output=timerOutput ./compressWith $sourceDir $i $sameDisk $logFile
  do  /usr/bin/time -a --output=timerOutput ./compressWith $sourceDir $i $otherDisk $logFile
done

E o segundo script ( compressWith):

#!/bin/bash
# use: compressWith sourceDir compressionFlag destinationDisk logFile
echo "compressing $1 to $3 with setting $2" >> $4
tar -c $1 | gzip -$2 > $3test-$2.tar.gz

Três coisas a serem observadas:

  1. Usando em /usr/bin/timevez de time, já que o comando interno de bashtem muito menos opções que o comando GNU
  2. Não me incomodei em usar a --formatopção, embora isso facilite a leitura do arquivo de log
  3. Eu usei um script em um script, pois timeparecia operar apenas no primeiro comando em uma sequência canalizada (então, fiz com que parecesse um único comando ...).

Com tudo isso aprendido, minhas conclusões são

  1. Acelere as coisas com a -1bandeira (resposta aceita)
  2. É gasto muito mais tempo compactando os dados do que lendo no disco
  3. Invista em um software de compactação mais rápido ( pigzparece ser uma boa escolha).
  4. Se você tiver vários arquivos para compactar, poderá colocar cada gzipcomando em seu próprio encadeamento e usar mais da CPU disponível (homem pobre pigz)

Obrigado a todos que me ajudaram a aprender tudo isso!

Floris
fonte
tar -cvf não faz qualquer compressão por isso vai ser mais rápido
parkydr
2
@ Florida: que tipo de dados você está tentando compactar? nota lateral: $> gzip -c myStuff.tar | pv -r -b > myStuff.tar.gzmostrará a rapidez com que sua máquina está compactando o material. side-note2: armazene o resultado em um disco diferente.
Akira #
3
Desculpe, eu interpretei mal sua pergunta. gzip tem a opção --fast para selecionar o mais rápido compressão
parkydr
1
@parkydr: A opção --fast é uma que eu não conhecia ... é a última da manpágina e não li até agora (porque é classificada por 'comando de letra única', que é -#) . Isso vai me ensinar a RTFM! Esta será a próxima coisa que eu tento!
Floris 03/03
2
Observe que, se um compilador adequado estiver disponível na máquina, e as permissões do sistema de arquivos não estiverem definidas para proibir a execução de binários dos diretórios aos quais você tem acesso, você poderá compilar pigze executá-lo de onde quer que o tenha construído, sem instalá-lo. Se não houver um compilador, você poderá compilá-lo em outro computador, embora isso esteja começando a se esforçar mais do que vale a pena. (Dependendo de quão mal você precisa esta compressão para correr mais rápido, eu acho.)
David Z

Respostas:

27

Você pode alterar a velocidade do gzip usando --fast --bestou -#onde # é um número entre 1 e 9 (1 é o mais rápido, mas menos compacto, 9 é o mais lento, mas mais compactação). Por padrão, o gzip é executado no nível 6.

robingrindrod
fonte
26

A razão pela qual o tar leva tão pouco tempo em comparação com o gzip é que há muito pouca sobrecarga computacional ao copiar seus arquivos em um único arquivo (que é o que ele faz). Por outro lado, o gzip está usando algoritmos de compactação para reduzir o arquivo tar.

O problema é que o gzip está restrito (como você descobriu) a um único thread.

Digite pigz , que pode usar vários threads para executar a compactação. Um exemplo de como usar isso seria:

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

Há um bom resumo succint da opção --use-compress-program em um site irmão .

Steve Gore
fonte
Obrigado pela sua resposta e links. Na verdade, eu mencionei pigz na pergunta.
Floris
Esta é a resposta correta aqui ..!
Stolsvik
4

Parece que estou usando uma única CPU em aproximadamente 100%.

Isso implica que não há um problema de desempenho de E / S, mas que a compactação está usando apenas um encadeamento (que será o caso do gzip).

Se você conseguir obter o acesso / acordo necessário para instalar outras ferramentas, o 7zip também suporta vários threads para aproveitar as CPUs com vários núcleos, embora não tenha certeza se isso se estende tanto ao formato gzip quanto ao seu.

Se você estiver usando apenas o gzip por enquanto e tiver vários arquivos para compactar, tente compactá-los individualmente - dessa forma, usará mais dessa CPU multinúcleo executando mais de um processo em paralelo. Tenha cuidado para não exagerar, porque assim que chegar perto da capacidade do seu subsistema de E / S, o desempenho cairá vertiginosamente (para diminuir do que se você estivesse usando um processo / encadeamento), pois a latência dos movimentos da cabeça se torna significativa gargalo.

David Spillett
fonte
Obrigado pela sua contribuição. Você me deu uma ideia (para a qual obtém um voto positivo): como tenho vários arquivos para criar, basta escrever os comandos individuais seguidos de um &- e deixar o sistema cuidar disso a partir daí. Cada um deles será executado em seu próprio processador e, como passo muito mais tempo na compactação do que na E / S, levará o mesmo tempo para fazer um e para todos os 10 deles. Então eu fico "de multi core" de um executável que é único segmento ...
Floris
1

Pode-se explorar também o número de processos disponíveis no pigz, que geralmente possui desempenho mais rápido, conforme mostrado no comando a seguir

tar cf - diretório para arquivar | pigz -0 -p largenumber> mydir.tar.gz

Exemplo - tar cf - patha | pigz -0 -p 32> patha.tar.gz

Provavelmente, isso é mais rápido do que os métodos sugeridos no post, pois -p é o número de processos que se pode executar. Na minha experiência pessoal, definir um valor muito grande não prejudica o desempenho se o diretório a ser arquivado consistir em um grande número de arquivos pequenos. Caso contrário, o valor padrão considerado é 8. Para arquivos grandes, minha recomendação seria definir esse valor como o número total de encadeamentos suportados no sistema.

Exemplo de configuração de um valor de p = 32 no caso de uma máquina com 32 CPUs ajuda.

0 é destinado à compactação pigz mais rápida, pois não compacta o arquivo e é focado na velocidade. O valor padrão é 6 para compactação.

Ankit Shah
fonte