Mongodb是一種單進程且靈活的非關系型數據庫。但由于其軟件小巧,單進程多線程的特點注定不會存在完善的系統動態性能視圖,這點與mysql類似,但個人認為即便與mysql對比,不足還是顯而易見。此外,對于運維人員來說,多數人習慣使用字符終端處理問題,由于mongodb是基于json,所以輸出都是json格式,這點跟關系型數據庫輸出的行列格式相比,個人感覺可讀性相對較差。所以,基于運維需要的MongDB監控能力補齊,是運維工作不可或缺工作之一,至于是腳本形式還是工具平臺形式,都可以基于各自已有IT能力水平有計劃分步驟的進行實施。畢竟不管白貓黑貓,能抓老鼠的就是好貓。
數據庫性能數據獲取診斷方式對比:
數據庫 | 進程結構 | 獲取、診斷性能問題的方式 | 備注 |
oracle | 多進程 | 1、有大量的動態性能視圖,如v$session,v$latch等,可進行關聯查詢反饋當前數據庫實例的會話等待、會話CPU、IO等資源消耗等 | |
mysql | 單進程多線程 | 1、存在少量多臺性能視圖可供查詢 | |
mongodb | 單進程多線程 | 1、通過mongotop、mongostat工具診斷 |
在數據庫日常運維過程中,數據庫性能監控是重點工作之一。對于mongodb來說,由于在數據庫中不會保存歷史性能信息,所以我們只能通過使用集中監控軟件或者自己編寫腳本的方式采集性能數據保存在本地,本文只介紹利用Mongodb自帶工具或者命令采集性能數據。
1、操作系統資源使用率監控
操作系統CPU、內存、IO等資源使用率監控,在任一數據庫產品都需要部署,本文不再闡述。
2、mongotop&&mongostat
mongotop和mongostat是mongodb官方提供的兩個在不同級別對數據庫性能進行監控的工具,可以獲取到實例全局和表級的性能數據。通過在操作系統上部署定時任務的方式執行這兩個命令并將結果輸出保存,可用于歷史性能分析。
1)、mongotop
返回數據庫集合級別的讀寫耗時情況,輸出結果按照讀寫耗時降序排列,排序越靠前表示該集合訪問并發越大或者說該集合上執行的MQL語句執行計劃不是最優。輸出結果示例如下:
2)、mongostat
mongostat類似操作系統的vmstat命令,返回實例全局每秒鐘整體性能情況,包括讀寫次數、內存占用,鎖隊列、網絡、連接數等信息。如果是集群,建議使用—discover參數獲取集群全局信息。
oracle有一個監控利器叫Oswatcher,使用mongostat&&mongotop合理編寫腳本,在用crontab定時調用,可實現類似oswatcher的功能,作為歷史性能數據分析。
3、慢查詢分析
mongodb的慢查詢,可以通過設置profile后,在system.profile集合或者在數據庫日志中獲取。設置命令為db.setProfilingLevel(level,options),如db.setProfilingLevel(1,{ slowms: 200 }),表示級別為1,超過200ms的操作將被捕獲,設置級別為0表示不捕獲,級別為2表示捕獲所有操作。可通過db.getProfilingStatus()命令查詢當前的profile設置級別。
1)、system.profile
system.profile是通過使用db.setProfilingLevel(level,options)命令設置后在每一個庫中生成的固定大小為1MB的集合,該集合根據設置的profile級別保存所有或者超過指定時間的操作命令信息,當保存數據過多超過1MB時,會自動清理歷史數據。
保存信息示例:
{
"op": "query", --操作類型為查詢
"ns": "opn###od.optN###em", --操作的庫名.集合名
"command": {
"find": "optNu###tem", --集合名稱
"filter": { --過濾條件
"_id": {
"res##id": "1000000000000003733049",
"res##etype": "3002"
}
},
"limit": 1, --limit條數
"singleBatch": true,
"$db": "opnu###od" --庫名
},
"keysExamined": 0,
"docsExamined": 0,
"cursorExhausted": true,
"numYield": 0,
"locks": { ---本次操作的鎖信息
"Global": {
"acquireCount": {
"r": NumberLong(2)
}
},
"Database": {
"acquireCount": {
"r": NumberLong(1)
}
},
"Collection": {
"acquireCount": {
"r": NumberLong(1)
}
}
},
"nreturned": 0,
"responseLength": 237,
"protocol": "op_query",
"millis": 77432, --操作耗時,單位為毫秒
"planSummary": "IDHACK", ---執行計劃類型
"execStats": {
"stage": "IDHACK",
"nReturned": 0,
"executionTimeMillisEstimate": 0,
"works": 1,
"advanced": 0,
"needTime": 0,
"needYield": 0,
"saveState": 0,
"restoreState": 0,
"isEOF": 1,
"invalidates": 0,
"keysExamined": 0,
"docsExamined": 0
},
"ts": ISODate("2019-11-14T06:47:45.285Z"),--操作時間
"client": "10***227", ---客戶端IP
"allUsers": [
{
"user": "user_admin",
"db": "admin"
}
],
"user": "user_admin@admin"
}
2)、從日志中獲取慢查詢
在mongodb的后臺日志中會同時記錄一份慢查詢信息,相對于system.profile集合的優點是會永久保存,缺點是需要從海量的日志中過濾慢日志信息,不過若數據庫的性能較差且并發較大,此時可看到日志上有大量的慢查尋日志刷屏,一般也可快速定位問題。
日志中輸出的內容跟system.profile保存的基本一致,只是可讀性稍微較差些,示例見上圖。
4、當前會話操作獲取
在mongodb中,如需獲取當前的會話信息,可使用db.currentOp()命令,該命令獲取到的信息,類似于在oracle中通過聯合查詢v$session和v$process獲取到的信息,包含客戶端類型、IP、正在執行的命令、正在操作的對象、執行計劃、鎖等等詳細信息,其中包括活動會話和非活動會話信息。對于自己需要的信息,可通過相關的過濾條件進行過濾,如下示例:
--獲取活動會話信息
db.currentOp(
{
"active": true
}
)
--查詢所有在等待鎖,且操作命令為增刪改的會話信息。
db.currentOp(
{
"waitingForLock": true,
$or:[
{"op" : { "$in" : [ "insert", "update","remove" ] } },
{"query.findandmodify": { $exists: true } }
]
}
)
從3.6版本開始,提供了$currentOp這個聚合管道階段,可以更加靈活的獲取到當前的會話操作信息,并且返回的是游標,規避了db.currentOp的最大16MB的BSON大小限制。
--獲取活動會話,
useadmin
db.aggregate([
{$currentOp: { allUsers: true ,idleConnections:false} },
{$project:{opid:1,client:1,op:1,ns:1,microsecs_running:1}},
{$match:{client:{$exists:true}}}
]);
針對獲取到的異常會話或者執行時間長的會話,可以通過db.killOp()命令kill客戶端會話。
1、通過創建索引優化慢查詢
跟其他關系型數據庫一樣,當出現對大量的慢查詢時,可以檢查其執行計劃,若執行計劃是全表掃描(COLLSCAN)語句時,可以通過在選擇性較高的過濾條件上創建索引來優化查詢。db.collection.createIndex({field:1},{background,true});
注:生產系統創建索引一定必須在后臺創建索引,即指定{background,true},否則會產生庫級鎖
2、數據庫阻塞處理
mongodb作為一款輕量級nosql數據庫,在并發鎖控制上相對弱些。部分操作會加庫級鎖,如前臺創建索引、碎片整理、repair等,庫級鎖會阻塞當前數據庫的所有操作,最明顯的表現就是會導致數據庫會話數逐漸上升,阻塞時間長還會導致連接數爆滿。此類操作一般會記錄在后臺日志中,通過db.currentop()也可獲取會話信息,然后通過db.killOp()命令kill會話。注:killop只能kill客戶端會話,并且不是所有的操作都可以kill。
3、內存優化處理
在3.2版本以后,默認使用wiredtiger存儲引擎,可以通過參數cacheSizeGB設置存儲引擎的內存使用上限,默認是系統內存的60%。可以通過mongostat觀察內存cache的使用情況,一般情況下used會小于80%,如果長時間的used達90%或者dirty10%,可考慮增加內存或者檢查IO 。
4、數據庫寫入性能較差
寫入性能差,需確定是整體性能差還是某個集合寫入性能差,如果是整體都差的話,需檢查IO,考慮更換性能更好的存儲或者進行分片打散IO。如果是某個集合寫入性能差,則需要檢查這個集合是否索引過多,或者高并發或者異常語句導致異常加鎖。
--查詢在某個庫中從未使用過的索引,如果索引長期未使用,建議刪除
db.getCollectionNames().forEach(function(collection){
if(db[collection].getIndexes().length != 1){
print("Indexesfor "+ collection + ":");
db[collection].aggregate([{
$indexStats:{}
},{
$project:{
host:0
}
}]).forEach(
function(opDoc){
if(opDoc.accesses.ops== 0&& opDoc.name!= "_id_"){
printjson(opDoc);
}
});
}
});
5、便捷的數據生命周期管理
TTL索引是MongoDB中一種特殊的索引,可以支持文檔在一定時間之后自動過期刪除。可以再除_id外的所有字段上建立,但是只有在當字段值是時間或者數組中包含時間時,TTL索引才會執行刪除操作,數組中包含多個時間時,按照數組中最小的時間計算。
例:db.collection.createIndex({ "InsertTime": 1 }, { expireAfterSeconds: 2592000?} );
6、內存數據庫引擎
Mongodb企業版擁有自己的內存數據庫引擎,但是需要收費。在社區版中,可將數據文件(dbpath)放入/de/shm中,變相使用內存引擎。
注:由于內存一般不會太大,建議合理選擇業務,并使用固定大小集合。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/130193.html
摘要:優志愿張海鵬宋體背景宋體每年月下旬到月下旬期間是高考填志愿的高峰期,也是優志愿后端面臨大流量高并發請求的業務高峰期。對于優志愿讀多寫少的場景及其業務高峰期,用戶可以按需增刪節點,更好地實現讀取性能的擴展。 隨著用戶規模的增長,數據庫的壓力也在成倍增加。面對大流量、高并發,UCloud MongoDB 做到了高效,并展現出了更好的性能體驗。 —— 優志愿 CTO 張海鵬 背景...
摘要:監控和管理概述監控和管理是一個用于管理和監控和性能的開源平臺。是收集性能指標的。刪除數據容器升級服務器先停再刪,如果如要保留收集數據,不要執行此操作在和上安裝客戶端客戶端是安裝在您要監視的或主機上的一組代理和出口商。 Percona監控和管理概述 Percona監控和管理(PMM)是一個用于管理和監控MySQL和MongoDB性能的開源平臺。 它由Percona與托管數據庫服務,支持和...
摘要:推薦閱讀資源庫工具應用程序精選列表中文版有哪些鮮為人知,但是很有意思的網站一份攻城獅筆記每天搜集上優秀的項目一些有趣的民間故事超好用的谷歌瀏覽器油猴插件合集目錄資源文檔文章圖書會談教程更多庫工具管理數據部署桌面發展監控應用資源文檔介紹文檔教 推薦閱讀 MongoDB 資源、庫、工具、應用程序精選列表中文版 有哪些鮮為人知,但是很有意思的網站? 一份攻城獅筆記 每天搜集 Github ...
閱讀 1346·2023-01-11 13:20
閱讀 1684·2023-01-11 13:20
閱讀 1132·2023-01-11 13:20
閱讀 1858·2023-01-11 13:20
閱讀 4100·2023-01-11 13:20
閱讀 2704·2023-01-11 13:20
閱讀 1385·2023-01-11 13:20
閱讀 3597·2023-01-11 13:20