여러 백그라운드 작업의 데이터를 Bash의 단일 데이터 스트림으로 다시 병합하는 방법

여러 백그라운드 작업의 데이터를 Bash의 단일 데이터 스트림으로 다시 병합하는 방법

단일 코어 바운드 작업을 여러 부분으로 분할하고 각 부분을 bash에서 별도의 작업으로 실행하여 병렬화할 수 있는 유사한 상황에 직면했지만 반환된 데이터를 다시 단일 데이터로 변환하는 데 문제가 있습니다. 개울. 지금까지 나의 순진한 접근 방식은 임시 폴더를 만들고, PID를 추적하고, 각 스레드가 해당 PID를 파일에 쓰도록 한 다음 모든 작업이 완료되면 모든 PID를 읽고 순서대로 병합하는 것입니다. PID가 파일로 생성되었습니다. 이러한 다중 입력 및 단일 출력 상황을 처리하기 위해 bash/셸 도구를 사용하는 더 좋은 방법이 있습니까?

답변1

지금까지 나의 순진한 접근 방식은 임시 폴더를 만들고, PID를 추적하고, 각 스레드가 해당 PID를 파일에 쓰도록 한 다음 모든 작업이 완료되면 모든 PID를 읽고 순서대로 병합하는 것입니다. PID가 파일로 생성되었습니다.

이것이 GNU Parallel이 하는 일과 거의 똑같습니다.

parallel do_stuff ::: job1 job2 job3 ... jobn > output

몇 가지 추가 이점이 있습니다.

  • 임시 파일은 자동으로 삭제되므로 GNU Parallel을 종료하더라도 정리가 필요하지 않습니다.
  • 현재 실행 중인 작업에 임시 공간만 제공하면 됩니다. 완료된 작업에 대한 임시 공간은 작업이 완료된 후 해제됩니다.
  • 출력이 입력과 동일한 순서로 이루어지도록 하려면 를 사용하십시오 --keep-order.
  • 다른 작업의 한 줄씩 혼합된 출력을 원하는 경우 을 사용하십시오 --line-buffer.

GNU Parallel에는 작업을 더 작은 작업으로 분할하는 많은 기능이 있습니다. 어쩌면 이 중 하나를 사용하여 더 작은 일자리를 만들 수도 있을까요?

답변2

귀하의 제안은 완료하기 전에 데이터를 병합하는 방법에 대해 생각하지 않으므로 매우 합리적인 것 같습니다. 그러니 솔직히 말해서 그것은 나쁜 접근 방식이 아닙니다!

또 다른 일반적인 솔루션은 데이터를 수집하고, 데이터 "슬라이스" 의미/경계를 이해하고, 언제든지 콘텐츠를 병합하는 중앙 프로그램을 보유하는 것입니다.

이를 수행하는 방법은 생성하는 데이터 유형에 따라 크게 달라집니다! 이것은 UNIX, UDP 또는 TCP 소켓에서 메시지를 읽는 최소한의 프로그램만큼 간단할 수 있습니다(그러나 특정 데이터 포인트가 완료된 지점을 아는 직렬화 형식을 사용하는 것을 고려할 수도 있습니다). . 아니면 소규모 관계형 데이터베이스 서버(PostgreSQL?)를 실행하세요. 또는 ØMQ 소켓을 사용하여 여러 게시자를 보유하고 중앙에서 이러한 게시자의 구독자로 병합할 수 있으며, 이는 네트워크를 통해 즉시 작동한다는 추가 이점도 있습니다. 또는 데이터베이스를 사용하여 시계열 데이터를 저장합니다. 또는 데이터가 로그 메시지처럼 보이기 때문에 syslog 또는 syslog를 통해 결과를 기록하는 작업자를 구현하고 sd_journal_printJournald의 저널 네임스페이스를 사용하여 모든 로그 메시지를 단일 파일에 저장합니다. 또는...

결국 귀하의 옵션은 다음과 같습니다.

  1. 많은 파일에 쓰고 나중에 병합합니다(여기서는 다음을 사용하고 있습니다).파일 시스템문제 없이 다른 작업자가 다른 파일에 대한 동시 쓰기 액세스를 허용합니다.
  2. 일종의 파이프/소켓/프로세스 간 통신 방법을 사용하여 중앙 프로세스에 메시지를 보냅니다. 여기서는 데이터 구조를 알고 있고 즉시 병합을 수행할 수 있다는 사실을 사용합니다.

실제로 이를 수행하는 방법은 데이터 구조, 볼륨 및 병합 방법에 따라 100% 달라집니다.

관련 정보