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

31

Estou executando este comando:

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

Leva muito tempo. Eu olho para os processos com top. O processo bzip2 leva cerca de 95% e o postgres 5% de um núcleo. A waentrada é 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 possuem 16 núcleos.

Ou use uma alternativa ao bzip2?

O que posso fazer para aumentar o desempenho?

guettli
fonte
8
A menos que você precise do bzip2 por motivos herdados, minha experiência pessoal é que o xz oferece melhor compactação / tempo que o bzip2. Também é encadeado se você obtiver um programa novo o suficiente, e permite escalar o tempo e o uso de memória de gzipish até massivo, dependendo do que você deseja.
Perkins
6
"pigz" é outra opção - produz saída gzip em vez de saída bzip2. E basicamente tudo entende gzip.
Criggie
Você pode tentar criptografá-lo simetricamente com o GnuPG com compactação bzip2; parece surpreendentemente rápido em comparação com apenas compactá-lo, por algum motivo desconhecido, mesmo com o nível mais alto de compactação. É possível que o algoritmo seja mais rápido que a eficiência do meu programa de compactação regular, que é baseado em GUI.
Sule
2
Você não declarou os requisitos do seu algoritmo alternativo. Bzip2 é divisível. Isso é importante para você?
Martin Smith
7
" O que posso fazer para aumentar o desempenho? " - não compactá-lo? Na verdade, você não diz que precisa compactá-lo e não fazer o trabalho é sempre mais rápido do que fazer o trabalho. Faça do disco o gargalo.
TessellatingHeckler 10/09

Respostas:

49

Existem muitos algoritmos de compactação e bzip2é um dos mais lentos. A planície gziptende a ser significativamente mais rápida, geralmente com compressão não muito pior. Quando a velocidade é a mais importante, lzopé a minha favorita. Má compressão, mas oh, tão rápido.

Decidi me divertir e comparar alguns algoritmos, incluindo suas implementações paralelas. O arquivo de entrada é a saída do pg_dumpallcomando na minha estação de trabalho, um arquivo SQL de 1913 MB. O hardware é um i5 quad-core mais antigo. Os horários são apenas os da hora da compactação. Implementações paralelas estão definidas para usar todos os 4 núcleos. Tabela classificada por velocidade de compressã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 servidor estiverem inativos o suficiente para que todos possam ser usados ​​para compactação, pbzip2provavelmente haverá uma aceleração muito significativa. Mas você ainda precisa de mais velocidade e pode tolerar arquivos ~ 20% maiores, gzipprovavelmente é a sua melhor aposta.

Atualização: adicionei brotli(consulte a resposta dos TOOGAMs) à tabela. brotlis definição da qualidade de compressão tem um grande impacto sobre a taxa de compressão e a velocidade, por isso adicionou três configurações ( q0, q1, e q11). O padrão é q11, mas é extremamente lento e ainda pior que xz. q1parece muito bom; a mesma taxa de compressão que gzip, mas 4-5 vezes mais rápido!

Atualização: adicionada lbzip2(consulte o comentário de gmathts) e zstd(comentário de Johnny) à tabela e classifique-a pela velocidade de compactação. lbzip2coloca a bzip2família de volta na corrida comprimindo três vezes mais rápido que pbzip2com uma ótima taxa de compressão! zstdtambém parece razoável, mas é superado brotli (q1)tanto na proporção quanto na velocidade.

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

marcelm
fonte
11
Para uma tabela semelhante-ish com muito mais algoritmos, consulte mattmahoney.net/dc/text.html .
Dougal
11
@Dougal Fair o suficiente. Meu teste é em dados semelhantes como o OP embora ( pg_dumpallde saída), por isso é provavelmente um pouco mais representativo :)
marcelm
11
O zstd é outro que está faltando na tabela - para compactar nossos arquivos de log, descobri que um processo zstd de núcleo único supera 16 núcleos do pbzip2 com taxas de compactação comparáveis.
Johnny
11
lz4é um pouco mais rápido e mais eficiente do que lzop, a propósito. Ele usa mais RAM, o que é relevante em sistemas embarcados.
Daniel B
11
Se você estiver disposto a testar versões multithread, tente zstd -T4também. Para configurações muito rápidas, você pode tentar zstd -T4 -1, como zstdpadrão -3, que provavelmente é a configuração que você testou.
Ciano
37

Use pbzip2.

O manual diz:

O pbzip2 é uma implementação paralela do compressor de arquivos de classificação de blocos bzip2 que usa pthreads e alcança uma aceleração quase linear em máquinas SMP. A saída desta versão é totalmente compatível com o bzip2 v1.0.2 ou mais recente (ou seja, qualquer coisa compactada com o pbzip2 pode ser descompactada com o bzip2).

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

ThoriumBR
fonte
Isso é bom se você estiver compactando um arquivo, isso funciona horrivelmente através de um tubo embora
camelccc
@camelccc Por que você diz isso? Não acho que seja esse o caso. Você precisa de um produtor rápido ou de um grande buffer no tubo à sua frente para obter o desempenho ideal, mas isso também é válido para pixze pigzno tubo.
Michael - sqlbot
Depende do tamanho do que ele está comprimindo. Se você tem um buffer grande, tudo bem, como você diz, se você está canalizando algo muito maior que o aríete físico, descobri que as coisas podem ficar bem mais interessantes. Como você diz, provavelmente é verdade para qualquer algoritmo de compressão.
Camelccc 09/09
4
O bzip2 pode usar um pouco de memória RAM; portanto, rodar 16 trabalhadores bzip por vez pode consumir memória não trivial, acima de 1 GB. BTW, lbzip2parece dar melhor velocidade, uso de memória e compressão marginalmente melhor que pbzip2. Existem referências aqui: vbtechsupport.com/1614
gmatht
@gmatht lbzip2parece bom! Eu adicionei-lo para a minha resposta :)
marcelm
8

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

TOOGAM
fonte
Interessante, eu já tinha ouvido falar brotliantes, mas esqueci. Adicionei-o à tabela de benchmarks na minha resposta! Na verdade, fiquei um pouco decepcionado com o desempenho, exceto na configuração de qualidade 1, na qual ele forneceu a mesma taxa de compactação que gzipem uma velocidade muito maior.
marcelm
2

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

Em uma nota mais séria, é realmente muito bom . Eu o uso para tudo agora, porque simplesmente funciona e permite trocar velocidade por proporção em larga escala (na maioria das vezes, a velocidade importa mais do que o tamanho, já que o armazenamento é barato, mas a velocidade é um gargalo).
Em níveis de compactação que atingem compactação geral comparável à do bzip2, é significativamente mais rápido e, se você estiver disposto a pagar um pouco mais no tempo da CPU, quase poderá obter resultados semelhantes ao LZMA (embora seja mais lento que o bzip2). Em taxas de compactação um pouco piores, é muito, muito mais rápido que o bzip2 ou qualquer outra alternativa convencional.

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

Como bônus, se você fizer isso com frequência e quiser investir um tempo extra, poderá "treinar" o zstdcompressor com antecedência, o que aumenta a taxa de compressão e a velocidade. Observe que, para que o treinamento funcione bem, você precisará alimentá-lo com registros individuais, não com a coisa toda. Do jeito que a ferramenta funciona, ela espera muitas amostras pequenas e um tanto semelhantes para treinamento, e não uma bolha enorme.

Damon
fonte
melhor ainda, o uso pzstd (versão paralela) em máquinas com vários núcleos
borowis
1

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

Aqui estão alguns resultados do experimento que fiz na minha máquina. Eu usei o timecomando para medir o tempo de execução. input.txté um arquivo de texto de ~ 250mb que contém registros json arbitrários.

Usando o tamanho do bloco (maior) padrão ( --bestapenas 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 ( --fastargumento):

# 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 tanto surpreendente, considerando que a documentação diz:

A velocidade de compressão e descompressão não é afetada pelo tamanho do bloco

Jakub Kukul
fonte
Meu favorito atual é pbzip2. Você já tentou isso também? Esta pergunta é sobre um ambiente em que 16 núcleos estão disponíveis.
guettli
@ guettli infelizmente tenho que ficar com o bzip. Estou usando-o para trabalhos do Hadoop e o bzip é uma das compilações internas lá. Então, de certa forma, já está paralelizado.
Jakub Kukul