吳佳驊
(武漢城市職業(yè)學(xué)院 湖北·武漢 430064)
現(xiàn)在的項(xiàng)目開發(fā)早已不是平地起樓式的了。虛擬機(jī)、運(yùn)行時(shí)、編譯器、中間件、開發(fā)框架、數(shù)據(jù)庫以及其他各種要配置的環(huán)境,在項(xiàng)目開發(fā)之前,以上這些都得先準(zhǔn)備好,否則大概率影響實(shí)際開發(fā)任務(wù)完成進(jìn)度。然而,這種由各種雜七雜八的東西形成的龐雜集合體,本身在部署時(shí)就很讓人費(fèi)神,稍有不慎,可能就會導(dǎo)致環(huán)境錯(cuò)誤,在部署中發(fā)生人為錯(cuò)誤的概率不低。當(dāng)項(xiàng)目中發(fā)生新應(yīng)用的加入時(shí),也時(shí)常需要添加其他環(huán)境組件。這些原項(xiàng)目來說,有時(shí)就像是入侵的細(xì)菌,可能導(dǎo)致項(xiàng)目崩潰。于是,解決這些附加組件帶來的麻煩又成了不小的工作量。這些原本與開發(fā)任務(wù)本身關(guān)系不大的工作,需要在項(xiàng)目的各個(gè)階段上重復(fù)執(zhí)行,消耗大量的精力和耐性,對于要求速度的項(xiàng)目開發(fā),顯然很不劃算。
于是,容器技術(shù)開始被應(yīng)用在項(xiàng)目開發(fā)當(dāng)中。這是一種能夠把環(huán)境變量、應(yīng)用、數(shù)據(jù)庫等等打包在一個(gè)封閉的鏡像當(dāng)中的技術(shù),當(dāng)需要調(diào)用它們的時(shí)候,只需要根據(jù)鏡像去生成具體的執(zhí)行實(shí)例。不同的實(shí)例里可以包含不同的組件來提供服務(wù),而實(shí)例與實(shí)例之間是彼此獨(dú)立的。容器的出現(xiàn)使開發(fā)人員能用更靈活的方式去組織所需要的復(fù)雜環(huán)境。因?yàn)閷?shí)例與實(shí)例之間彼此互不干涉,由不同組件代碼或者執(zhí)行庫沖突和不兼容等問題所引起的各種錯(cuò)誤也就很難出現(xiàn)了。開發(fā)人員可以將全部的精力集中在項(xiàng)目本身的開發(fā)業(yè)務(wù)上,整體的開發(fā)效率提高了。
不過,把組件裝進(jìn)籠子里的容器技術(shù),是否真的是解決問題的銀色子彈?與傳統(tǒng)方式相比,在從雜亂環(huán)境部署的魔障里解救出開發(fā)人員的同時(shí),作為代價(jià)是否又失去了什么,比如性能?為了解開這個(gè)疑問,用開發(fā)項(xiàng)目常用的NoSQL數(shù)據(jù)庫MongoDB做代表,測試比較物理機(jī)部署和容器部署的性能表現(xiàn)。
MongoDB使用C++語言編寫,是一種面向文件存儲的分布式NoSQL數(shù)據(jù)庫。MongoDB會把數(shù)據(jù)當(dāng)作文檔來存放,風(fēng)格和JSON很像,數(shù)據(jù)結(jié)構(gòu)是鍵值對,值又可以再包含別的文檔、列表或者文檔的列表。整體使用風(fēng)格都比較像關(guān)系數(shù)據(jù)庫,操作也比較簡單。
Docker在容器中最流行,它用Go語言編寫,并用appche2.0許可證開源,英文意思是碼頭工人搬運(yùn)的箱子。正如其名,Docker所提供的容器就像是一個(gè)一個(gè)的箱子,箱子里裝著各種各樣的東西,箱子與箱子直接又彼此獨(dú)立,每個(gè)箱子同時(shí)又呈現(xiàn)類似的可以相互堆疊的規(guī)格,很容易組合。Docker由四個(gè)部分組成:客戶端、守護(hù)進(jìn)程、鏡像和容器。Docker的運(yùn)作方式是C/S模式。守護(hù)進(jìn)程充當(dāng)后臺服務(wù)器,負(fù)責(zé)接受請求,并且處理它們??蛻舳藙t提供人機(jī)交互界面,讓用戶可以和守護(hù)進(jìn)程進(jìn)行交互活動??蛻舳撕褪刈o(hù)進(jìn)程可以被部署在同一臺主機(jī)上,開發(fā)用計(jì)算機(jī)大都如此;也可以分開來部署成遠(yuǎn)程模式,通過socket來完成通信。鏡像是Docker由需要的環(huán)境變量、運(yùn)行庫和其他組件一起通過打包生成的模板,容器是鏡像的實(shí)現(xiàn),一份鏡像可以實(shí)現(xiàn)無數(shù)相同的容器。
為了測試結(jié)果更有參考價(jià)值,測試環(huán)境使用兩套完全一樣的硬件和操作系統(tǒng)。硬件:處理器intelcorei5-9400F,主頻2.9GHz;硬盤SSD;內(nèi)存16G DDR4。以上勝任一般開發(fā)用計(jì)算機(jī),SSD可降低I/O對測試結(jié)果的影響。操作系統(tǒng)ubuntu16.04LTS,Docker版本17.03.1,MongoDB版本5.0.2。計(jì)算機(jī)A直接安裝MongoDB,計(jì)算機(jī)B建立MongoDB的Docker鏡像然后生成Docker容器。
為了貼近平時(shí)的開發(fā)情景,本次測試分為兩項(xiàng):針對只讀性能的測試和針對讀寫混合操作性能的測試。只讀的性能測試設(shè)定為請求次數(shù)為25萬次,數(shù)據(jù)量100萬,表數(shù)30張,列數(shù)10列。讀寫混合操作的性能測試設(shè)定為請求次數(shù)25萬次,數(shù)據(jù)量100萬,表數(shù)1張,列數(shù)10列。
每種測試都設(shè)置4種并發(fā)線程:10線程、32線程、64線程、128線程。測試框架選擇使用業(yè)內(nèi)流行的sysbench-MongoDB。測試的數(shù)據(jù)全部在當(dāng)次測試之前隨機(jī)生成,避免數(shù)據(jù)庫緩存對測試結(jié)果造成的影響。測試結(jié)果以獲得的每秒鐘完成事務(wù)數(shù)量為準(zhǔn),即TPS。
四輪只讀性能測試的TPS結(jié)果如圖1所示。
圖1:只讀性能TPS
從圖1中不難看出,直接物理機(jī)安裝MongoDB的計(jì)算機(jī)A與使用Docker部署MongoDB的計(jì)算機(jī)B在只讀性能上還是有些差異的。10線程測試中,計(jì)算機(jī)A和B的實(shí)測TPS數(shù)據(jù)分別是400和399,基本持平。32線程測試中,計(jì)算機(jī)A和B的實(shí)測TPS數(shù)據(jù)分別是410和360,計(jì)算機(jī)B比A性能大約低12%。64線程測試中,計(jì)算機(jī)A和B的實(shí)測TPS數(shù)據(jù)分別是395和385,計(jì)算機(jī)B比A性能大約低3%。128線程測試中,計(jì)算機(jī)A和B的實(shí)測TPS數(shù)據(jù)分別是405和396,計(jì)算機(jī)B比A性能上大約低3%。兩者的最大性能差發(fā)生在32線程測試中。
通過以上數(shù)據(jù)分析,可以認(rèn)為使用Docker部署MongoDB的計(jì)算機(jī)B在只讀性能上要稍遜于直接物理機(jī)安裝MongoDB的計(jì)算機(jī)A,最大性能差距在中線程體現(xiàn)得較為明顯,而在低線程和高線程并不會在性能上拉開較大的差距。
四輪讀寫混合操作性能測試的TPS結(jié)果如圖2所示。
圖2:讀寫混合操作性能TPS
從圖2中可以看出,二者在讀寫混合操作性能上同樣存在差異。10線程測試中,計(jì)算機(jī)A和B的實(shí)測TPS數(shù)據(jù)分別是175和155,計(jì)算機(jī)B比A性能上大約低11%。32線程測試中,計(jì)算機(jī)A和B的實(shí)測TPS數(shù)據(jù)分別是200和167,計(jì)算機(jī)B比A性能上大約低16%。64線程測試中,計(jì)算機(jī)A和B的實(shí)測TPS數(shù)據(jù)分別是195和185,計(jì)算機(jī)B比A性能大約低5%。128線程測試中,計(jì)算機(jī)A和B的實(shí)測TPS數(shù)據(jù)分別是199和188,計(jì)算機(jī)B比A性能大約低1%。兩者的最大性能差依舊發(fā)生在32線程測試中。
通過以上數(shù)據(jù)分析,可以認(rèn)為使用Docker部署MongoDB的計(jì)算機(jī)B在讀寫混合操作性能上要明顯遜于直接物理機(jī)安裝MongoDB的計(jì)算機(jī)A,最大性能差發(fā)生在中線程,甚至高達(dá)15%以上,在低線程的性能差也在10%以上,在中高線程和高線程兩者勉強(qiáng)保持5%以內(nèi)的性能差距。
同時(shí),對比圖1和圖2的結(jié)果,不難看出,兩者的性能差距在讀寫混合操作時(shí)明顯大于只讀時(shí)。
通過在相同硬件條件下對只讀和讀寫混合操作這兩種性能共8輪測試的結(jié)果分析,不難看出將MongoDB部署在Docker中雖然并不能在性能上完全與傳統(tǒng)的物理機(jī)部署持平,但是損失的性能代價(jià)并不算太大,在低線程和高線程情況下這種性能差距是可以勉強(qiáng)接受,而在開發(fā)過程中最常涉及到中線程的情況下性能差距較大甚至超過10%。
所以,對于完全解決開發(fā)流程各個(gè)階段上復(fù)雜煩瑣的環(huán)境部署以保障整個(gè)流程里的環(huán)境一致這一問題,Docker并非銀色子彈。在性能和便利的天平上,還是得依靠開發(fā)團(tuán)隊(duì)去針對實(shí)際的需求做出增減砝碼的取舍。