全部產品
Search
文件中心

ApsaraDB for MongoDB:MongoDB執行個體的CPU使用率高問題

更新時間:Jun 19, 2024

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管理主控台CloudDBA > 執行個體會話頁面查看當前執行的活躍會話,分析不符合預期執行時間的查詢操作,選擇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後,您可以在日誌管理 > 慢日誌中查看慢⽇志。

    重要
    • 您只能查看3天內的慢日誌。

    • 如果是2021年06月06日後新購買的執行個體,您需要先開通審計日誌功能,並設定需要審計的操作類型包含adminslow,然後查看慢日誌。

      • 只能查看審計日誌功能開通之後出現的慢日誌。

      • 開通審計日誌功能的方法請參見開通審計日誌

      • 設定審計操作類型的方法請參見更改審計設定

    更多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 ResultsCursor Methods

    • 索引設計和最佳化

      除了全表掃描以外,當查詢的掃描行數關鍵字docsExamined超過1000且執行頻率較高時,我們需要關注該查詢。除了全表掃描以外,造成docsExamined過多⼀般有以下情況:

      • 多條件過濾時,未使⽤複合式索引或不滿⾜最左首碼匹配原則。

      • 未使⽤索引做排序操作。

      • 查詢過於複雜,或者存在⼤量的彙總類操作,基本⽆法從索引層⾯做到極致最佳化,或者導致查詢⾛錯解析計劃。

      • 資料列的資料選擇性和運⾏頻率的評估錯誤,未能做到最好的折中。

      針對以上問題的更多資訊,請參見以下官⽅⽂檔:

  • 並發過大

    如果確認查詢層⾯沒有問題,那麼引起執行個體CPU佔用高的可能原因為業務並發過⾼。如果是由於業務請求量過⼤,並發過⾼導致了CPU佔用高的問題,在ApsaraDB for 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升⾼。如果遇到這種情況,建議您直接忽略。