記一次 MongoDB 佔用 CPU 太高問題的排查

引言

今天查看監控無心間忽然發現本身的服務器上,CPU 佔用率飆升到 100%,load 升到 10 以上,登陸的響應已經達到半分鐘html

立刻運行 top,發現主要是 mongodb 佔用了大量的 CPU,這是爲何呢?又該如何解決呢?mongodb

 

 

分析正在執行的請求

經過運行命令:數據庫

 

1服務器

db.currentOp()優化

 

咱們能夠看到數據庫當前正在執行的操做:spa

 

 

 

官方文檔

 

https://docs.mongodb.com/manual/reference/method/db.currentOp/?spm=a2c4e.11153940.blogcont73389.10.2c402b90x4iad1日誌

 

 

包含信息

 

主要有如下信息:htm

 

 

 

 

 

 

 

 

 

 

  • client -- 請求是由哪一個客戶端發起的
  • opid -- 操做的opid,有須要的話,能夠經過 db.killOp(opid) 殺死操做
  • secs_running/microsecs_running -- 請求運行的時間,若是這個值特別大就很是值得注意
  • query/ns: 對集合進行的具體操做
  • lock*:鎖相關參數

 

開啓慢請求日誌

MongoDB 支持 profiling 功能,將請求的執行狀況記錄到同DB下的 system.profile 集合裏,profiling 有3種模式:blog

 

 

 

 

 

 

  1. 0 -- 關閉 profiling
  2. 1 -- 針對慢請求 profiling,將超過必定閾值的請求,記錄到system.profile 集合
  3. 2 -- 針對全部請求開啓 profiling,將全部請求的執行都記錄到 system.profile 集合

 

 

經過命令開啓

 

推薦在生產環境中設置爲 1,開啓慢請求日誌,方便問題的暴露和排查,能夠經過下面命令設置 profiling 級別:排序

 

1

db.setProfilingLevel(1, { slowms: 20 })

 

 

{ slowms: 20 } 參數就是慢請求執行閾值,單位是毫秒

 

 

經過配置文件開啓

 

也能夠經過配置文件開啓:

 

1

2

3

operationProfiling:

mode: slowOp

slowOpThresholdMs: 100

 

 

 

查看慢請求記錄

 

下面的命令中咱們獲取了最近的3條慢請求記錄:

 

1

db.system.profile.find().sort({$natrual: -1}).limit(3)

 

 

慢請求分析 -- 全表掃描 COLLSCAN

若是在日誌中看到關鍵字 COLLSCAN,說明該查詢在進行全表掃描,一般這就是 CPU 異常飆高的主要緣由

 

 

查看掃描文檔數

 

system.profile 裏 docsExamined 的值顯示了本次查詢的掃描文檔數

 

 

解決辦法 -- 添加索引

 

最好針對查詢語句創建索引:

 

1

db.col.createIndex({"title":1})

 

 

咱們也能夠在添加索引時增長傳入可選參數,例如,在生產環境咱們一般不但願索引添加的操做阻塞其餘數據庫操做,這時就須要務必添加 background 參數:

 

1

db.col.createIndex({"title":1}, {'background', true})

 

 

慢請求分析 -- 索引設置不合理

有的時候,請求即便查詢走了索引,執行也很慢,一般是由於索引創建不太合理或者匹配結果太多

索引一般應該創建在區分度大的字段上

在 system.profile 中,能夠經過 keysExamined 字段查看查詢掃描了多少條索引,若是該值過大,要考慮創建新的索引或優化查詢了

 

慢請求分析 -- 大量數據排序

當查詢請求裏包含排序的時候,若是排序沒法經過索引知足,MongoDB 會在內存中對結果進行排序

你們都知道,排序是很是消耗 CPU 的一項操做,最好在須要排序的字段上創建索引

 

system.profile 中的 SORT 關鍵字反映了查詢須要排序

 

服務能力評估

有時 CPU 消耗太高僅僅是單純的由於服務器達到了上限

若是上面的措施都沒法讓 CPU 佔用率降低到合理的指標內,就要考慮擴容、升級來提高服務能力的上限

但切忌將這個方法做爲首要考慮的解決方案,合理的設置索引,創建資源預警,而不是盲目提高配置或在業務已經達到上限時再考慮優化

 

參考資料

https://docs.mongodb.com/manual/reference/method/db.currentOp/?spm=a2c4e.11153940.blogcont73389.10.2c402b90x4iad1

https://docs.mongodb.com/manual/tutorial/manage-the-database-profiler/?spm=a2c4e.11153940.blogcont73389.11.2c402b90x4iad1

https://docs.mongodb.com/manual/reference/database-profiler/?spm=a2c4e.11153940.blogcont73389.13.2c402b90WPcbsr

https://yq.aliyun.com/articles/73389

http://www.runoob.com/mongodb/mongodb-indexing.html

相關文章
相關標籤/搜索