15分鐘并行神器gnu parallel入門指南
GNU Parallel是一個(gè)shell工具,為了在一臺(tái)或多臺(tái)計(jì)算機(jī)上并行的執(zhí)行計(jì)算任務(wù)。本文簡(jiǎn)要介紹GNU Parallel的使用。
這個(gè)cpu是多核的。
一般兩核是這樣工作的的:
四核是這樣工作的:
16核是這樣工作的:
好了不黑了。再黑intel要打我了。
在某個(gè)周末的早上百無(wú)聊賴之際,花了半天時(shí)間過(guò)了一遍gnu parallel的man page和tutorial。哈哈,我得說(shuō)這半天時(shí)間花的應(yīng)該挺值,因?yàn)楦杏X(jué)以后它能為我節(jié)省的時(shí)間不止半天吧。
本文并不會(huì)嘗試去翻譯gnu parallel的man page或者tutorial。因?yàn)楝F(xiàn)成的翻譯已經(jīng)有了,可以看這里,或者這里。
但是我前幾次看到 parallel詭異的幾個(gè):::以及奇奇怪怪的 {}{#}{.}{\}占位符之后就打起了退堂鼓,如此丑陋的語(yǔ)法令人無(wú)愛(ài)啊。還好直接看了一下幾個(gè)example壓壓驚,動(dòng)手試一把,才發(fā)現(xiàn)實(shí)乃神器也。
本文主要的目的是安利(lure)你使用這個(gè)工具,并且告訴你為啥(why)使用和如何(how)使用。
why
使用gnu parallel的目的只要一個(gè),就是為了快!
安裝快
(wget -O - pi.dk/3 || curl pi.dk/3/) | bash
作者說(shuō)10秒裝好。在國(guó)內(nèi)實(shí)際情況可能不夠。但是也不用太久。其實(shí)就是一個(gè)1萬(wàn)多行perl單文件腳本(是的,你沒(méi)看錯(cuò),所有模塊都在這個(gè)文件里,這是一個(gè)特色~)。我之后都是寫fabric腳本直接拷貝到各個(gè)節(jié)點(diǎn)機(jī)。再chmod一下執(zhí)行權(quán)限。
然后是執(zhí)行快,它將你的程序并行利用系統(tǒng)的多核執(zhí)行:
上圖:
grep 一個(gè) 1G 大小的log。
使用parallel ,和不使用parallel直接grep。結(jié)果顯而易見(jiàn),相差 20 倍。這比用啥 ack,ag優(yōu)化效果明顯多了。
備注:這是在一個(gè)48 核服務(wù)器上執(zhí)行的結(jié)果。
how
最簡(jiǎn)單的方法就是類比xargs。在xargs里面有一個(gè)參數(shù) -P,可以利用多核。
舉個(gè)例子:
$ time echo {1..5} |xargs -n 1 sleep real 0m15.005s user 0m0.000s sys 0m0.000s
這一條xargs把每個(gè)echo的數(shù)作為參數(shù)傳給sleep ,所以一共sleep了 1+2+3+4+5=15秒。
如果使用 -P 參數(shù)分給5個(gè)核,每個(gè)核各sleep 1,2,3,4,5秒,所以執(zhí)行完之后總共sleep的5秒。
$ time echo {1..5} |xargs -n 1 -P 5 sleep real 0m5.003s user 0m0.000s sys 0m0.000s
鋪墊結(jié)束。一般情況下,parallel的第一種模式,就是替換掉 xargs -P.
比如壓縮一下所有的html文件。
find . -name '*.html' | parallel gzip --best
傳參數(shù)模式
第一種模式是利用 parallel傳參數(shù)。管道前面進(jìn)來(lái)的作為參數(shù)傳給后面的命令,并行執(zhí)行
比如
huang$ seq 5 | parallel echo pre_placehoder_{} pre_placehoder_1 pre_placehoder_2 pre_placehoder_3 pre_placehoder_4 pre_placehoder_5
其中{}是占位符,用來(lái)占位傳入?yún)?shù)的位置。
在云計(jì)算操作中,經(jīng)常有批量操作,比如建立10個(gè)云硬盤
seq 10 | parallel cinder create 10 --display-name test_{}
建立50個(gè)云主機(jī)
批量刪除云主機(jī)
nova list | grep some_pattern| awk '{print $2}' | parallel nova delete
改寫 for loop
可以看到,我其實(shí)是把很多需要寫循環(huán)的地方用parallel替換了,順帶享受了并行帶來(lái)的快捷。
這個(gè)道理是這樣的,在進(jìn)行for循環(huán)的時(shí)候,是最有可能并行化的,因?yàn)楸环旁谘h(huán)中的各個(gè)對(duì)象是上下文無(wú)關(guān)的。
普世抽象,shell的循環(huán):
(for x in `cat list` ; do do_something $x done) | process_output
可以直接寫成
cat list | parallel do_something | process_output
如果loop 里面內(nèi)容太多了
(for x in `cat list` ; do do_something $x [... 100 lines that do something with $x ...] done) | process_output
那么最好寫成一個(gè)腳本
doit() { x=$1 do_something $x [... 100 lines that do something with $x ...] } export -f doit cat list | parallel doit
而且還能避免掉很多麻煩的轉(zhuǎn)義。
--pipe模式
另一種模式就是 parallel --pipe
這時(shí)管道前面的不是作為參數(shù),而是標(biāo)準(zhǔn)輸入傳給后面的命令
例如:
cat my_large_log |parallel --pipe grep pattern
如果不加 --pipe ,相當(dāng)于 mylog中的每一行都變成 grep pattern line的命令展開(kāi)了。而加入了--pipe,則和 cat mylog | grep pattern 沒(méi)有區(qū)別,只是分配到各個(gè)核上去執(zhí)行了。
好了,基本概念就講完了!其他的都只是各個(gè)參數(shù)具體使用,比如到底用幾個(gè)核啊,place_holder的替換啊,各種花樣傳參數(shù)啊,并行執(zhí)行但是保證結(jié)果順序輸出(-k),以及神奇的跨節(jié)點(diǎn)并行計(jì)算啊,看看man page就知道了。
bonus
手邊有了一個(gè)轉(zhuǎn)換成并行的小工具,除了讓你日常執(zhí)行快一點(diǎn)之外,還有一個(gè)好處,就是測(cè)并發(fā)。
很多接口在并發(fā)操作下會(huì)出現(xiàn)一些bug,比如有一些判斷數(shù)據(jù)庫(kù)里面沒(méi)有加鎖,是在代碼層面判斷的,結(jié)果并發(fā)請(qǐng)求下去,每個(gè)請(qǐng)求在到達(dá)服務(wù)器的時(shí)候是判斷通過(guò),一起寫了之后就超出限制了。之前寫for循環(huán)因?yàn)槭谴袌?zhí)行的,并不會(huì)觸發(fā)這些問(wèn)題。但是你要真正測(cè)并發(fā)的話,又要寫腳本,或者利用python的mulitiprocessing封裝一下。但我手邊有了parallel,又在bashrc里面就加了以下兩個(gè)alias
alias p='parallel' alias pp='parallel --pipe -k'
這樣制造并發(fā)太方便了,只需要管道后面加個(gè)p , 我就時(shí)時(shí)刻刻可以制造并發(fā)來(lái)觀察響應(yīng)。
舉個(gè)例子
seq 50 | p -n0 -q curl 'example.com'
以你核的個(gè)數(shù)并發(fā)請(qǐng)求。-n0的意思是seq輸出不作為參數(shù)傳給后面的命令。
八卦時(shí)間:gnu界的祥林嫂
作為一個(gè)自由軟件八卦愛(ài)好者,每次我發(fā)現(xiàn)一個(gè)新奇的軟件總會(huì)去 google一下 關(guān)鍵詞 site:https://news.ycombinator.com
和關(guān)鍵詞 site:http://www.reddit.com/
??纯达L(fēng)評(píng)如何,并且往往還能在討論中有意外收獲。
然后我再hacker news上看到了一段吐槽,主要就是說(shuō)每次觸發(fā)執(zhí)行parallel都會(huì)彈出一段文字和你說(shuō),要是你把這個(gè)工具用在學(xué)術(shù)上的話(很多生命科學(xué)相關(guān)的都在用這個(gè)工具的),要引用他的論文,不然的話你就付他10000歐元吧。我因此學(xué)到一個(gè)詞,叫Nagware,特指通過(guò)啰啰嗦嗦像唐僧那樣煩你要你付錢的軟件。雖然我認(rèn)為真用到了的確也應(yīng)該引用一下文章,但是,如同這位同學(xué)說(shuō)的:
I agree it's a great tool, except for the nagware messages and their content. Imagine if the author of cd or ls had the same attitude...
另外,該作者真是灰常喜歡別人引用他的軟件,以致于在NEWS里面我還看到了:
原理時(shí)間
直接摘抄一下作者在 stackoverflow 的回答
GNU Parallel is a general parallelizer and makes is easy to run jobs in parallel on the same machine or on multiple machines you have ssh access to.
If you have 32 different jobs you want to run on 4 CPUs, a straight forward way to parallelize is to run 8 jobs on each CPU:
GNU Parallel instead spawns a new process when one finishes - keeping the CPUs active and thus saving time:
結(jié)論
本文主要安利了一個(gè) 真 - 并行 工具,解釋了其主要的兩種模式,附贈(zèng)了一個(gè)技巧,八卦了gnu界不為人知的另一面。希望對(duì)你有用。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Linux?CentOS7?vim重復(fù)行問(wèn)題
這篇文章主要介紹了Linux?CentOS7?vim重復(fù)行問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11CentOS 6.6服務(wù)器編譯安裝lnmp(Nginx1.6.2+MySQL5.6.21+PHP5.6.3)
這篇文章主要介紹了CentOS 6.6服務(wù)器編譯安裝lnmp(Nginx1.6.2+MySQL5.6.21+PHP5.6.3),需要的朋友可以參考下2016-10-10Ubuntu16.04環(huán)境下搭建FTP服務(wù)器的教程
這篇文章主要介紹了Ubuntu16.04搭建FTP服務(wù)器的教程,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-12-12ssh遠(yuǎn)程無(wú)法訪問(wèn)linux的問(wèn)題及解決
這篇文章主要介紹了ssh遠(yuǎn)程無(wú)法訪問(wèn)linux的問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04Ubuntu18 給terminal改個(gè)漂亮的命令行提示符的方法
這篇文章主要介紹了Ubuntu18 給terminal改個(gè)漂亮的命令行提示符的方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-06-06