bzip2 muito lento. Vários núcleos são disponíveis

21

Estou executando este comando:

pg_dumpall | bzip2 > cluster-$(date --iso).sql.bz2

Demora demais. Eu olho para os processos com top . O processo do bzip2 leva cerca de 95% e postgres 5% de um núcleo. A entrada wa está baixa. Isso significa que o disco não é o gargalo.

O que posso fazer para aumentar o desempenho?

Talvez deixe o bzip2 usar mais núcleos. Os servidores tem 16 núcleos.

Ou use uma alternativa ao bzip2?

O que posso fazer para aumentar o desempenho?

    
por guettli 08.09.2017 / 20:39

5 respostas

35

Existem muitos algoritmos de compactação por perto e bzip2 é um dos mais lentos. O gzip simples tende a ser significativamente mais rápido, geralmente com compressão não muito pior. Quando a velocidade é a mais importante, lzop é o meu favorito. Má compressão, mas oh tão rápido.

Eu decidi me divertir e comparar alguns algoritmos, incluindo suas implementações paralelas. O arquivo de entrada é a saída do comando pg_dumpall em minha estação de trabalho, um arquivo SQL de 1913 MB. O hardware é um i5 quad-core mais antigo. Os tempos são tempos de relógio apenas da compressão. Implementações paralelas são configuradas para usar todos os 4 núcleos. Tabela classificada por velocidade de compactação.

Algorithm     Compressed size        Compression          Decompression

lzop           398MB    20.8%      4.2s    455.6MB/s     3.1s    617.3MB/s
lz4            416MB    21.7%      4.5s    424.2MB/s     1.6s   1181.3MB/s
brotli (q0)    307MB    16.1%      7.3s    262.1MB/s     4.9s    390.5MB/s
brotli (q1)    234MB    12.2%      8.7s    220.0MB/s     4.9s    390.5MB/s
zstd           266MB    13.9%     11.9s    161.1MB/s     3.5s    539.5MB/s
pigz (x4)      232MB    12.1%     13.1s    146.1MB/s     4.2s    455.6MB/s
gzip           232MB    12.1%     39.1s     48.9MB/s     9.2s    208.0MB/s
lbzip2 (x4)    188MB     9.9%     42.0s     45.6MB/s    13.2s    144.9MB/s
pbzip2 (x4)    189MB     9.9%    117.5s     16.3MB/s    20.1s     95.2MB/s
bzip2          189MB     9.9%    273.4s      7.0MB/s    42.8s     44.7MB/s
pixz (x4)      132MB     6.9%    456.3s      4.2MB/s     7.9s    242.2MB/s
xz             132MB     6.9%   1027.8s      1.9MB/s    17.3s    110.6MB/s
brotli (q11)   141MB     7.4%   4979.2s      0.4MB/s     3.6s    531.6MB/s

Se os 16 núcleos do seu servidor estiverem ociosos o suficiente para que todos possam ser usados para compactação, pbzip2 provavelmente lhe dará uma aceleração muito significativa. Mas você precisa de mais velocidade ainda e pode tolerar arquivos ~ 20% maiores, gzip é provavelmente sua melhor aposta.

Atualização: adicionei os resultados de brotli (consulte a resposta do TOOGAMs) à tabela. A configuração da qualidade de compactação brotli s tem um impacto muito grande na taxa de compactação e na velocidade, portanto, adicionei três configurações ( q0 , q1 e q11 ). O padrão é q11 , mas é extremamente lento e ainda pior que xz . q1 parece muito bom; a mesma taxa de compressão que gzip , mas 4-5 vezes mais rápido!

Atualização: Adicionamos lbzip2 (veja o comentário do gmathts) e zstd (comentário do Johnny) à tabela e classificamos por velocidade de compactação. lbzip2 coloca a família bzip2 de volta na corrida, comprimindo três vezes mais rápido que pbzip2 com uma excelente taxa de compactação! zstd também parece razoável, mas é batido por brotli (q1) na proporção e na velocidade.

Minha conclusão original de que plain gzip é a melhor aposta está começando a parecer quase boba. Embora para onipresença, ainda não pode ser batida;)

    
por 09.09.2017 / 01:40
36

Use o pbzip2.

O manual diz:

pbzip2 is a parallel implementation of the bzip2 block-sorting file compressor that uses pthreads and achieves near-linear speedup on SMP machines. The output of this version is fully compatible with bzip2 v1.0.2 or newer (ie: anything compressed with pbzip2 can be decompressed with bzip2).

Ele detecta automaticamente o número de processadores que você possui e cria threads de acordo.

    
por 08.09.2017 / 21:22
8

Você não mencionou um sistema operacional. Se o Windows, 7-Zip com ZStandard (Liberações) é uma versão do 7-Zip que foi modificada para fornecer suporte para usar todos esses algoritmos.

    
por 09.09.2017 / 10:09
2

Use zstd . Se for bom o suficiente para o Facebook, provavelmente é bom o suficiente para você também.

Em uma nota mais séria, na verdade é muito bom . Eu o uso para tudo agora, porque ele simplesmente funciona e permite que você troque a velocidade pela taxa em grande escala (na maioria das vezes, a velocidade é mais importante que o tamanho, pois o armazenamento é barato, mas a velocidade é um gargalo). Em níveis de compactação que atingem compactação geral comparável como bzip2, é significativamente mais rápido, e se você estiver disposto a pagar um pouco mais em tempo de CPU, você pode quase alcançar resultados semelhantes ao LZMA (embora seja mais lento do que bzip2). Em índices de compactação um pouco piores, ele é muito, muito mais rápido que o bzip2 ou qualquer outra alternativa convencional.

Agora, você está compactando um dump SQL, que é quase tão embaraçoso para compactar quanto possível. Até mesmo os compressores mais pobres têm uma boa pontuação nesse tipo de dados. Assim, você pode executar zstd com um nível de compactação mais baixo, que será executado dezenas de vezes mais rápido e ainda atingir 95-99% da mesma compactação nesses dados.

Como bônus, se você fizer isso com frequência e quiser investir algum tempo extra, poderá "treinar" o compressor zstd com antecedência, o que aumenta a taxa de compactação e a velocidade. Observe que, para que o treinamento funcione bem, você precisará fornecer registros individuais, e não a coisa toda. A maneira como a ferramenta funciona, ela espera muitas amostras pequenas e um pouco similares para treinamento, não uma grande bolha.

    
por 10.09.2017 / 17:37
1

Parece que ajustar (diminuir) o tamanho do bloco pode ter um impacto significativo no tempo de compactação.

Aqui estão alguns resultados da experiência que fiz na minha máquina. Eu usei o comando time para medir o tempo de execução. input.txt é um arquivo de texto de ~ 250MB contendo registros json arbitrários.

Usando o tamanho de bloco padrão (maior) ( --best simplesmente seleciona o comportamento padrão):

# time cat input.txt | bzip2 --best > input-compressed-best.txt.bz

real    0m48.918s
user    0m48.397s
sys     0m0.767s

Usando o menor tamanho de bloco ( --fast argument):

# time cat input.txt | bzip2 --fast > input-compressed-fast.txt.bz

real    0m33.859s
user    0m33.571s
sys     0m0.741s

Esta foi uma descoberta um pouco surpreendente, considerando que a documentação diz:

Compression and decompression speed are virtually unaffected by block size

    
por 25.07.2018 / 13:12