《MongoDB CPU 利用率高,怎么破?》要點(diǎn):
本文介紹了MongoDB CPU 利用率高,怎么破?,希望對(duì)您有用。如果有疑問(wèn),可以聯(lián)系我們。
相關(guān)主題:非關(guān)系型數(shù)據(jù)庫(kù)
歡迎參與《MongoDB CPU 利用率高,怎么破?》討論,分享您的想法,維易PHP學(xué)院為您提供專(zhuān)業(yè)教程。
更多深度文章,請(qǐng)關(guān)注云計(jì)算頻道:https://yq.aliyun.com/cloud
經(jīng)常有用戶(hù)咨詢(xún)「MongoDB CPU 利用率很高,都快跑滿(mǎn)了」,應(yīng)該怎么辦?
遇到這個(gè)問(wèn)題,99.9999% 的可能性是「用戶(hù)使用上不合理導(dǎo)致」,本文主要介紹從應(yīng)用的角度如何排查 MongoDB CPU 利用率高的問(wèn)題
Step1: 分析數(shù)據(jù)庫(kù)正在執(zhí)行的哀求
用戶(hù)可以通過(guò) Mongo Shell 連接,并執(zhí)行 db.currentOp()
命令,能看到數(shù)據(jù)庫(kù)當(dāng)前正在執(zhí)行的操作,如下是該命令的一個(gè)輸出示例,標(biāo)識(shí)一個(gè)正在執(zhí)行的操作.重點(diǎn)關(guān)注幾個(gè)字段
client:哀求是由哪個(gè)客戶(hù)端發(fā)起的?
opid:操作的opid,有必要的話,可以通過(guò) db.killOp(opid) 直接干掉的操作
secs_running/microsecs_running: 這個(gè)值重點(diǎn)關(guān)注,代表哀求運(yùn)行的時(shí)間,如果這個(gè)值特別大,就得注意了,看看哀求是否合理
query/ns: 這個(gè)能看出是對(duì)哪個(gè)集合正在執(zhí)行什么操作
lock*:還有一些跟鎖相關(guān)的參數(shù),必要了解可以看官網(wǎng)文檔,本文不做詳細(xì)介紹
db.currentOp 文檔在這里,多看官網(wǎng)文檔
{ "desc" : "conn632530", "threadId" : "140298196924160", "connectionId" : 632530, "client" : "11.192.159.236:57052", "active" : true, "opid" : 1008837885, "secs_running" : 0, "microsecs_running" : NumberLong(70), "op" : "update", "ns" : "mygame.players", "query" : { "uid" : NumberLong(31577677)
這里先要明確一下,通過(guò) db.currentOp() 查看正在執(zhí)行的操作,目的到底是什么?
并不是說(shuō)我們要將正在執(zhí)行的操作都列出來(lái),然后通過(guò) killOp
逐個(gè)干掉;這一步的目的是要看一下,是否有「意料之外」的耗時(shí)哀求正在執(zhí)行.
好比你的業(yè)務(wù)平時(shí) CPU 利用率不高,運(yùn)維管理人員連到數(shù)據(jù)庫(kù)執(zhí)行了一些需要全表掃描的操作,然后突然 CPU 利用率飆高,導(dǎo)致你的業(yè)務(wù)響應(yīng)很慢,那么就要重點(diǎn)關(guān)注下那些執(zhí)行時(shí)間很長(zhǎng)的操作.
一旦找到罪魁禍?zhǔn)?拿到對(duì)應(yīng)哀求的 opid,執(zhí)行 db.killOp(opid)
將對(duì)應(yīng)的哀求干掉.
如果你的應(yīng)用一上線,cpu利用率就很高,而且一直持續(xù),通過(guò) db.currentOp
的結(jié)果也沒(méi)發(fā)現(xiàn)什么異常哀求,可以進(jìn)入到 Step2 進(jìn)行更深入的分析.
Step2:分析數(shù)據(jù)庫(kù)慢哀求
MongoDB 支持 profiling 功能,將哀求的執(zhí)行情況記錄到同DB下的 system.profile
集合里,profiling 有3種模式
profiling 設(shè)置文檔在這里,多看官網(wǎng)文檔
關(guān)閉 profiling
針對(duì)所有哀求開(kāi)啟 profiling,將所有哀求的執(zhí)行都記錄到 system.profile
集合
針對(duì)慢哀求 profiling,將超過(guò)一定閾值的哀求,記錄到system.profile
集合
默認(rèn)哀求下,MongoDB 的 profiling 功能是關(guān)閉,生產(chǎn)環(huán)境建議開(kāi)啟,慢哀求閾值可根據(jù)需要定制,如不確定,直接使用默認(rèn)值100ms.
operationProfiling: mode: slowOp
基于上述配置,MongoDB 會(huì)將超過(guò) 100ms 的哀求記錄到對(duì)應(yīng)DB 的 system.profile
集合里,system.profile
默認(rèn)是一個(gè)最多占用 1MB 空間的 capped collection.
查看最近3條 慢哀求,{$natrual: -1} 代表按插入數(shù)序逆序
在開(kāi)啟了慢哀求 profiling 的情況下(MongoDB 云數(shù)據(jù)庫(kù)是默認(rèn)開(kāi)啟慢哀求 profiling的),我們對(duì)慢哀求的內(nèi)容進(jìn)行分析,來(lái)找出可優(yōu)化的點(diǎn),常見(jiàn)的包括.
profiling的結(jié)果輸出含義在這里,多看官網(wǎng)文檔
CPU殺手1:全表掃描
全集合(表)掃描 COLLSCAN
,當(dāng)一個(gè)查詢(xún)(或更新、刪除)哀求需要全表掃描時(shí),是非常耗CPU資源的,所以當(dāng)你在 system.profile
集合 或者 日志文件發(fā)現(xiàn) COLLSCAN
關(guān)鍵字時(shí),就得注意了,很可能就是這些查詢(xún)吃掉了你的 CPU 資源;確認(rèn)一下,如果這種哀求比較頻繁,最好是針對(duì)查詢(xún)的字段建立索引來(lái)優(yōu)化.
一個(gè)查詢(xún)掃描了多少文檔,可查看 system.profile
里的 docsExamined
的值,該值越大,哀求CPU開(kāi)銷(xiāo)越大.
關(guān)鍵字:COLLSCAN、 docsExamined
CPU殺手2:不合理的索引
有的時(shí)候,哀求即使查詢(xún)走了索引,執(zhí)行也很慢,通常是因?yàn)楹侠斫⒉惶侠?或者是匹配的結(jié)果本身就很多,這樣即使走索引,哀求開(kāi)銷(xiāo)也不會(huì)優(yōu)化很多).
如下所示,假設(shè)某個(gè)集合的數(shù)據(jù),x字段的取值很少(假設(shè)只有1、2),而y字段的取值很豐富.
{ x: 1, y: 1 }
要服務(wù) {x: 1: y: 2}
這樣的查詢(xún)
db.createIndex( {x: 1} ) 效果欠好,因?yàn)閤相同取值太多db.createIndex( {x: 1, y: 1} ) 效果欠好,因?yàn)閤相同取值太多db.createIndex( {y: 1 } ) 效果好,因?yàn)閥相同取值很少db.createIndex( {y: 1, x: 1 } ) 效果好,因?yàn)閥相同取值少
至于{y: 1} 與 {y: 1, x: 1} 的區(qū)別,可參考MongoDB索引原理 及 復(fù)合索引官方文檔 自行理解.
一個(gè)走索引的查詢(xún),掃描了多少條索引,可查看 system.profile
里的 keysExamined
字段,該值越大,CPU 開(kāi)銷(xiāo)越大.
關(guān)鍵字:IXSCAN、keysExamined
CPU殺手3:大量數(shù)據(jù)排序
當(dāng)查詢(xún)哀求里包含排序的時(shí)候,如果排序無(wú)法通過(guò)索引滿(mǎn)足,MongoDB 會(huì)在內(nèi)存李結(jié)果進(jìn)行排序,而排序這個(gè)動(dòng)作本身是非常耗 CPU 資源的,優(yōu)化的方法仍然是建立索引,對(duì)經(jīng)常需要排序的字段,建立索引.
當(dāng)你在 system.profile
集合 或者 日志文件發(fā)現(xiàn) SORT
關(guān)鍵字時(shí),就可以考慮通過(guò)索引來(lái)優(yōu)化排序.當(dāng)哀求包含排序階段時(shí), system.profile
里的 hasSortStage
字段會(huì)為 true.
關(guān)鍵字:SORT、hasSortStage
其他還有諸如建索引,aggregationv等操作也可能非常耗 CPU 資源,但本色上也是上述幾種場(chǎng)景;建索引需要全表掃描,而vaggeregation 也是遍歷、查詢(xún)、更新、排序等動(dòng)作的組合.
Step3: 服務(wù)才能評(píng)估
經(jīng)過(guò)上述2步,你發(fā)現(xiàn)整個(gè)數(shù)據(jù)庫(kù)的查詢(xún)非常合理,所有的哀求都是高效的走了索引,基本沒(méi)有優(yōu)化的空間了,那么很可能是你機(jī)器的服務(wù)能力已經(jīng)達(dá)到上限了,應(yīng)該升級(jí)配置了(或者通過(guò) sharding 擴(kuò)展).
當(dāng)然最好的情況時(shí),提前對(duì) MongoDB 進(jìn)行測(cè)試,了解在你的場(chǎng)景下,對(duì)應(yīng)的服務(wù)才能上限,以便及時(shí)擴(kuò)容、升級(jí),而不是到 CPU 資源用滿(mǎn),業(yè)務(wù)已經(jīng)完全撐不住的時(shí)候才去做評(píng)估.
轉(zhuǎn)載請(qǐng)注明本頁(yè)網(wǎng)址:
http://www.fzlkiss.com/jiaocheng/10241.html