mongodb三種存儲引擎高併發更新性能專題測試

背景說明python

近期北京理財頻道反饋用來存放股市實時數據的MongoDB數據庫寫響應請求很慢,難以跟上業務寫入速度水平。咱們分析了線上現場的狀況,發現去年升級到SSD磁盤後,數據持久化的磁盤IO開銷已經不是瓶頸.經過日誌分析,線上單次寫入(更新)請求大多在數十毫秒這個級別,數據庫端觀察幾個主要的db在繁忙時一般有95%以上的時間在進行鎖等待。線上數據庫併發很高,接近1000個鏈接,因此懷疑是併發爭用表鎖致使性能不足。web

 

咱們知道MongoDB的mmap存儲引擎一直是庫/表級鎖,所以任何寫操做併發越高鎖爭用形成的性能損耗越大。爲了改善鎖併發性能MongoDB,升級到行級鎖引擎應該可以改善線上更新數據的性能瓶頸。3.0的WT存儲引擎和toku開發的tokumx存儲引擎都號稱實現了行級鎖和多版本併發控制。所以,爲了肯定咱們升級的方向,決定使用線上相似的場景,對三種存儲引擎進行一次性能測試,評估最能改善併發更新寫的方案。數據庫

 

咱們取得了線上最繁忙的stock和stock_status數據,而且仿照線上併發更新最頻繁的根據證券code更新的方式,在測試環境進行測驗。併發

 

硬件環境app

CPU:  24 核 Intel(R) Xeon(R) CPU E5-2630 0 @ 2.30GHzdom

內存:  48Gasync

磁盤:  SSD函數

 

MongoDB版本高併發

1. Mmap存儲引擎 MongoDB-2.6.9性能

2. Toku存儲引擎 MongoDB-2.4.10

3. WiredTiger存儲引擎 MongoDB 3.0.5

 

 

測試用例

從線上將股票信息表數據導入測試環境,建立與線上一致的索引,股票碼code_id爲惟一索引。

單純寫測試:從股票表stock中抽取1000個code_id,用隨機函數獲取其中一個code_id,對這一行數據進行一次update操做;

讀寫混合測試:在必定併發度的寫操做狀況下,以一樣併發度經過code_id讀取一行數據,讀寫混合比例爲1:1。

 

 

測試腳本

1.寫測試腳本

#! /usr/bin/env python
# -*- coding: utf-8 -*-
import multiprocessing
import time
import random
import pymongo
client = pymongo.MongoClient("172.17.1.234", 27017) db = client.stock
def get_id():  code_list = [1000個code_id]  code_loct = random.randint(0, 999)  up_value  = random.randint(10, 99)/10.0  return code_list[code_loct], up_value
def update_func():  
 while True:    code_id, up_value = get_id()    
   db.stock.update_one({"CODE":str(code_id)},{"$set":
{"ASK1":str(up_value),"ASK2":str(up_value),"ASK3":str(up_value),"ASK4":str(up_value),"ASK5":str(up_value),"ASKVOL1":str(up_value),"ASKVOL2":str(up_value),"ASKVOL3":str(up_value),"ASKVOL4":str(up_value),"ASKVOL5":str(up_value),"BID1":str(up_value),"BID2":str(up_value),"BID3":str(up_value),"BID4":str(up_value),"BID5":str(up_value)}})
if __name__ == "__main__":  pool = multiprocessing.Pool(processes=併發度)  
 for i in xrange(10000000):    pool.apply_async(update_func,)  pool.close()  pool.join()  
 print "\n"  print "All done."
2.讀測試腳本
#! /usr/bin/env python
# -*- coding: utf-8 -*-
import multiprocessing
import time
import random
import pymongo
client = pymongo.MongoClient("172.17.1.234", 27017) db = client.stock
def get_id():  code_list = [1000個code_id]  code_loct = random.randint(0, 499)  
 return code_list[code_loct]
def update_func(): 
 while True:    code_id = get_id()    
 db.stock.find_one({"CODE":str(code_id)},{"CODE":1,"ASK1":1,"ASK2":1})
if __name__ == "__main__":  pool = multiprocessing.Pool(processes=併發度)  
 for i in xrange(1000000):     pool.apply_async(update_func,)  pool.close()  pool.join()  
 print "\n"  print "All done."

測試結果

1.單純寫的測試結果

結論:WiredTiger在純update測試場景中性能明顯高於toku和mmap

 

a.toku和mmap併發度超過32後TPS穩定在1.4萬到1.5萬左右,此時總體DB的鎖爭用很是高

b.WiredTiger表現良好,128併發度時TPS處理能力達到5萬多,更高併發下處理能力逐漸降低,穩定在3萬到4萬之間

2.讀寫1比1混合的測試結果

結論:WiredTiger在讀寫1比1混合測試場景中,綜合能力優於toku和mmap,且讀寫互不影響,都比較穩健

 

a.WiredTiger在讀寫混合測試場景中更新性能明顯高於toku和mmap,讀性能在高於256時不如toku和mmap,可是讀寫互不影響且性能較爲穩定

b.mmap在高併發狀況下讀性能良好,可是更新性能降低很明顯,受讀的影響較大

c.toku在讀寫兩端就像是WiredTiger和mmap的中庸版



讀寫混合模式下,WiredTiger在32到256之間的併發狀況下,綜合能力優於toku和mmap,其餘併發度狀況下讀寫綜合能力相近

小結

由測試結果能夠看出,3.0的WT引擎對多併發更新的場景明顯好於其餘兩種引擎,TPS性能有較大的提高,所以建議線上升級3.0而且更換存儲引擎。

目前線上已經在測試環境部署了3.0的數據庫,等待應用反饋迴歸測試結果,若是一切順利,打算儘快升級

 

原創文章  

禁止其餘公衆帳號轉載

相關文章
相關標籤/搜索