全部產品
Search
文件中心

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

更新時間:Dec 28, 2024

MongoDB執行個體的CPU使用率是一個非常重要的監控指標。如果MongoDB執行個體的CPU使用率過高,會導致MongoDB響應緩慢,甚至業務不可用。本文介紹查看MongoDB執行個體CPU使用率的方法,以及導致CPU使用率高的原因和最佳化策略。

查看方法

監控圖查看:在MongoDB管理主控台監控資訊頁面,可以查看ApsaraDB for MongoDB的CPU使用率。關於採集粒度和操作步驟的更多資訊,請參見基本監控

ApsaraDB for MongoDB不同架構的節點構成不同,您可以選擇對應節點,查看其CPU使⽤率。

  • 複本集架構。包括一個主節點(Primary節點)、一個或多個從節點(Secondary節點)、一個隱藏節點(Hidden節點)和可選的一個或多個唯讀節點(ReadOnly節點)。

  • 分區叢集架構。各個分區(Shard)的CPU使用與複本集保持一致;ConfigServer僅儲存配置中繼資料,基本上不會造成CPU瓶頸,一般可以忽略;Mongos路由節點的CPU使用往往與彙總結果集、並發請求數有關。

說明

CPU使用率與執行個體規格有關,例如執行個體規格是8核16 GB,CPU使用率顯示100%時,表示該執行個體已經用滿了8核的CPU,而並非顯示800%。

常見原因

掃描行數過多

MongoDB為多線程應用,如果存在單個查詢掃描行數過多,該查詢所線上程的CPU佔用時間會變長,當請求堆積或此類查詢的並發度足夠高時,整個MongoDB執行個體的CPU佔用就會過高。從某種意義上說,MongoDB的CPU使用率與該執行個體的總掃描行數成正相關的關係。導致查詢掃描行數過多的情境有以下幾個方面:

  • 全表掃描

    當您在慢日誌或者 system.profile集合(需主動開啟database profiler)中發現COLLSCAN關鍵字時,就表示該查詢進行了全表掃描。關於查看慢日誌與database profiler的更多資訊,請參見慢日誌

    關於查詢執行計畫的更多解讀資訊,請參見:Explain ResultsCursor Methods

  • 不合理的索引設計與使用

    當查詢的docsExamined(文檔掃描條數)關鍵字超過1000且執行頻率較高時,需關注對應查詢。除全表掃描外,其他導致docsExamined過多的情況如下:

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

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

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

並發過大

業務請求量過⼤,並發過⾼也會導致CPU佔用高。針對此問題,如果確認查詢層面沒有問題,一般通過添加CPU核心數的⽅式解決。

其他原因

  • 頻繁短串連。MongoDB 3.X後使用的預設的身份認證機制是SCRAM-SHA1,需要進⾏⼀些CPU密集型操作,⽐如雜湊計算等。在⾼並發的短串連情境下,這些雜湊計算占⽤的CPU將會被放⼤很多倍,進⽽耗盡整個機器的CPU資源。其中⼀個現象是在運⾏⽇志中可以發現⼤量包含saslStart的報錯資訊。阿⾥雲MongoDB在PHP⾼並發短串連情境做了⼀定程度的最佳化,通過在核心層⾯最佳化改寫內建的隨機函數的⽅式⼤幅降低了MongoDB執行個體CPU使⽤率。

  • TTL索引導致從節點(Secondary)CPU使用率高於主節點(Primary)CPU使用率。如果遇到這種情況,建議您直接忽略。

    自MongoDB 3.2開始實現了多線程複製,Oplog日誌的回放並發度由參數replWriterThreadCount控制,預設為16。所以儘管Secondary節點不承載任何業務寫,在部分情境下CPU使⽤率也可能會超過Primary節點。例如,在Primary節點上針對某⼀張表設定了TTL到期⾃動刪除,在Primary節點上,系統會根據時間列的索引大量刪除資料,效率很⾼,同時會將該操作轉換成很多單條的Delete操作發送給Secondary節點;在Secondary節點上,回放Oplog日誌時效率較低,所以在多線程回放的情況下容易引起該節點CPU升⾼。

排查方法

查看和Kill活躍會話

正常運行中的MongoDB執行個體會話突然飆升至100%,絕⼤部分情況是業務側的變化引起,可能是由於掃描行數過多、資料排序和彙總、業務流量突增等原因導致的。您可以通過以下方法排查:

  • MongoDB管理主控台CloudDBA > 執行個體會話頁面查看當前執行的活躍會話。分析不符合預期執行時間的查詢操作,可以選擇Kill活躍會話或者其他方法解決該問題。

  • 通過MongoDB⾃帶的命令db.currentOp()查看和分析更加詳細的活躍會話執行情況。如果需要,可以通過命令db.killOp()主動Kill⾮預期內的慢查詢。詳情請參見db.currentOp()db.killOp()

記錄和查看日誌

當CPU使用率異常上升時,可以通過慢日誌或審計日誌深入分析異常請求。通過檢查COLLSCANdocsExamined等關鍵字,進一步確認是否存在掃描行數過多的情況。

  • 審計日誌

    MongoDB管理主控台資料安全性 > 審計日誌頁面開通並查看審計⽇志。關於審計⽇志的開通與使用方法,請參見開通日誌審計功能

  • 慢日誌

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

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

    1. MongoDB管理主控台參數設定 > 參數列表頁面,根據業務需求設定operationProfiling.mode(慢查詢的模式)和operationProfiling.slowOpThresholdMs(慢查詢的閾值)。

      MongoDB在profiling上共有3種設定模式:

      • 關閉profiling,即不記錄任何請求。

      • 針對所有請求開啟profiling,即將所有請求的執⾏都記錄到system.profile集合。

      • 慢查詢profiling,將超過⼀定閾值的請求,記錄到system.profile集合。

      關於profiling相關參數含義及更多資訊,請參見:Database Profiler

    2. 日誌管理 > 慢日誌中查看慢日誌。

最佳化策略

最佳化索引

索引最佳化是減少MongoDB單個查詢掃描行數的最優⽅案。從底層設計上,MongoDB的索引設計原理幾乎與MySQL保持一致(或許種類和功能更豐富一些),所以適用於MySQL的索引最佳化策略基本也都適用於 MongoDB執行個體。

關於索引的建立與使用方式,請參見ApsaraDB for MongoDB建立索引最佳實務,或以下官方文檔:

添加CPU核心數

如果確認查詢層⾯沒有問題,CPU佔用高是由於業務請求量過⼤、並發過⾼所導致,可以通過添加CPU核心數的⽅式解決。⼀般有如下⽅法:

  • 單一實例垂直配置升降級,使得單一實例能夠承載更多的讀寫量。

  • 配置複本集層面的讀寫分離,或者添加該副本的唯讀執行個體。

  • 升級至MongoDB分區叢集,通過資料水平分割的方式橫向,線性擴充系統效能。

  • 如果是Mongos路由節點CPU佔滿,則直接添加Mongos節點個數並設定Mongos節點的負載平衡,關於Mongos節點負載平衡的說明,請參見負載平衡

ApsaraDB for MongoDB配置變更的更多資訊,請參見變更單節點執行個體配置變更複本集執行個體配置變更分區叢集執行個體配置

控製表的數量和執行頻率

針對全表掃描的問題,優先通過添加索引的方式最佳化,如果已無法通過此方式最佳化,建議在業務側控製表的資料量和執行頻率。

避免頻繁短串連

建議您儘可能使⽤⻓串連。