溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

(9)異步Mongo驅(qū)動(dòng)的性能測(cè)試——響應(yīng)式Spring的道

發(fā)布時(shí)間:2020-02-29 16:58:14 來(lái)源:網(wǎng)絡(luò) 閱讀:18057 作者:享學(xué)IT 欄目:MongoDB數(shù)據(jù)庫(kù)

本系列文章索引《響應(yīng)式Spring的道法術(shù)器》
前情提要 Spring WebFlux快速上手 | Spring WebFlux性能測(cè)試 | Spring WebClient性能測(cè)試
本文源碼

1.4.4 同步與異步數(shù)據(jù)庫(kù)驅(qū)動(dòng)的性能對(duì)比

許多數(shù)據(jù)庫(kù)已陸續(xù)推出官方的異步驅(qū)動(dòng),在Spring Data Reactive中,已經(jīng)集成了Mongo、Casandra、Redis、CouchDB的異步驅(qū)動(dòng)。

在Spring WebFlux中使用 Reactive Mongo的示例見(jiàn)Spring WebFlux快速上手。

這一節(jié)我們通過(guò)使用YSCB對(duì)MongoDB的同步和異步驅(qū)動(dòng)的性能基準(zhǔn)測(cè)試,來(lái)觀察異步驅(qū)動(dòng)的優(yōu)勢(shì)。

YCSB(Yahoo! Cloud Serving Benchmark)是雅虎開(kāi)源的一款用于測(cè)試各類(lèi)云服務(wù)/NoSQL/鍵值對(duì)存儲(chǔ)的性能基準(zhǔn)測(cè)試工具。YCSB很贊,使用起來(lái)很簡(jiǎn)單,我們就按照wiki介紹來(lái)操作即可。

1)準(zhǔn)備YCSB

如果使用Windows,請(qǐng)參考這里來(lái)預(yù)先安裝必要的軟件和工具。

獲取YCSB有兩種方式,一種是直接下載壓縮包:

curl -O --location https://github.com/brianfrankcooper/YCSB/releases/download/0.12.0/ycsb-0.12.0.tar.gz
tar xfvz ycsb-0.12.0.tar.gz
cd ycsb-0.12.0

另一種是基于源碼構(gòu)建:

git clone git://github.com/brianfrankcooper/YCSB.git
cd YCSB
mvn clean package

此時(shí)就可以使用bin/ycsb命令來(lái)進(jìn)行性能測(cè)試了,運(yùn)行一下:

usage: bin/ycsb command databse [options]

Commands:
    load        Execute the load phase
    run         Execute the transaction phase
    shell       Interactive mode

...

從上邊的命令幫助可以看到,我們可以運(yùn)行三種命令:

  • load,執(zhí)行數(shù)據(jù)加載,也就是向數(shù)據(jù)庫(kù)保存數(shù)據(jù);
  • run,執(zhí)行事務(wù),比如更新、查詢(xún)等;
  • shell,可以交互式地運(yùn)行測(cè)試。

本節(jié)的測(cè)試主要用到load和run來(lái)進(jìn)行數(shù)據(jù)的批量操作,先用load命令加載數(shù)據(jù)集,然后使用run命令測(cè)試數(shù)據(jù)操作。在YCSB中,測(cè)試的工作量由workload文件來(lái)定義。我們看到在workloads下有workload[a-f]幾個(gè)配置文件,比如workloada:

# Yahoo! Cloud System Benchmark
# Workload A: Update heavy workload
#   Application example: Session store recording recent actions
#                        
#   Read/update ratio: 50/50
#   Default data size: 1 KB records (10 fields, 100 bytes each, plus key)
#   Request distribution: zipfian

recordcount=1000
operationcount=1000
workload=com.yahoo.ycsb.workloads.CoreWorkload

readallfields=true

readproportion=0.5
updateproportion=0.5
scanproportion=0
insertproportion=0

requestdistribution=zipfian

可見(jiàn)配置文件定義了記錄條數(shù)、操作次數(shù)、以及不同的操作所占的百分比。比如上邊readproportionupdateproportion都是50%,從注釋也可以看出來(lái),這模擬的是一種更新操作比較頻繁的場(chǎng)景,可以模擬Web應(yīng)用中保存session的場(chǎng)景。

幾個(gè)workload的配置通過(guò)不同的read/update/scan/insert操作比例來(lái)模擬不同的場(chǎng)景。

我們可以通過(guò)如下命令對(duì)mongo運(yùn)行基于workloada的load階段的性能測(cè)試:

bin/ycsb load mongodb -P workloads/workloada

默認(rèn)是連接localhost:27017的mongodb數(shù)據(jù)庫(kù),如果希望指定數(shù)據(jù)庫(kù)連接信息,可以用-p參數(shù)指定:

bin/ycsb load mongodb -P workloads/workloada \
-p "mongodb.url=mongodb://192.168.0.101:27017/ycsb?w=1&maxPoolSize=32&waitQueueMultiple=20" 

同時(shí)還指定了連接池最大數(shù)量和最多等待數(shù)量。

當(dāng)然我們也可以通過(guò)命令參數(shù)覆蓋workloada文件中的數(shù)值,比如:

bin/ycsb load mongodb -P workloads/workloada \
-p "mongodb.url=mongodb://192.168.0.101/ycsb?w=1&maxPoolSize=32&waitQueueMultiple=20"  \
-p recordcount=10000 -p operationcount=10000 -threads 20

此外,還用-threads指定了并發(fā)線程數(shù)為20。

以上這些是本次測(cè)試會(huì)用到的內(nèi)容,其他更多關(guān)于YCSB的使用請(qǐng)參考wiki吧。

2)準(zhǔn)備測(cè)試

本次測(cè)試的目標(biāo)是對(duì)比Mongodb同步和異步驅(qū)動(dòng)的性能,簡(jiǎn)單起見(jiàn),從吞吐量平均操作時(shí)長(zhǎng)兩個(gè)數(shù)據(jù)來(lái)衡量。縱向上,

  • 比較不同數(shù)量的并發(fā)線程對(duì)兩個(gè)數(shù)據(jù)的影響;
  • 觀察測(cè)試時(shí)的連接數(shù)變化。

連接數(shù)的變化可以通過(guò)mongostat命令來(lái)觀察,如下圖所示:

(9)異步Mongo驅(qū)動(dòng)的性能測(cè)試——響應(yīng)式Spring的道

上邊運(yùn)行的mongo-benchmark.sh是基于bin/ycsb命令編寫(xiě)的方便測(cè)試的腳本,并輸出一些匯總數(shù)據(jù)(包括吞吐量和平局操作時(shí)長(zhǎng))方便查看,同時(shí)也會(huì)將每次bin/ycsb命令輸出的詳細(xì)內(nèi)容保存到output目錄下的文件中。
腳本可以在代碼庫(kù)中找到,如果mongo運(yùn)行于localhost:27017,可直接用如下命令執(zhí)行(在與bin同目錄下):

curl https://raw.githubusercontent.com/get-set/get-reactive/master/ycsb-mongo-shell/mongo-benchmark.sh | bash

圖中上方是對(duì)同步驅(qū)動(dòng)和異步驅(qū)動(dòng)各自跑了一次基于workloada的load和run的測(cè)試,下方是mongostat的輸出(每秒輸出一行),從insert、queryupdate的數(shù)字可以找出四個(gè)橘×××的框標(biāo)出的4個(gè)階段。通過(guò)這些數(shù)據(jù)我們可以分析出:

  • load主要是加載數(shù)據(jù)集,因此會(huì)看到insert的數(shù)字增多,加起來(lái)是測(cè)試預(yù)設(shè)的30000條數(shù)據(jù);類(lèi)似的run主要是進(jìn)行基于workload的操作測(cè)試,workloada是50/50的read/update,在mongostat的輸出中也有體現(xiàn)。
  • load階段同步和異步驅(qū)動(dòng)的吞吐量分別為19801和25554,run階段同步和異步的吞吐量分別為25706和27675,同步驅(qū)動(dòng)略遜一籌;再觀察insert、read和update操作的平均時(shí)長(zhǎng),可以得出同樣的結(jié)論。
  • 這次測(cè)試設(shè)置了20個(gè)線程對(duì)mongo數(shù)據(jù)庫(kù)進(jìn)行操作,在mongostat輸出的conn列可以看到數(shù)據(jù)庫(kù)連接個(gè)數(shù)的變化,對(duì)于同步的驅(qū)動(dòng)來(lái)說(shuō),連接個(gè)數(shù)會(huì)從4個(gè)增加到25個(gè),而對(duì)于異步的驅(qū)動(dòng)來(lái)說(shuō),連接個(gè)數(shù)會(huì)從4個(gè)增加到7個(gè)。

通過(guò)這種方式,針對(duì)不同的線程數(shù),觀察兩種驅(qū)動(dòng)的性能數(shù)據(jù)并通過(guò)mongostat的數(shù)據(jù)記錄連接數(shù)。

一、不限制連接數(shù)

為了觀察連接數(shù)的變化,先不限制maxPoolSize(注釋腳本中MAX_POOL_SIZE=8那一行)。最終結(jié)果如下:

(9)異步Mongo驅(qū)動(dòng)的性能測(cè)試——響應(yīng)式Spring的道

圖中,每種顏色的左列和右列分別是同步和異步的數(shù)據(jù)。直觀起見(jiàn),我們通過(guò)圖表來(lái)對(duì)比一下:

首先對(duì)比一下load階段和run階段的吞吐量(柱越高越好)

(9)異步Mongo驅(qū)動(dòng)的性能測(cè)試——響應(yīng)式Spring的道

(9)異步Mongo驅(qū)動(dòng)的性能測(cè)試——響應(yīng)式Spring的道

可以發(fā)現(xiàn),當(dāng)線程數(shù)達(dá)到8個(gè)之后,吞吐量的增長(zhǎng)趨勢(shì)基本消失了,尤其是同步驅(qū)動(dòng)的吞吐量還會(huì)隨線程數(shù)的繼續(xù)增加而略有下降。不知是否跟測(cè)試環(huán)境為四核八線程的CPU有關(guān)系。

然后對(duì)比一下INSERT、READ和UPDATE操作的平均時(shí)長(zhǎng)(柱越低越好)

(9)異步Mongo驅(qū)動(dòng)的性能測(cè)試——響應(yīng)式Spring的道

(9)異步Mongo驅(qū)動(dòng)的性能測(cè)試——響應(yīng)式Spring的道

(9)異步Mongo驅(qū)動(dòng)的性能測(cè)試——響應(yīng)式Spring的道

相對(duì)來(lái)說(shuō),異步驅(qū)動(dòng)能帶來(lái)更快的讀寫(xiě)操作,尤其是應(yīng)對(duì)越來(lái)越多的線程的時(shí)候。

最后對(duì)比一下連接數(shù)

連接數(shù)的對(duì)比更加明顯:對(duì)于同步的情況,連接數(shù)=線程數(shù)+5;而對(duì)于異步的情況,連接數(shù)幾乎一直保持在7個(gè)。沒(méi)有對(duì)比就沒(méi)有傷害呀。

二、限制連接數(shù)

下面,將連接數(shù)限制為32個(gè),測(cè)試一下線程數(shù)從30-80的情況下,同步驅(qū)動(dòng)的性能數(shù)據(jù):

(9)異步Mongo驅(qū)動(dòng)的性能測(cè)試——響應(yīng)式Spring的道

通過(guò)圖表對(duì)比:

(9)異步Mongo驅(qū)動(dòng)的性能測(cè)試——響應(yīng)式Spring的道

(9)異步Mongo驅(qū)動(dòng)的性能測(cè)試——響應(yīng)式Spring的道

(9)異步Mongo驅(qū)動(dòng)的性能測(cè)試——響應(yīng)式Spring的道

(9)異步Mongo驅(qū)動(dòng)的性能測(cè)試——響應(yīng)式Spring的道

(9)異步Mongo驅(qū)動(dòng)的性能測(cè)試——響應(yīng)式Spring的道

可見(jiàn),限制連接數(shù)之后,略有改善,但是相比異步驅(qū)動(dòng)來(lái)說(shuō),仍然有一定差距。

3)結(jié)論

首先,需要說(shuō)明的是,以上并非是以數(shù)據(jù)庫(kù)調(diào)優(yōu)為目的的測(cè)試,這里我們只測(cè)試了workloada(如果你感興趣可以將腳本中的WORKLOAD變量修改一下,然后測(cè)試其他場(chǎng)景),而且限制連接數(shù)為32并沒(méi)有特別的依據(jù),對(duì)測(cè)試的機(jī)器來(lái)說(shuō),32也并非最優(yōu)的連接數(shù)。

通過(guò)本節(jié)的測(cè)試,針對(duì)MongoDB驅(qū)動(dòng)我們可以得出以下兩個(gè)結(jié)論:

  • 相對(duì)于同步驅(qū)動(dòng)來(lái)說(shuō),異步驅(qū)動(dòng)在性能方面略勝一籌;
  • 在應(yīng)對(duì)大量客戶(hù)端線程的情況下,異步驅(qū)動(dòng)能夠以少量而穩(wěn)定的連接數(shù)應(yīng)對(duì),意味著更少的內(nèi)存消耗(每個(gè)連接消耗stack size的內(nèi)存空間,默認(rèn)情況下stack size為10M)。

1.4.4 總結(jié)

上邊我們分別針對(duì)Http服務(wù)端、Http客戶(hù)端以及數(shù)據(jù)庫(kù)進(jìn)行了同步和異步的測(cè)試對(duì)比,綜上來(lái)看,基于異步非阻塞的響應(yīng)式應(yīng)用或驅(qū)動(dòng)能夠以少量且固定的線程應(yīng)對(duì)高并發(fā)的請(qǐng)求或調(diào)用,對(duì)于存在阻塞的場(chǎng)景,能夠比多線程的并發(fā)方案提供更高的性能。

響應(yīng)式和非阻塞并不是總能讓?xiě)?yīng)用跑的更快,況且將代碼構(gòu)建為非阻塞的執(zhí)行方式本身還會(huì)帶來(lái)少量的成本。但是在類(lèi)似于WEB應(yīng)用這樣的高并發(fā)、少計(jì)算且I/O密集的應(yīng)用中,響應(yīng)式和非阻塞往往能夠發(fā)揮出價(jià)值。尤其是微服務(wù)應(yīng)用中,網(wǎng)絡(luò)I/O比較多的情況下,效果會(huì)更加驚人。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI