여러 병렬 셸 작업을 실행하고 동시에 모두 모니터링하려면 어떻게 해야 합니까?

여러 병렬 셸 작업을 실행하고 동시에 모두 모니터링하려면 어떻게 해야 합니까?

나는 필터링하고 변환하기 위해 여러 프로그램을 통해 파이프해야 하는 대용량 파일(수백 개의 파일, 각각 수백 MB)을 가지고 있습니다. 저는 여러 CPU 코어를 활용하고 있으므로 각 파일에서 동일한 파이프의 여러 인스턴스를 실행하고 있습니다(최대 100개의 코어일 수 있으며 파이프의 일부로 ssh를 사용할 수 있습니다. 답변). 각 파이프를 모니터링하고 싶고 pv이를 위해 사용하고 있습니다. 내가 가지고 있는 최소한의 예는 다음과 같습니다.

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

실제로는 ssh를 통해 다른 시스템에 데이터를 전달하고 해당 시스템의 필터를 통해 파이프하는 것을 포함하여 파이프에서 여러 가지 다른 작업도 수행하지만 파이프는 항상 기본 호스트의 새 파일로 리디렉션되는 것으로 끝납니다. 또한 파이프의 어떤 단계에서도 전체 데이터 세트가 필요하지 않습니다. 라인 단위 또는 청크 단위로 작동할 수 있습니다.

현재 파이프의 각 인스턴스에 대해 별도의 터미널 창이 필요합니다. 내가 하고 싶은 것은 단일 터미널/셸에서 파이프의 n 병렬 인스턴스를 시작하고 자체 라인에 있는 각 PV 인스턴스의 출력을 얻는 것입니다. 이 같은:

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

n의 값은 터미널 창에 들어갈 수 있는 줄 수(예: 3-50 정도)입니다. 진행 보고서의 정확한 형식은 속도, 완료율, 경과 시간 및 예상 남은 시간을 포함하는 한 중요하지 않습니다. 를 사용하는 것도 중요하지 않습니다 pv. 쉽게 설치할 수 있는 한 다른 프로그램을 사용하거나 일반 쉘(bash, 가급적이면)을 사용해도 괜찮습니다. 그러나 중요한 것은 어떤 이유로 인해 파이프의 일부가 충돌하는 경우 가끔 파이프가 파손되는 경우를 처리할 수 있다는 것입니다. 또한 작업이 완료되거나(성공 여부에 관계없이) 처리되지 않은 파일이 아직 남아 있을 때마다 새 작업을 시작하고 싶습니다.

이 작업을 수행하는 방법에 대한 아이디어가 있습니까?

나는 이미 시도했습니다.GNU 병렬, 그러나 ssh 기능은 각 입력 파일이 먼저 원격 호스트로 전송된 다음 처리된 다음 결과가 다시 전송된다고 가정하는 것으로 보입니다. 이는 관련된 데이터 양과 각 처리 공간의 제한으로 인해 피하고 싶습니다. 마디.

답변1

이 작업을 수행하는 방법에 대한 아이디어가 있습니까?

아니요.

pv에는 원하는 작업을 수행할 수 있게 해주는 -c 및 -N 옵션이 있습니다.

$ 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] [  <=>  ]

하지만 해당 기능을 여러 파이프라인에 적용하는 방법을 알 수 없습니다.


그러나 PV의 매뉴얼 페이지를 보면 다음과 같은 내용을 볼 수 있습니다.

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

따라서 작은 창 클러스터에서 진행 상황을 볼 수 있는 한 이를 확장하여 여러 작업을 병렬로 실행할 수 있습니다. Xdialog를 사용해 보겠습니다.

현재 파이프의 각 인스턴스에 대해 별도의 터미널 창이 필요합니다.

내 요점은 대화식으로 많은 터미널 창을 열 필요가 없다는 것입니다. 하나의 스크립트로 많은 대화 상자 자체를 열 수 있습니다.


답변2

--pipeGNU Parallel을 보셨나요 ?

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

(강조를 위해 고양이가 포함됨)

기본값은 1MB 블록 크기이며 --block으로 조정할 수 있습니다.

-- 1-1 대응을 위한 편집 --

위 내용을 바탕으로 다음과 같은 1-1 대응을 얻을 수 있습니다.

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

(강조를 위해 고양이가 포함됨)

내부 병렬은 형제에 대해 알지 못하므로 server2보다 server1에서 더 많은 것을 생성할 수 있으므로 최적은 아닙니다. 이를 방지하는 한 가지 방법은 외부 병렬에서 -j1이지만 내부에 첫 번째 서버에 대한 충분한 블록만 있는 경우에는 최적이 아닙니다. 즉, 작업 부하의 균형을 완벽하게 맞추려면 이것으로 약간 조정해야 할 수도 있습니다. 어쩌면 --load 100% 또는 이와 유사한 것을 사용할 수도 있습니다.

--- 편집: 충돌 처리 ---

오류가 반환 되면 process_pipe명령을 2번 더 재시도해야 합니다.

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

관련 정보