
나는 필터링하고 변환하기 위해 여러 프로그램을 통해 파이프해야 하는 대용량 파일(수백 개의 파일, 각각 수백 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
--pipe
GNU 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*