MongoDB實例的CPU使?率是?個?常重要的監控指標。如果MongoDB實例的CPU使?率過?,會導致MonogoDB響應緩慢,甚?業務不可?。本文介紹查看MongoDB實例CPU使用率的方法,以及導致CPU使用率高的原因和優化策略。
查看CPU使用率
分?集群架構下,各個Shard的CPU使?與副本集保持?致;Config Server僅僅存儲配置元數據,基本上不會造成CPU瓶頸,?般可以忽略;Mongos路由節點的CPU使?往往與聚合結果集、并發請求數有關。
副本集架構下,提供有多種查看CPU使?的?法:
監控圖查看
MongoDB副本集由多種??組成,?個??可能對應?個或多個物理節點。阿?云MongoDB對?戶暴露主節點(Primary)和從節點(Secondary),另外還提供有只讀實例。
在MongoDB管理控制臺的監控信息頁面,選擇對應的?色,查看MongoDB CPU使?率的監控情況。
說明CPU使?率與實例規格有關,例如實例規格是8核16 GB,那么CPU使?率顯示100%的時候,就表示該實例已經?滿了8核的CPU,而并非顯示800%。
查看和Kill活躍會話
正常運?中的MongoDB實例會話突然飆升?100%,絕?部分情況是業務側的變化引起,可能是由于掃描行數過多、數據排序和聚合、業務流量突增等原因導致的。建議您使?以下方法查看。
在MongoDB管理控制臺的 頁面查看當前執行的活躍會話,分析不符合預期執行時間的查詢操作,選擇Kill活躍會話或者其他方法解決該問題。
通過MongoDB?帶的命令db.currentOp()查看和分析更加詳細的活躍會話執行情況。如果需要,可以通過命令db.killOp()主動Kill?預期內的慢查詢。詳情請參見db.currentOp()和db.killOp()。
記錄慢?志和審計?志
MongoDB在profiling上共有3種設置模式:
關閉profiling,即不記錄任何請求。
針對所有請求開啟profiling,即將所有請求的執?都記錄到system.profile集合。
慢查詢profiling,將超過?定閾值的請求,記錄到system.profile集合。
在MongoDB管理控制臺的 頁面,根據業務需求設置合理的operationProfiling.mode(慢查詢的模式)和operationProfiling.slowOpThresholdMs(慢查詢的閾值)。
設置profiling后,您可以在
中查看慢?志。更多profiling的信息請參見:https://docs.mongodb.com/manual/tutorial/manage-the-database-profiler/
部分情況下排查問題請求需要更為細致的審計,您可以在MongoDB管理控制臺的 頁面開通審計?志。
關于審計?志的使??法和語法參考:開通日志審計功能
CPU使用率高的常見原因和優化策略
CPU使用率高的常見原因及對應的優化策略如下:
掃描?數過多
MongoDB為多線程應?,如果存在單個查詢掃描?數過多,該查詢所在線程的CPU占?時間會變?,當請求堆積或此類查詢的并發度?夠高時,整個MongoDB實例的CPU占用就會過高。從某種意義上說,MongoDB的CPU使?率與該實例的總掃描?數成正相關的關系。
索引優化是減少MongoDB單個查詢掃描?數的最優?案,從底層設計上,MongoDB的索引設計原理?乎與MySQL保持?致(或許種類和功能更豐富?些),所以適?于MySQL的索引優化策略基本也都適?于 MongoDB實例。
導致查詢掃描行數過多的場景有以下幾個方面:
全表掃描
當您在 system.profile集合或者運??志?件發現COLLSCAN關鍵字時,就表示該查詢進行了全表掃描。針對這類查詢,您可以通過添加索引的方法優化,如果當前已不能使用該方法,則在業務側控制該表的數據量和執行頻率。
更多關于查詢執?計劃的解讀,請參見:Explain Results和Cursor Methods。
索引設計和優化
除了全表掃描以外,當查詢的掃描行數關鍵字docsExamined超過1000且執行頻率較高時,我們需要關注該查詢。除了全表掃描以外,造成docsExamined過多?般有以下情況:
多條件過濾時,未使?組合索引或不滿?最左前綴匹配原則。
未使?索引做排序操作。
查詢過于復雜,或者存在?量的聚合類操作,基本?法從索引層?做到極致優化,或者導致查詢?錯解析計劃。
數據列的數據選擇性和運?頻率的評估錯誤,未能做到最好的折中。
針對以上問題的更多信息,請參見以下官??檔:
組合索引的原理和使??法,詳情請參見:Compound Indexes。
使?索引排序,詳情請參見:Use Indexes to Sort Query Results。
使?Hint固化執?計劃,詳情請參考:Cursor Methods和cursor.hint()。
索引的數據選擇性和運?頻率折中?法,詳情請參見:Create Queries that Ensure Selectivity。
并發過大
如果確認查詢層?沒有問題,那么引起實例CPU占用高的可能原因為業務并發過?。如果是由于業務請求量過?,并發過?導致了CPU占用高的問題,在云數據庫MongoDB中解決思路本質上就是通過添加CPU核數的?式解決,?般有如下?法:
單實例垂直配置升降級,使得單實例能夠承載更多的讀寫量。
配置副本集層?的讀寫分離,或者添加該副本的只讀實例。
升級?MongoDB分?集群,通過數據?平拆分的?式橫向,線性擴展系統性能。
如果是Mongos路由節點CPU占滿,則直接添加Mongos節點個數并設置Mongos節點的負載均衡,關于Mongos節點負載均衡的說明,請參見負載均衡。
更多內容請參見阿?云MongoDB官??檔:變更分片集群實例配置概覽、變更單節點實例配置和變更副本集實例配置。
其他可能導致CPU使用率高的場景
MongoDB頻繁短連接
MongoDB 3.X后使?的默認的身份認證機制是SCRAM-SHA1,需要進??些CPU密集型操作?如哈希計算等,在?并發的短連接場景下,這些哈希計算占?的CPU將會被放?很多倍,進?耗盡整個機器的CPU資源,其中?個現象是在運??志中可以發現?量包含saslStart的報錯信息。
阿?云MongoDB建議您盡可能使??連接,同時在PHP?并發短連接場景做了?定程度的優化,通過在內核層?優化改寫內置的隨機函數的?式?幅降低了MongoDB實例CPU使?率。
在MongoDB管理控制臺的數據庫連接頁面開啟私網免密訪問。
TTL索引導致從節點(Secondary)CPU使?率?于主節點(Primary)CPU使用率
自MongoDB 3.2開始實現了多線程復制,Oplog日志的回放并發度由參數replWriterThreadCount控制,默認為16。所以盡管Secondary節點不承載任何業務讀,在部分場景下CPU使?率也可能會超過Primary節點。例如在Primary節點上針對某?張表設置了TTL過期?動刪除,在Primary節點上,系統會根據時間列的索引批量刪除數據,效率很?,同時會將該操作轉換成很多單條的Delete操作發送給Secondary節點;在Secondary節點上,回放Oplog日志時效率較低,所以在多線程回放的情況下容易引起該節點CPU升?。如果遇到這種情況,建議您直接忽略。