Menos alternativa com fome de recursos para piping 'cat' no gzip para arquivos enormes

3

Eu tenho alguns arquivos dos quais alguns são muito grandes (como vários GB), que eu preciso para concatenar em um arquivo grande e depois zip-lo, então algo como isto:

cat file1 file2 file3 file4 | gzip > compress.gz

que produz CPU e carga de memória extremamente altas na máquina ou até mesmo faz com que ela falhe, porque o cat gera vários GB.

Eu não posso usar arquivos tar, eu realmente preciso de um grande pedaço compactado por gzip.

Como posso produzir o mesmo arquivo gz de forma sequencial, para que eu não tenha que cat vários GB primeiro, mas ainda assim ter todos os arquivos no mesmo .gz no final?

    
por Foo Bar 14.11.2014 / 09:51

2 respostas

7

cat não usa nenhum tempo significativo da CPU (a menos que esteja envolvida a descriptografia ou descompactação no disco e seja responsável pelo processo cat , que é a leitura do disco) ou pela memória. Ele apenas lê o conteúdo dos arquivos e os grava no pipe em pequenos trechos em um loop.

No entanto, aqui, você não precisa disso. Você pode apenas fazer:

gzip -c file1 file2 file3 file4 > compress.gz

(não que isso faça uma diferença significativa).

Você pode diminuir a prioridade do processo gzip (wrt CPU scheduling) com o comando nice . Alguns sistemas possuem um comando ionice para o mesmo com E / S.

nice -n 19 ionice -c idle pigz -c file1 file2 file3 file4 > compress.gz

No Linux, seria executada uma versão paralela de gzip com o menor impacto possível sobre o sistema.

Ter compress.gz em um disco diferente (se estiver usando armazenamento rotacional) o tornaria mais eficiente.

O sistema pode armazenar em cache os dados que cat ou gzip/pigz leem na memória, se houver memória disponível para isso. Ele faz isso no caso de você precisar desses dados novamente. No processo, pode despejar outros dados em cache que seja mais útil. Aqui, esses dados provavelmente não precisam estar disponíveis.

Com o GNU dd , você pode usar iflag=nocache para avisar ao sistema para não armazenar os dados em cache:

for file in file1 file2 file3 file4; do
  ionice -c idle dd bs=128k status=none iflag=nocache < "$file"
done | nice pigz > compress.gz
    
por 14.11.2014 / 12:26
1

Se você quiser expandir o processo sem usar muitos recursos, tente modificar a prioridade de agendamento alterando o valor nice .:

nice -n 19 cat file1 file2 file3 file4 | gzip > compress.gz  

homem legal

  -n, --adjustment=N
         add integer N to the niceness (default 10)

Você também pode regular a velocidade do gzip que pode valer a pena investigar ( --best )

Outros métodos estão disponíveis, mas manterão os arquivos separados:

Se você estiver satisfeito em usar o formato de arquivo tar , então você pode usar o argumento zip para zipar o conteúdo em tempo real, no entanto, eles podem manter o processamento alto:

tar zcvf compress.tgz file[1234]

Ou você pode usar zip , que pode lidar com vários arquivos:

zip compress.zip file[1234]
    
por 14.11.2014 / 10:07