磊哥評測之資料庫:騰訊雲MongoDB vs自建
作者:磊哥
上期文章我們聊到了redis。這期我們來說說另一個網紅nosql資料庫:MongoDB。有這麼一個介紹MongoDB的說法是:MongoDB是非關係資料庫當中功能最豐富,最像關係資料庫的。這麼說是因為作為一個面向文件儲存型、資料結構非常鬆散自由的的資料庫,卻擁有著豐富的功能特性如強大靈活的查詢語言、支援二級索引等特性,新版本的MongDB甚至還支援事務。聽小夥伴說MongoDB不僅功能豐富,而且讀效能強大到遠遠把MySQL甩在後面,今天我就代替大家來動手進行一下資料庫測試,揭開MongoDB的神祕“面紗”。
為了進行資料庫對比測試,這次我購買了騰訊雲MongoDB的主從版(1主2從),同時在同樣配置的雲主機自建MongoDB作為對比。
下面給出CentOS7 64位上安裝MongoDB 3.6的實踐如下:
vim /etc/yum.repos.d/mongod-org.repo
編輯內容如下:
[mongodb-org]
name=MongoDB Repository
baseurl= https://repo.mongodb.org/yum/... $releasever/mongodb-org/3.6/x86_64/
gpgcheck=1
enabled=1
gpgkey= https://www.mongodb.org/stati...
執行指令yum install mongodb-org -y安裝
vim /etc/mongod.conf
此處根據自己需求修改 bindIp: 0.0.0.0 #監聽地址 port: 27017 #監聽埠
systemctl start mongod.service #開啟服務
netstat -anpt | grep 27017 #檢查是否啟動
服務開啟後可以使用上面的指令測試服務是否啟動,如果成功啟動的話會看到結果如下圖所示:
如果無法啟動,需要根據日誌分析具體原因。根據筆者的實踐,大部分的原因會落在配置和許可權上。如果排除錯誤太難,建議重新安裝來的快一點。
接下來需要安裝資料庫測試工具,這次我們使用YCSB,雅虎開發的一個很強大的測試工具。
在安裝YCSB前需要安裝Java和Maven,測試前需要在workloads資料夾中建立配置檔案,配置如下圖所示:
考慮到購買的mongoDB是副本集配置,一個主節點帶兩個從節點,我們在本地也配置好副本叢集,使用用 ./mongod --replSet amymongo --dbpath /data/27019 --port 27019 --logpath /var/log/mongodb/27019.log --fork 配置從節點,具體配置和初始化方法參考 https://cloud.tencent.com/dev... (當然部署在本機的方案不能保證高可用)
在workloads中防止配置檔案,我們選擇插入1千萬條記錄,執行1千萬次操作,測試兩種場景:read/update 9:1和純insert場景。
廢話少說,下面就一起來看看測試結果吧。
場景讀更新read/update 9:1,單位ops/sec:
場景純寫入insert,單位ops/sec:
場景讀更新read/update 9:1,單位us(延時):
場景純寫入insert,單位us(延時):
看來mongodb真的是一個高效能的資料庫,為啥呢,因為mongo的延時單位居然是us微秒、微秒、微秒。。。16GB的記憶體基本上20執行緒之後延時就會大大增加,在100執行緒的時候基本上延時基本在1000us以上,而讀多場景跟寫入場景相比,寫入場景的效能略差一點,隨著執行緒數的增大,寫入場景的吞吐量和延時表現和讀更新場景的差距會擴大。
有讀者可能會有疑惑,既然資料庫測試是比較雲和自建,看起來差距也沒有那麼大,用自建好像也可以接受啊。這裡我要把測試中的發現講給大家聽,聽完之後大家就明白了。
第一點,筆者買的是16G記憶體的機器(流下了沒有錢的淚水),測試的時候發現cvm的記憶體佔用基本到了百分之60左右,筆者在建立副本集和加大測試資料量(購買資料量的百分之80)之後發現,記憶體佔用基本到了百分之80以上。看來mongo的第一個缺點,就是對記憶體的消耗真的非常可怕!!如果遇到高併發大資料量讀寫,恐怕分分鐘就存在著存在著OOM的風險。
所以這裡奉勸各位同學,如果要自建MongoDB,還是儘量購買超大記憶體滿足業務需求,避免在業務高峰的時候被“幹掉”。如果因為跟筆者一樣貧窮不想買那麼大的記憶體,可以考慮使用雲資料庫,雲MongoDB具備動態伸縮能力,即使沒有買夠大的記憶體,也完全來得及在業務高峰擴容, 即使發生故障,也有完善的資料自動備份和無損恢復機制來恢復資料,在可用性上保障就高多了。
第二點,筆者在後續測試本地副本集的時候,嘗試讀secondary節點的資料,結果遇到了讀延遲很高的情況。在網上研究了一下發現是因為,MongoDB 複製集裡 Secondary 不斷從主上批量拉取 oplog,然後在本地重放,以保證資料與 Primary 一致。這裡為了防止髒讀,會加一個鎖阻塞所有的讀請求。
所以如果遇到 Secondary 重放 oplog 佔用鎖時間長,讀取的延時也會對應變長。這個鎖最高能鎖多久呢,看到有個案例鎖了接近一個小時。。。看到的人內心一定是崩潰的,而在雲Mongo測試的時候沒有遇到這個情況,我想這一定是針對這個缺陷做了很大的改進,使用了其他方法實現同步。
總的來說,MongoDB確實可以不借助其他第三方工具實現高可用和分片功能,具備的高可用的故障切換,分片可以實現資料的分部均衡,大資料量的時候通過路由實現了伺服器的負載均衡。所以MongoDB自身的可用性較高,也難怪會在短短時間內成為流行的nosql資料庫。
但是MongoDB也存在著一些坑:如對記憶體的佔用過高、對網路的佔用過高、存在從節點鎖導致讀幾乎不可用的情況,這些情況在實際業務使用的時候會導致很嚴重的問題,叢集宕機、服務癱瘓、資料丟失無時不刻不是覆蓋在運維同學心頭的陰影。這個時候雲MongoDB幾乎就是救星,彈性伸縮、隨時擴容、真正安全的資料熱備以及強大的專業運維架構師團隊,才能真的確保業務安全無故障的執行下去。
寫到這裡,筆者也在思考,雲資料庫到底是什麼,它僅僅是把資料庫封裝一下,改改核心,提供給使用者嗎?不,雲資料庫應當是一整套專業服務,除了資料庫之外,還有監控、安全、遷移、災備、運維等一系列的服務提供。能讓業務開發專注於業務本身,把專業的交給專業的人去做。
此文已由騰訊雲+社群在各渠道釋出
獲取更多新鮮技術乾貨,可以關注我們 騰訊雲技術社群-雲加社群官方號及知乎機構號