Como posso executar vários trabalhos de shell paralelos e monitorar todos eles de uma só vez?

3

Eu tenho um grande número de arquivos grandes (centenas de arquivos, centenas de MB cada) que eu preciso passar por vários programas para filtrá-los e convertê-los. Estou aproveitando vários núcleos de CPU, então estou executando várias instâncias do mesmo canal em cada arquivo (pode ter até cem núcleos e poderia usar ssh como parte do canal, caso isso faça alguma diferença para o responda). Eu quero monitorar cada pipe e estou usando pv para isso. Aqui está um exemplo mínimo do que tenho:

$ pv file-001.gz | gunzip | xz > file-001.xz
1.58GB 0:00:02 [ 713MB/s] [=================================>] 100%

Na realidade, eu também faço várias outras coisas no pipe, incluindo passar dados para outras máquinas através do ssh e canalizá-las através de filtros nessas máquinas, mas o pipe sempre termina com um redirecionamento para um novo arquivo na máquina principal. hospedeiro. Além disso, nenhum estágio no pipe requer o conjunto de dados inteiro; eles podem operar em uma base de linha por linha ou por pedaço.

Atualmente, eu preciso de uma janela de terminal separada para cada instância do pipe. O que eu gostaria de fazer é iniciar n instâncias paralelas do pipe em um único terminal / shell e obter a saída de cada instância pv em uma linha própria. Algo parecido com isto:

1.48GB 0:00:54 [ 704MB/s] [===============================>  ]  97% ETA 00:00:06
1.58GB 0:01:00 [ 713MB/s] [=================================>] 100%
0.75GB 0:00:31 [ 709MB/s] [================>                 ]  50% ETA 00:00:29

O valor para n seria o número de linhas que eu posso ajustar em uma janela de terminal, digamos 3-50 ou mais. O formato exato do relatório de progresso não é importante, desde que inclua a velocidade, a porcentagem concluída, o tempo decorrido e o tempo restante estimado. Também não é importante que eu use pv , não há problema em usar outro programa, desde que eu possa facilmente instalá-lo ou simplesmente shell (bash, de preferência). O importante, no entanto, é que o método pode manipular ocasionalmente um cano quebrado no caso de uma parte do cano cair por algum motivo. Também gostaria de iniciar novos trabalhos sempre que um trabalho for concluído (com êxito ou não) e ainda houver arquivos não processados.

Alguma idéia de como fazer isso?

Note que eu já tentei GNU Parallel , mas seus recursos ssh parecem assumir que cada arquivo de entrada é primeiro transferido para o host remoto, em seguida, processado e, em seguida, o resultado transferido de volta, o que eu quero evitar devido à quantidade de dados envolvidos e à quantidade limitada de espaço em cada nó de processamento.

    
por Fabian Fagerholm 19.09.2012 / 10:05

2 respostas

4

Você viu --pipe para o Paralelo GNU?

cat bigfiles* | pv | parallel --pipe -S server1,server2 'cat | process_pipe'

(gato incluído para ênfase)

O padrão é o tamanho de bloco de 1 MB, que pode ser ajustado com --block.

- editar para correspondência 1-1 -

Com base no acima, você pode obter uma correspondência 1-1 como esta:

parallel --eta "cat {} | parallel --pipe -S server1,server2 'cat | process_pipe' > {}.out" ::: bigfiles*

(gato incluído para ênfase)

Não é ideal, pois o paralelo interno não saberá sobre seus irmãos e, portanto, poderá gerar mais em server1 que em server2. Uma maneira de evitar isso é -j1 no paralelo externo, mas isso não será o ideal se o interior tiver blocos suficientes para o primeiro servidor. Em outras palavras: Para equilibrar perfeitamente sua carga de trabalho, você pode ter que mexer um pouco com isso - talvez até mesmo usar - carregar 100% ou similar.

--- editar: lidar com falhas ---

Se o process_pipe retornar com um erro, isso deve ser repetido 2 vezes mais:

parallel --retries 3 --eta "cat {} | parallel --pipe -S server1,server2 'cat | process_pipe' > {}.out" ::: bigfiles*
    
por 19.09.2012 / 12:38
3

Any ideas on how to do this?

Não.

pv tem opções -c e -N que devem permitir que você faça o que quiser

$ pv -cN source access.log | gzip | pv -cN gzip > access.log.gz
source:  760MB 0:00:15 [37.4MB/s] [=>     ] 19% ETA 0:01:02
  gzip: 34.5MB 0:00:15 [1.74MB/s] [  <=>  ]

mas não consigo ver como aplicar esse recurso a vários pipelines

No entanto, se você olhar para a página man do pv você verá isso

          (tar cf - . \
           | pv -n -s $(du -sb . | awk '{print $1}') \
           | gzip -9 > out.tgz) 2>&1 \
          | dialog --gauge 'Progress' 7 70

Assim, você pode estender isso para executar várias tarefas em paralelo, desde que seja aceitável visualizar o progresso em um cluster de pequenas janelas. Eu tentaria Xdialog.

Currently, I need a separate terminal window for each instance of the pipe

O meu ponto principal é que não é necessário que você interativamente abra muitas janelas de terminal, você pode ter um script aberto em muitas caixas de diálogo.

por 19.09.2012 / 12:36