日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

好用的parallel命令

發布時間:2023/12/18 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 好用的parallel命令 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

簡介

有時,我們需要處理一批數據,使用while循環是個不錯的想法,但while循環中的命令是一個一個執行的,如果要批量處理的數據很多,執行時間就會很長,而parallel可以讓命令并行執行,從而縮短命令執行時間。
下面,我們先用ncat來模擬一個處理數據的接口。

模擬接口

ncat -lk 8088 -c 'sleep 1;printf "HTTP/1.1 200 OK\r\nContent-Type: plain/text\r\nContent-Length: 3\r\n\r\nok\n"' 復制代碼

此接口直接睡眠1秒,然后返回一個ok,表示數據處理成功。

調用接口

curl -X POST http://localhost:8088/user/add -d '{"user_id": 1, "user_name":"u1"}' 復制代碼

測試數據

假設有10條數據,在data.txt中,如下:

1 u1 2 u2 3 u3 ... 復制代碼

使用while循環處理

$ time while read -r -a line; docurl -X POST http://localhost:8088/user/add -d '{"user_id": '${line[0]}', "user_name":"'${line[1]}'"}'done < data.txt ok ok ok ok ok ok ok ok ok okreal 0m10.276s user 0m0.094s sys 0m0.096s 復制代碼

使用while循環處理,其中time命令用來計時,real表示while命令的執行時間,可以看到,處理完10條數據花了約10秒,接下來我們使用parallel并發執行。

使用parallel并發執行

$ time cat data.txt | parallel -j10 -C '\s+' curl -s -X POST http://localhost:8088/user/add -d \'{\"user_id\": {1}, \"user_name\":\"{2}\"}\' ok ok ok ok ok ok ok ok ok okreal 0m1.205s user 0m0.203s sys 0m0.060s 復制代碼

使用parallel命令并發執行curl,-j10表示最多10個并發進程,-C '\s+' 表示使用空白來拆分每行(注:\s+是表示空白的正則表達式),這樣就可以使用{1}表示第1列,{2}表示第2列了,如我們所預期的,10條數據使用10個并發,處理完約1秒。

有用的--tag選項

上例的接口很簡單,直接返回ok,但在有大量數據需要處理時,有可能出現部分數據處理失敗,像上面的執行結果中,就很難知道是哪些數據處理失敗了,還好parallel提供了--tag選項,可以將處理的數據與執行結果都打印出來,如下:

$ cat data.txt | parallel -j10 -C '\s+' --tag curl -s -X POST http://localhost:8088/user/add -d \'{\"user_id\": {1}, \"user_name\":\"{2}\"}\' 1 u1 ok 2 u2 ok 4 u4 ok 3 u3 ok 5 u5 ok 6 u6 ok 7 u7 ok 8 u8 ok 9 u9 ok 10 u10 ok 復制代碼

這樣,什么數據執行對應什么結果,就一目了然了。

查看進度

如果有大量數據需要處理,處理時能直觀的看到一個進度就再好不過了,parallel提供了3個查看進度的選項,--bar、--progress和--eta,一般使用--bar、--progress即可。
其中--bar適合待處理數據量確定的場景,因為parallel需要讀取所有數據后才能根據數據總量計算進度條。
而--progress適合待處理數據量未知的場景,只能看到已經處理了多少條數據,如下:

# 使用 --bar 顯示進度條 cat data.txt | parallel -j10 -C '\s+' --tag --bar curl -s -X POST http://localhost:8088/user/add -d \'{\"user_id\": {1}, \"user_name\":\"{2}\"}\'# 使用 --progress 顯示處理條數 cat data.txt | parallel -j10 -C '\s+' --tag --progress curl -s -X POST http://localhost:8088/user/add -d \'{\"user_id\": {1}, \"user_name\":\"{2}\"}\' 復制代碼

--joblog與--resume-failed選項

相信當你使用腳本處理有一定數據量的數據時,一定會遇到數據偶爾處理失敗的情況(由于網絡不穩定),這時你需要將處理失敗的數據再次找出來,然后再次處理,過程還是挺麻煩的。
好在parallel命令已經考慮到了這種場景,并提供了--joblog與--resume-failed選項,當有失敗產生時,你只需要再次執行整個命令行即可。

# 模擬接口修改如下,使得接口有概率失敗,成功返回true,失敗返回fail ncat -lk 8088 -c 'sleep 1;r=$(head /dev/urandom | tr -dc 0-9 | head -c 1);printf "HTTP/1.1 200 OK\r\nContent-Type: plain/text\r\nContent-Length: 5\r\n\r\n";[ $r -lt 5 ] && printf "true\n" || printf "fail\n"'# parallel添加--joblog job.log --resume-failed參數,這次我們將處理腳本封裝為一個函數,并用export -f使其生效,這樣就可以在parallel中直接使用函數了 function deal_data(){res=$(curl -s -X POST http://localhost:8088/user/add -d '{"user_id": '$1', "user_name":"'$2'"}')echo "$res"[[ "$res" == "true" ]] && return 0 || return 1 } export -f deal_data$ cat data.txt | parallel -j10 -C '\s+' --tag --joblog job.log --resume-failed deal_data1 u1 true2 u2 true4 u4 true5 u5 true3 u3 fail6 u6 true8 u8 true7 u7 true9 u9 true10 u10 fail# 上面有2條數據處理失敗,我們再次執行以上命令,如下,可以看到本次只執行了之前失敗的2條數據,perfect! $ cat data.txt | parallel -j10 -C '\s+' --tag --joblog job.log --resume-failed deal_data3 u3 true10 u10 true 復制代碼

--semaphore選項

parallel既然提供了并發,那么必然會遇到并發沖突問題,比如sed命令就不支持并發的修改同一文件,不過parallel已經提供了--semaphore選項來解決這個問題了。
如下,其中sem是parallel --semaphore的別名,與其是等價的。

function deal_data(){res=$(curl -s -X POST http://localhost:8088/user/add -d '{"user_id": '$1', "user_name":"'$2'"}')echo "$res"[[ "$res" == "true" ]] && return 0 || return 1 } export -f deal_data$ grep -vnP 'ok$' data.txt |parallel -C ':|\s+' --tag 'deal_data {2} {3}; [[ $? -eq 0 ]] && sem -j1 sed -i \"{1} s/$/ ok/\" data.txt' 復制代碼

這里的邏輯是,每處理成功data.txt中的一條數據,就使用sed將data.txt中的那行數據末尾加一個ok,表示執行成功,然后在前面使用grep找不包含ok的數據,就達到了命令每次都處理未處理或處理失敗數據的邏輯。而sem -j1保護了sed,避免sed命令并發執行。

與mysql結合使用

parallel還可以和mysql結合使用,將任務導入mysql中或是執行mysql中的任務,如下:

# 1.將任務數據導入到pardb庫的paralleljobs表中,pardb庫需要事先自行創建 cat data.txt |parallel --sqlmaster 'sql:mysql://user:pass@localhost:3306/pardb/paralleljobs'# 2.執行paralleljobs表中待處理任務,Exitval=-1000為待處理任務 function deal_data(){p=($*)res=$(curl -s -X POST http://localhost:8088/user/add -d '{"user_id": '${p[0]}', "user_name":"'${p[1]}'"}')echo "$res"[[ "$res" == "true" ]] && return 0 || return 1 } export -f deal_dataparallel --sqlworker 'sql:mysql://user:pass@localhost:3306/pardb/paralleljobs' --tag deal_data 復制代碼

處理csv數據

parallel命令還能很方便的處理csv文件數據,比如將data.txt改為data.csv,如下:

$ cat data.csv user_id,user_name 1,u1 2,u2 3,u3 ... # 使用--header : 選項來讀取csv的表頭,然后就可以{user_id},{user_name}來占位命令參數了 $ cat data.csv | parallel --header : -C ',' --tag curl -s -X POST http://localhost:8088/user/add -d \'{\"user_id\": {user_id}, \"user_name\":\"{user_name}\"}\' 復制代碼

--pipe選項

有很多文本處理命令,并不從參數中獲取數據,而是從標準輸入中獲取,比如paste,通過指定--pipe選項,能將數據傳入到待執行命令的輸入流中去。

# 比如我想把data.csv變成data.json,且每3條數據聚合成一個json數組,如下: $ cat data.csv | parallel --header : -C ',' echo \'{\"user_id\": {user_id}, \"user_name\":\"{user_name}\"}\' | parallel -N3 --pipe paste -s -d, | sed -e 's/^/\[/' -e 's/$/]/' [{"user_id": 7, "user_name":"u7"},{"user_id": 8, "user_name":"u8"},{"user_id": 9, "user_name":"u9"}] [{"user_id": 1, "user_name":"u1"},{"user_id": 2, "user_name":"u2"},{"user_id": 3, "user_name":"u3"}] [{"user_id": 4, "user_name":"u4"},{"user_id": 5, "user_name":"u5"},{"user_id": 6, "user_name":"u6"}] [{"user_id": 10, "user_name":"u10"}] 復制代碼

第一個parallel將每條數據變成了{"user_id": 1, "user_name":"u1"}形式。
第二個parallel將每3個json傳給paste的輸入流,然后paste使用逗號將它們連接起來。
每三個sed給首尾加上[],即成為了需要的數據格式。

與tmux結合使用

parallel提供了--tmuxpane,使得可以實現在tmux的多個panel中執行命令,這非常適合用來觀察一些監控命令的結果,比如查看每臺主機的網絡情況。

# 使用ping同時監控簡書、百度、知乎的網絡情況,注意,必須要加--delay選項 $ printf "www.jianshu.com\nwww.jianshu.com\nwww.baidu.com\nwww.zhihu.com"|parallel -j0 --delay 1 --tmuxpane ping {0} See output with: tmux -S /tmp/tmsOHGXM attach # 查看tmux面板 $ tmux -S /tmp/tmsOHGXM attach 復制代碼

如下,為tmux面板的內容,你將能直觀的看到4臺機器的ping實時結果。

總結

如果你經常使用shell來幫助你處理各種問題,我想parallel命令就非常適合你,它真的太強大太方便了。


作者:打碼日記

總結

以上是生活随笔為你收集整理的好用的parallel命令的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。