摘要
1. MongoDB 適用場景簡介
2. Mongodb 性能監控與分析
3. Mongodb 性能優化建議mysql
關於Mongodb的幾個大事件
1.根據美國數據庫知識大全官網發佈的DB熱度排行,Mongodb的熱度排名從2014年的第5名,在2015年躍升爲第4名,僅次於主流DB(Oracle、MySQL、SQLServer)以後。linux
2.2015第六屆中國數據庫技術大會(DTCC)上,Mongodb高調宣佈收購開源引擎WiredTiger,性能在3.0版本上實現了7~10倍的提高。ios
Mongodb 適用場景簡介算法
適用場景
1. 實時的CRU操做,如網站、論壇等實時數據存儲
2. 高伸縮性,能夠分佈式集羣,動態增刪節點
3. 存儲大尺寸、低價值數據
4. 緩存
5. BSON結構對象存儲
不適用場景
1. 高度事務性操做,如銀行或會計系統
2. 傳統商業智能應用,如提供高度優化的查詢方式
3. 須要SQL的問題
4. 重要數據,關係型數據sql
Mongodb 性能監控與分析mongodb
mongostat
1. faults/s:每秒訪問失敗數,即數據被交換出物理內存,放到SWAP。
若太高(通常超過100),則意味着內存不足。
vmstat & iostat & iotop
si:每秒從磁盤讀入虛擬內存的大小,若大於0,表示物理內存不足。
so:每秒虛擬內存寫入磁盤的大小,若大於0,同上。shell
mongostat
2. idx miss %:BTree 樹未命中的比例,即索引不命中所佔百分比。
若太高,則意味着索引創建或使用不合理。
db.serverStatus()
indexCounters」 : {
「btree」 : {
「accesses」 : 2821726, #索引被訪問數
「hits」 : 2821725, #索引命中數
「misses」 : 1, #索引誤差數
「resets」 : 0, #復位數
「missRatio」 : 3.543930204420982e-7 #未命中率
}數據庫
mongostat
3. locked %:全局寫入鎖佔用了機器多少時間。當發生全局寫入鎖時,全部查詢操做都將等待,直到寫入鎖解除。
若太高(通常超過50%),則意味着程序存在問題。
db.currentOp()
{
「inprog」 : [ ],
「fsyncLock」 : 1, #爲1表示MongoDB的fsync進程(負責將寫入改變同步到磁盤)不容許其餘進程執行寫數據操做
「info」 : 「use db.fsyncUnlock() to terminate the fsync write/snapshot lock」
}緩存
mongostat
4. q r|w :等待處理的查詢請求隊列大小。
若太高,則意味着查詢會過慢。
db.serverStatus()
「currentQueue」 : {
「total」 : 1024, #當前須要執行的隊列
「readers」 : 256, #讀隊列
「writers」 : 768 #寫隊列
}性能優化
mongostat
5. conn :當前鏈接數。
高併發下,若鏈接數上不去,則意味着Linux系統內核須要調優。
db.serverStatus()
「connections」 : {
「current」 : 3, #當前鏈接數
「available」 : 19997 #可用鏈接數
}
6.鏈接數使用內存過大
shell> cat /proc/$(pidof mongod)/limits | grep stack | awk -F 'size' '{print int($NF)/1024}'
將鏈接數使用Linux棧內存設小,默認爲10MB(10240)
shell> ulimit -s 1024
優化器Profile
db.setProfilingLevel(2);
0 – 不開啓
1 – 記錄慢命令 (默認爲>100ms)
2 – 記錄全部命令
info: #本命令的詳細信息
reslen: #返回結果集的大小
nscanned: #本次查詢掃描的記錄數
nreturned: #本次查詢實際返回的結果集
millis: #該命令執行耗時(毫秒)
執行計劃Explain
db.test.find({age: 「20」}).hint({age:1 }).explain();
cursor: 返回遊標類型(BasicCursor 或 BtreeCursor)
nscanned: 被掃描的文檔數量
n: 返回的文檔數量
millis: 耗時(毫秒)
indexBounds: 所使用的索引
只查詢使用到的字段,而不查詢全部字段
db.posts.find({ts:1,title:1,author:1,abstract:1}).sort({ts:-1}).limit(10);
基於Mongodb分佈式集羣作數據分析時,MapReduce性能優於count、distinct、group等聚合函數
Capped Collections比普通Collections的讀寫效率高
db.createCollection(「mycoll」, {capped:true, size:100000});
例:system.profile 是一個Capped Collection。
注意:
固定大小;Capped Collections 必須事先建立,並設置大小。
Capped Collections能夠insert和update操做;不能delete操做。只能用 drop()方法刪除整個Collection。
默認基於 Insert 的次序排序的。若是查詢時沒有排序,則老是按照insert的順序返回。
FIFO。若是超過了Collection的限定大小,則用 FIFO 算法,新記錄將替代最早 insert的記錄。
Mongodb 3.0.X版本性能較Mongodb 2.0.X有7-10倍提高,引入WiredTiger新引擎,同時支持MMAPv1內存映射引擎
注意:
默認MMAPv1,切換至WiredTiger:mongod –dbpath /usr/local/mongodb/data –storageEngine wiredTiger
備註:若更換新引擎,則以前使用舊引擎創建的DB數據庫沒法使用。 建議先經過Mongodb的同步機制,將舊引擎創建的DB數據同步到從庫, 且從庫使用新引擎.
選擇 Windows 2008 R2 x64 或 Linux x64,Linux版本性能優於 Windows,建議基於Linux系統進行架構選型
根據RHEL版本號選擇Mongodb相應Linux版本
Mongodb Driver 與 Mongodb 版本一致
最後的建議
哪種物理設計更適合Mongodb:範式化 & 反範式化 & 業務 ?
範式化設計的思想是「徹底分離」,存在關聯查詢,查詢效率低,但寫入、修改、刪除性能更高
反範式化設計的思想是「數據集中存儲」,查詢效率高,而Mongodb對查詢機制支持較弱,看似成爲一種互補
下面咱們來看一個圖書信息DB表設計案例:
示例1:範式化設計
{
"_id" : ObjectId("5124b5d86041c7dca81917"),
"title" : "MongoDB性能調優",
"author" : [
ObjectId("144b5d83041c7dca84416"),
ObjectId("144b5d83041c7dca84418"),
ObjectId("144b5d83041c7dca84420"),
]
}
分析:更新效率高,由於不須要關聯表操做。好比更新做者年齡,只須要更新做者信息1張表就能夠了。而查詢效率低,由於須要關聯表操做。好比查看某本圖書的做者簡介,須要先查圖書信息表以獲取做者ID,再根據ID,在做者信息表中查詢做者簡介信息。
示例2:反範式化設計
{
"_id" : ObjectId("5124b5d86041c7dca81917"),
"title" : "MongoDB性能調優",
"author" : [
{
"name" : "張三"
"age" : 40,
"nationality" : "china",
},
{
"name" : "李四"
"age" : 49,
"nationality" : "china",
},
{
"name" : "王五"
"age" : 59,
"nationality" : "china",
},
]
}
分析:將做者簡介信息嵌入到圖書信息表中,這樣查詢效率高,不須要關聯表操做。依然是更新做者年齡,此時更新效率就顯得低,由於該做者出過多本書,須要修改多本圖書信息記錄中該做者的年齡。
示例3:不徹底範式化設計
{
"_id" : ObjectId("5124b5d86041c7dca81917"),
"title" : "MongoDB性能調優",
"author" : [
{
"_id" : ObjectId("144b5d83041c7dca84416"),
"name" : "張三"
},
{
"_id" : ObjectId("144b5d83041c7dca84418"),
"name" : "李四"
},
{
"_id" : ObjectId("144b5d83041c7dca84420"),
"name" : "王五"
},
]
}
分析:其實咱們知道某本書的做者姓名是不會變化的,屬於靜態數據,又好比做者的年齡、收入、關注度等,均屬於動態數據,因此結合業務特色,圖書信息表確定是查詢頻率高、修改頻率低,故能夠將一些做者的靜態數據嵌入到圖書信息表中,作一個折中處理,這樣性能更優。
總結:Mongodb性能調優不是最終或最有效的手段,最高效的方法是作出好的物理設計。而什麼樣的物理設計適合Mongodb,最後仍是由當前業務及業務將來發展趨勢決定的。最後送給你們一句話「好的性能不是調出來的,更可能是設計出來的」!