MongoDB性能測(cè)試

Nodejs編寫的應(yīng)用,后端連MongoDB進(jìn)行持久化存儲(chǔ)表制。Mongodb分別有兩個(gè)版本撩炊,分別跑在虛擬機(jī)和kubernetes里面放仗,進(jìn)行讀寫性能測(cè)試

測(cè)試基線

分別在虛擬機(jī)和K8S中安裝Mongodb數(shù)據(jù)庫,版本為4.0.18包警,測(cè)試目標(biāo)為考察mongodb跑在虛擬機(jī)和K8S中的性能差異

  • 虛擬機(jī)配置:2C4G
  • K8S中的pod配額(limits)為2C4G撵摆,mongodb后端掛接ceph rbd存儲(chǔ)

壓力測(cè)試使用的軟件為wrk,地址為:https://github.com/wg/wrk害晦。這里推薦一下wrk特铝,可以以極少的線程模擬出高并發(fā)的場(chǎng)景,比之前用的ab好用了不是一點(diǎn)壹瘟。

Node性能測(cè)試

首先我們來看下node的基礎(chǔ)性能測(cè)試苟呐,眾所周知nodejs是異步非阻塞的編程模型,在處理高并發(fā)場(chǎng)景有天然優(yōu)勢(shì)俐筋,這邊我們測(cè)試一下,在不接后端數(shù)據(jù)庫的情況下严衬,純nodejs處理(比如請(qǐng)求校驗(yàn)錯(cuò)誤)澄者,性能可以到多少。node應(yīng)用也是跑在k8里的请琳,設(shè)置的配額(limits)為6C粱挡,并發(fā)數(shù)設(shè)置為200:

[root@dce304-cal-vm3 ~]# wrk -c 200 -T 30s -s demo.lua http://22.196.66.200:31010/users
Running 10s test @ http://22.196.66.200:31010/users
  2 threads and 200 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    61.84ms   26.29ms 479.18ms   94.73%
    Req/Sec     1.65k   209.52     2.03k    85.00%
  32905 requests in 10.01s, 8.38MB read
  Non-2xx or 3xx responses: 32905
Requests/sec:   3287.93
Transfer/sec:    857.30KB

可以看到QPS在3200多,而且這個(gè)數(shù)值是線性增長的俄精,即如果起兩個(gè)實(shí)例询筏,則QPS可以到6000多,3個(gè)實(shí)例的話可以到9000多竖慧。記住這個(gè)數(shù)據(jù)嫌套,這是后面進(jìn)行比較的基礎(chǔ)(單個(gè)node的最高性能,也就是加上數(shù)據(jù)庫以后理論上也不會(huì)超過這個(gè)QPS)

虛擬機(jī)Mongo實(shí)例測(cè)試

node后端接入跑在虛擬機(jī)上的mongodb實(shí)例(mongo本身均為單實(shí)例圾旨,未做集群)踱讨,我們來看一下:

寫入測(cè)試

單node副本

[root@dce304-cal-vm3 ~]# wrk -c 200 -T 30s -s demo.lua http://22.196.66.200:31010/users
Running 10s test @ http://22.196.66.200:31010/users
  2 threads and 200 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   810.15ms    1.62s    9.80s    88.46%
    Req/Sec   317.73    113.81   727.00     71.36%
  6323 requests in 10.02s, 3.41MB read
Requests/sec:    631.35
Transfer/sec:    348.95KB

cpu使用率為20%

2個(gè)node副本

[root@dce304-cal-vm3 ~]# wrk -c 200 -T 30s -s demo.lua -d 30s http://22.196.66.200:31010/users
Running 30s test @ http://22.196.66.200:31010/users
  2 threads and 200 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   176.34ms  266.36ms   3.79s    97.12%
    Req/Sec   710.32    168.50     1.01k    63.83%
  42445 requests in 30.03s, 22.91MB read
Requests/sec:   1413.36
Transfer/sec:    781.11KB

cpu使用率為40%

5個(gè)node副本

[root@dce304-cal-vm3 ~]# wrk -c 200 -T 30s -s demo.lua -d 30s http://22.196.66.200:31010/users
Running 30s test @ http://22.196.66.200:31010/users
  2 threads and 200 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    60.30ms   35.27ms   1.06s    96.79%
    Req/Sec     1.71k   236.41     2.18k    76.83%
  102166 requests in 30.02s, 55.12MB read
Requests/sec:   3403.58
Transfer/sec:      1.84MB

cpu使用率為60%

寫入測(cè)試總結(jié)

總體來說隨著副本數(shù)增加,整體性能呈線性增加砍的,5副本時(shí)mongo數(shù)據(jù)庫的cpu也只有60%痹筛,應(yīng)該說還有余量。應(yīng)該是mongodb默認(rèn)的連接池的限制起了作用(默認(rèn)連接數(shù)為5個(gè))

讀取測(cè)試

數(shù)據(jù)庫中放置測(cè)試數(shù)據(jù)780萬條廓鞠,根據(jù)ObjectId關(guān)鍵字進(jìn)行查詢:

單node副本

[root@dce304-cal-vm3 ~]# wrk -c 200 -T 30s http://22.196.66.200:31010/users/5ecb83b3c5299b002bf8bd09
Running 10s test @ http://22.196.66.200:31010/users/5ecb83b3c5299b002bf8bd09
  2 threads and 200 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   726.33ms    1.46s    8.79s    88.23%
    Req/Sec   524.42    158.59     1.00k    72.00%
  10448 requests in 10.01s, 5.59MB read
Requests/sec:   1043.39
Transfer/sec:    572.14KB

cpu利用率16%

5個(gè)node副本

[root@dce304-cal-vm3 ~]# wrk -c 200 -T 30s -d 30s http://22.196.66.200:31010/users/5ecb83b3c5299b002bf8bd09
Running 30s test @ http://22.196.66.200:31010/users/5ecb83b3c5299b002bf8bd09
  2 threads and 200 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    33.17ms   18.24ms 584.77ms   87.45%
    Req/Sec     3.10k   303.76     3.64k    85.17%
  184886 requests in 30.01s, 98.91MB read
Requests/sec:   6159.80
Transfer/sec:      3.30MB

cpu利用率63%

讀取測(cè)試總結(jié)

讀取方面帚稠,因?yàn)橛芯彺娴年P(guān)系(命中率較高),整體的QPS比寫入還略高床佳,基本也是隨副本數(shù)呈線性增長的態(tài)勢(shì)滋早。

kubernetes mongo 實(shí)例測(cè)試

接下來我們測(cè)試一下,mongodb跑在k8s中夕土,后端掛ceph塊存儲(chǔ)的性能(k8的work與ceph集群連接為千兆網(wǎng)卡)

寫入測(cè)試

單node副本

[root@dce304-cal-vm3 ~]# wrk -c 500 -s demo.lua -T 30s http://22.196.66.200:31010/users
Running 10s test @ http://22.196.66.200:31010/users
  2 threads and 500 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   470.51ms    1.13s    9.77s    93.67%
    Req/Sec   398.62    150.61     0.91k    71.81%
  7654 requests in 10.02s, 4.13MB read
Requests/sec:    763.54
Transfer/sec:    422.03KB

cpu使用率 13.7%

2個(gè)node副本

[root@dce304-cal-vm3 ~]# wrk -c 200 -s demo.lua -T 30s http://22.196.66.200:31010/users
Running 10s test @ http://22.196.66.200:31010/users
  2 threads and 200 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   281.70ms  628.13ms   5.50s    93.31%
    Req/Sec   738.18    142.56     1.14k    79.50%
  14710 requests in 10.01s, 7.94MB read
Requests/sec:   1468.87
Transfer/sec:    811.73KB

cpu使用率25%

5個(gè)node 副本

[root@dce304-cal-vm3 ~]# wrk -c 200 -s demo.lua -T 30s http://22.196.66.200:31010/users
Running 10s test @ http://22.196.66.200:31010/users
  2 threads and 200 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    61.27ms   29.67ms 453.58ms   83.79%
    Req/Sec     1.66k   233.53     2.09k    93.00%
  33091 requests in 10.02s, 17.85MB read
Requests/sec:   3303.79
Transfer/sec:      1.78MB

cpu使用率57%

寫入測(cè)試總結(jié)

可以看到使用網(wǎng)絡(luò)存儲(chǔ)和本地磁盤馆衔,在寫入性能上基本沒有區(qū)別瘟判,在單副本情況下,使用rbd的性能甚至還好于本地磁盤角溃。

讀取測(cè)試

單node 副本

[root@dce304-cal-vm3 ~]# wrk -c 200 -T 30s http://22.196.66.200:31010/users/5ecba669f41c9b002b91cfbc
Running 10s test @ http://22.196.66.200:31010/users/5ecba669f41c9b002b91cfbc
  2 threads and 200 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   564.36ms    1.19s    7.58s    89.28%
    Req/Sec   610.83    224.26     1.01k    58.38%
  12119 requests in 10.02s, 6.49MB read
Requests/sec:   1210.00
Transfer/sec:    663.37KB

cpu使用率20%

5個(gè)node副本

[root@dce304-cal-vm3 ~]# wrk -c 200 -T 30s http://22.196.66.200:31010/users/5ecba669f41c9b002b91cfbc
Running 10s test @ http://22.196.66.200:31010/users/5ecba669f41c9b002b91cfbc
  2 threads and 200 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    36.44ms   26.26ms 542.40ms   96.53%
    Req/Sec     2.91k   498.88     3.58k    87.00%
  58009 requests in 10.01s, 31.03MB read
Requests/sec:   5792.89
Transfer/sec:      3.10MB

cpu使用率91%

測(cè)試總結(jié)

可以看到拷获,不管是跑在虛擬機(jī)中,還是k8s里减细,測(cè)試的結(jié)果是基本接近的匆瓜。而按照我們的一般認(rèn)知,本地磁盤的讀寫性能肯定還是要高于網(wǎng)絡(luò)存儲(chǔ)的未蝌,這里面的關(guān)鍵驮吱,還是要說到mongodb的讀寫機(jī)制。mongo作為一款典型的nosql數(shù)據(jù)庫萧吠,其絕大部分的操作都是在內(nèi)存中完成的左冬。MongoDB把文檔寫進(jìn)內(nèi)存之后就返回了,所以說QPS基本不受后端存儲(chǔ)性能的影響纸型。

這邊簡單說一下mongodb數(shù)據(jù)存儲(chǔ)的原理:

內(nèi)存映射機(jī)制

Mongo使用了內(nèi)存映射技術(shù)(mmap) - 寫入數(shù)據(jù)時(shí)候只要在內(nèi)存里完成就可以返回給應(yīng)用程序拇砰,而保存到硬盤的操作則在后臺(tái)異步完成。這也就是說狰腌,MongoDB并不對(duì)RAM和磁盤這兩者進(jìn)行區(qū)別對(duì)待除破,只是將文件看作一個(gè)巨大的數(shù)組,然后按照字節(jié)為單位訪問其中的數(shù)據(jù)琼腔,剩下的都交由操作系統(tǒng)(OS)去處理瑰枫。先了解一下Memeory-Mapped Files:
1、內(nèi)存映射文件是OS通過mmap在內(nèi)存中創(chuàng)建一個(gè)數(shù)據(jù)文件丹莲,這樣就把文件映射到一個(gè)虛擬內(nèi)存的區(qū)域光坝。
2、虛擬內(nèi)存對(duì)于進(jìn)程來說甥材,是一個(gè)物理內(nèi)存的抽象教馆,尋址空間大小為2^64
3、操作系統(tǒng)通過mmap來把進(jìn)程所需的所有數(shù)據(jù)映射到這個(gè)地址空間(紅線)擂达,然后再把當(dāng)前需要處理的數(shù)據(jù)映射到物理內(nèi)存(灰線)
4土铺、當(dāng)進(jìn)程訪問某個(gè)數(shù)據(jù)時(shí),如果數(shù)據(jù)不在虛擬內(nèi)存里板鬓,觸發(fā)page fault悲敷,然后OS從硬盤里把數(shù)據(jù)加載進(jìn)虛擬內(nèi)存和物理內(nèi)存
5、如果物理內(nèi)存滿了俭令,觸發(fā)swap-out操作后德,這時(shí)有些數(shù)據(jù)就需要寫回磁盤,如果是純粹的內(nèi)存數(shù)據(jù)抄腔,寫回swap分區(qū)瓢湃,如果不是就寫回磁盤理张。


mmap.png

Storage View

Mongodb有三個(gè)storage view:Share view,private view绵患,journal日志雾叭,前兩個(gè)位于內(nèi)存中,后一個(gè)位于磁盤上落蝙。

  • Share view:位于內(nèi)存上织狐,會(huì)存儲(chǔ)已經(jīng)改變的要刷新到磁盤上的數(shù)據(jù)(臟數(shù)據(jù))。Share view是唯一一個(gè)直接連映射到數(shù)據(jù)庫文件上的view筏勒。當(dāng)你啟用mongoDB的日志功能時(shí)移迫,mongod會(huì)請(qǐng)求操作系統(tǒng)把磁盤上的數(shù)據(jù)文件指向share view內(nèi)存視圖上。操作系統(tǒng)不會(huì)數(shù)據(jù)文件加載到share view中管行。Mongdb在需要時(shí)自己把數(shù)據(jù)文件加載到share view上厨埋。
  • Private view:位于內(nèi)存上,存儲(chǔ)用于讀請(qǐng)求的數(shù)據(jù)捐顷,更改請(qǐng)求最先在這執(zhí)行揽咕。MongDB把Private view指向share view。
  • Journal view:存儲(chǔ)已經(jīng)在private cache上發(fā)生更改的數(shù)據(jù)套菜,但是會(huì)在更改數(shù)據(jù)刷新到 share view(cache) 之前存儲(chǔ)。Journal 確保了數(shù)據(jù)的持久化设易。如果更改的數(shù)據(jù)沒有刷新到磁盤上的數(shù)據(jù)文件里逗柴,mongodb crash了,當(dāng)mongodb 起來以后顿肺,mongodb會(huì)把journallog中沒應(yīng)用到數(shù)據(jù)文件中的數(shù)據(jù)回放到 share view(cache) 中戏溺,最終會(huì)應(yīng)用到數(shù)據(jù)文件中。

當(dāng)一個(gè)寫請(qǐng)求發(fā)生時(shí):
1屠尊、更改 private view (cache)中的數(shù)據(jù)
2旷祸、默認(rèn)每100毫秒刷新到j(luò)ournal log。journal log有一個(gè)記錄當(dāng)前日志點(diǎn)的pointer
3讼昆、應(yīng)用journal log中的寫操作到share view ,這時(shí)share view 就和數(shù)據(jù)文件不一致
4托享、默認(rèn)每隔60秒,mongodb會(huì)請(qǐng)求操作系統(tǒng)刷新shared view中更改的數(shù)據(jù)到數(shù)據(jù)文件
5浸赫、mongdb會(huì)把journal log中記錄更改數(shù)據(jù)日志點(diǎn)的pointer闰围,以前的數(shù)據(jù)刪除掉。
6既峡、為了數(shù)據(jù)的一致性羡榴,Mongodb通常會(huì)請(qǐng)求操作系統(tǒng)重新把share view 指向private view。


image.png

所以說运敢,在客戶端連接數(shù)一定的情況下(使用mongoose情況下連接池默認(rèn)為5)校仑,單個(gè)node實(shí)例占用的mongodb資源是固定的忠售,性能也是接近的(都是操作內(nèi)存),實(shí)測(cè)將k8s中的mongodb實(shí)例的內(nèi)存配額調(diào)低到2GB迄沫,測(cè)出的性能沒有太大差距稻扬,所以說mongo的性能和內(nèi)存的關(guān)系不大(當(dāng)然大內(nèi)存會(huì)降低cpu的資源消耗)。

補(bǔ)充測(cè)試

既然前面提高了使用node連接mongo邢滑,默認(rèn)連接池大小為5(數(shù)據(jù)庫連接相關(guān)設(shè)置腐螟,請(qǐng)參考http://www.mongoosejs.net/docs/connections.html
),那么我們來測(cè)試一下困后,如果調(diào)整參數(shù)乐纸,是否會(huì)對(duì)于性能產(chǎn)生影響。仍然還是單node副本摇予,數(shù)據(jù)庫連接配置如下:

  config.mongoose = {
    client: {
      url: 'mongodb://22.196.66.200:31669/test',
      options: {
        user: 'test',
        pass: 'test',
        poolSize: 50,
      },
    },
  };

調(diào)整為50汽绢,測(cè)試結(jié)果如下:

[root@dce304-cal-vm3 ~]# wrk -c 200 -s demo.lua http://22.196.66.200:31010/users
Running 10s test @ http://22.196.66.200:31010/users
  2 threads and 200 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   188.41ms  111.62ms   1.87s    90.22%
    Req/Sec   316.79    126.13   626.00     70.90%
  6236 requests in 10.02s, 3.37MB read
  Socket errors: connect 0, read 0, write 0, timeout 85
Requests/sec:    622.50
Transfer/sec:    344.11KB

cpu使用率為13%
結(jié)果:增強(qiáng)pooSize大小對(duì)于QPS并沒有實(shí)質(zhì)性影響,最有效的增加性能的方式還是添加實(shí)例數(shù)侧戴。從測(cè)試結(jié)果來看宁昭,影響QPS的不是mongodb的連接數(shù),而是nodejs的并發(fā)數(shù)限制酗宋,因?yàn)閚ode本身是單進(jìn)程模型积仗,單進(jìn)程能處理的并發(fā)數(shù)有限,不能充分利用cpu多核的優(yōu)勢(shì)蜕猫。

為了進(jìn)一步驗(yàn)證寂曹,我們把eggjs的工作線程workers的數(shù)量設(shè)置為4,重啟pod進(jìn)行測(cè)試:
[root@dce304-cal-vm3 ~]# wrk -c 200 -s demo.lua http://22.196.66.200:31010/users
Running 10s test @ http://22.196.66.200:31010/users
2 threads and 200 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 82.35ms 29.02ms 347.47ms 76.04%
Req/Sec 1.21k 285.20 1.76k 81.50%
24194 requests in 10.02s, 13.06MB read
Requests/sec: 2415.47
Transfer/sec: 1.30MB

可以看出來QPS馬上變成原來的4倍回右,所以說影響nodejs性能的主要因素還是**線程數(shù)**

參考資料:
[http://blog.chinaunix.net/uid-25135004-id-3810200.html](http://blog.chinaunix.net/uid-25135004-id-3810200.html)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末隆圆,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子翔烁,更是在濱河造成了極大的恐慌渺氧,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,039評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蹬屹,死亡現(xiàn)場(chǎng)離奇詭異侣背,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)慨默,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門秃踩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人业筏,你說我怎么就攤上這事憔杨。” “怎么了蒜胖?”我有些...
    開封第一講書人閱讀 165,417評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵消别,是天一觀的道長抛蚤。 經(jīng)常有香客問我,道長寻狂,這世上最難降的妖魔是什么岁经? 我笑而不...
    開封第一講書人閱讀 58,868評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮蛇券,結(jié)果婚禮上缀壤,老公的妹妹穿的比我還像新娘。我一直安慰自己纠亚,他們只是感情好塘慕,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蒂胞,像睡著了一般图呢。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上骗随,一...
    開封第一講書人閱讀 51,692評(píng)論 1 305
  • 那天蛤织,我揣著相機(jī)與錄音,去河邊找鬼鸿染。 笑死指蚜,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的涨椒。 我是一名探鬼主播摊鸡,決...
    沈念sama閱讀 40,416評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼丢烘!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起些椒,我...
    開封第一講書人閱讀 39,326評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤播瞳,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后免糕,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體赢乓,經(jīng)...
    沈念sama閱讀 45,782評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評(píng)論 3 337
  • 正文 我和宋清朗相戀三年石窑,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了牌芋。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,102評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡松逊,死狀恐怖躺屁,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情经宏,我是刑警寧澤犀暑,帶...
    沈念sama閱讀 35,790評(píng)論 5 346
  • 正文 年R本政府宣布驯击,位于F島的核電站,受9級(jí)特大地震影響耐亏,放射性物質(zhì)發(fā)生泄漏徊都。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評(píng)論 3 331
  • 文/蒙蒙 一广辰、第九天 我趴在偏房一處隱蔽的房頂上張望暇矫。 院中可真熱鬧,春花似錦择吊、人聲如沸李根。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽朱巨。三九已至,卻和暖如春枉长,著一層夾襖步出監(jiān)牢的瞬間冀续,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評(píng)論 1 272
  • 我被黑心中介騙來泰國打工必峰, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留洪唐,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,332評(píng)論 3 373
  • 正文 我出身青樓吼蚁,卻偏偏與公主長得像凭需,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子肝匆,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評(píng)論 2 355