如何執行多個並行 shell 作業並同時監視所有作業?

如何執行多個並行 shell 作業並同時監視所有作業?

我有大量大文件(數百個文件,每個文件數百 MB),我需要透過許多程式來過濾和轉換它們。我正在利用多個 CPU 核心,因此我在每個文件上運行同一管道的多個實例(最多可以有一百個核心,並且可以使用 ssh 作為管道的一部分,以防這對回答)。我想監控每個管道,我正在pv為此使用。這是我所擁有的一個最小範例:

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

實際上,我還在管道中做了其他幾件事,包括通過ssh 將數據傳遞到其他計算機,並將其通過這些計算機上的過濾器進行管道傳輸,但管道始終會以重定向到主主機上的新文件結束。此外,管道中的任何階段都不需要整個資料集;它們可以逐行或逐塊地操作。

目前,我需要為管道的每個實例提供一個單獨的終端視窗。我想做的是在單一終端機/shell 中啟動管道的 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,使用其他程式也可以,只要我可以輕鬆安裝它或只是簡單的 shell(最好是 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'

(包括貓以強調)

預設為 1 MB 區塊大小,可以使用 --block 進行調整。

-- 編輯 1-1 對應關係 --

根據以上內容,您可以得到如下 1-1 對應:

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

(包括貓以強調)

這並不是最優的,因為內部並行不會知道其同級,因此可能會在 server1 上產生比 server2 更多的並行。避免這種情況的一種方法是在外部並行上設定 -j1,但如果內部並行只有足夠的區塊用於第一台伺服器,則這不是最佳選擇。換句話說:為了完美平衡你的工作負載,你可能需要稍微調整一下 - 甚至可能使用 --load 100% 或類似的。

---編輯:處理崩潰---

如果process_pipe傳回錯誤,則應再重試該指令 2 次:

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

相關內容