疑難排解效能為 Databases for MongoDB

使用本指南可幫助您找出並解決在 IBM Cloud 上執行並由 MongoDB 供電的 Databases for MongoDB 部署中的效能問題。

您也可以從下列方式找到更多關於解決效能問題的資訊:

如果您的應用程式遇到回應緩慢、逾時或資料庫效能不一致的問題,請考慮下列步驟和資訊。

效能問題的症狀

您可能會觀察到下列一些顯示效能問題的症狀:

  • 增加應用程式延遲
  • 緩慢的查詢記錄項目
  • CPU 或記憶體使用率過高
  • 增加磁碟延遲
  • 抄寫延遲
  • 連線逾時值

完成下列步驟以確定問題的原因:

步驟 1:檢查資源利用率

  1. 登入 IBM Cloud 主控台並導覽您的 MongoDB 部署。

  2. 檢視「監測」部分,以瞭解

    • CPU 使用率
    • 記憶體用量
    • 磁碟 IOPS 與延遲
    • 作用中連線

需要注意的事項:

  • CPU 持續在 75% 以上
  • 記憶體持續高於 80
  • 磁碟延遲隨時間增加
  • 接近計劃限額的連接

建議採取的行動:

  • 如果磁碟延遲很高,請增加儲存空間或 IOPS。
  • 檢視應用程式中的工作量峰值。

如果資源使用量持續偏高,建議進行擴充。

步驟 2:識別緩慢的查詢

查詢速度慢是導致效能下降的最常見原因之一。

  1. 啟用剖析:

    db.setProfilingLevel(1, { slowms: 100 })
    
  2. 檢視近期緩慢的作業:

    db.system.profile.find().sort({ ts: -1 }).limit(20)
    
  3. 分析查詢執行:

    db.collection.find({ ... }).explain("executionStats")
    

需要注意的事項:

  • COLLSCAN (以集合掃描取代索引使用)
  • totalDocsExamined 相比 nReturned

建議採取的行動:

  • 建立適當的索引。
  • 使用複合索引進行多欄位查詢。
  • 確保聚合管道以 $match 開始。
  • 避免使用大型 skip() 分頁。

步驟 3:檢視連線使用情況

過高或管理不善的連接會影響效能。

檢查連線統計資料:

db.serverStatus().connections

建議採取的行動:

  • 在您的應用程式中使用連線池。
  • 避免為每個請求開啟新連線。
  • 關閉未使用的游標。

連線限制由您的部署方案決定。

步驟 4:檢查複製狀況

複製滯後會影響讀取效能和資料新鮮度。

檢查複製狀態:

rs.printSecondaryReplicationInfo()

造成滯後的常見原因:

  • 高寫入吞吐量
  • 磁碟瓶頸
  • 網路延遲

建議採取的行動:

  • 擴充儲存效能。
  • 檢閱寫入關注設定。
  • 如果滯後情況持續,請擴充至更高的方案。

步驟 5:分片群集考量(如適用)

在下列情況下,您可能需要分片:

  • 工作集大於 RAM
  • 單節點 IOPS 在擴充後仍達到最大值
  • 需要水平寫入縮放
  • 收藏量超過 1-2 TB

如需詳細資訊,請參閱 效能調整分片

如果您的部署使用分片,請執行:

sh.status()

檢查:

  • 不均勻的區塊分佈
  • 特大塊
  • 流量集中在單一碎片上

建議採取的行動:

  • 檢閱分片金鑰選擇。
  • 避免單調增加分片金鑰。
  • 考慮散列分塊金鑰。

不當的分片金鑰選擇會大幅影響規模擴充時的效能。

步驟 6:刪除大量資料後

刪除相當比例的資料不會立即減少作業系統層級的磁碟使用量。

可能的影響:

  • 內部分割
  • 磁碟使用率高
  • 效能降低

建議採取的行動:

  • 仔細規劃壓實作業。
  • 對於嚴重的磁碟分割,可考慮轉存和還原。
  • 將磁碟使用率維持在 80-85% 以下。

適當安排維護活動。

步驟 7:檢查鎖的爭用

鎖爭用會嚴重影響並行作業和整體吞吐量。

  • 檢查全局鎖統計資料:

    db.serverStatus().locks
    
  • 檢查目前的操作是否有鎖:

    db.currentOp({
      $or: [
        { waitingForLock: true },
        { "locks.Global": "w" }
      ]
    })
    
  • 分析鎖等待時間:

    db.serverStatus().globalLock
    

需要注意的事項:

  • currentQueue 值(讀者或作家)。
  • 使用 waitingForLock: true 執行作業。
  • 長時間執行的作業持有鎖。
  • 阻擋作業的索引建立。

常見原因:

  • 沒有適當索引的長時間執行查詢。
  • 大型寫入作業。
  • 索引建立在大型集合上。
  • 管理命令 (精簡、repairDatabase )。

建議採取的行動:

  • 必要時,關閉長時間執行的作業:
    db.killOp(opid)
    
  • 在背景中建立索引:
    db.collection.createIndex({ field: 1 }, { background: true })
    
  • 將大型作業分成較小的批次。
  • 將維護作業安排在交通流量低的時段。
  • 適當地使用讀取關注和寫入關注。

步驟 8:分析工作量模式

瞭解您的工作量模式有助於找出最佳化機會。

  • 檢查操作計數器:

    db.serverStatus().opcounters
    
  • 分析隨時間推移的作業:

    db.serverStatus().opcountersRepl
    
  • 識別熱門系列:

    db.adminCommand({ top: 1 })
    
  • 檢查讀取比率與寫入比率的比較:

    var stats = db.serverStatus().opcounters;
    print("Read ratio: " + (stats.query + stats.getmore) / (stats.query + stats.getmore + stats.insert + stats.update + stats.delete));
    

需要注意的事項:

  • 對特定藏品進行不成比例的作業
  • 高讀寫比或寫入比
  • 操作次數突然激增
  • 以時間為基礎的模式(繁忙時間)

建議採取的行動:

  • 首先優化經常存取的收藏集。
  • 針對讀取繁重的工作負載,考慮使用讀取複製。
  • 使用適當的讀取偏好設定。
  • 對經常讀取的資料實施快取。
  • 檢視熱門收藏集的索引策略。
  • 對於寫入繁重的集合,請考慮分片。

步驟 9:調查記憶體壓力和快取效能

MongoDB's WiredTiger 儲存引擎非常依賴快取記憶體的效率。

  • 檢查 WiredTiger 快取統計資料:

    db.serverStatus().wiredTiger.cache
    
  • 檢閱關鍵指標:

    var cache = db.serverStatus().wiredTiger.cache;
    print("Cache size: " + cache["bytes currently in the cache"]);
    print("Max cache size: " + cache["maximum bytes configured"]);
    print("Pages read into cache: " + cache["pages read into cache"]);
    print("Pages written from cache: " + cache["pages written from cache"]);
    print("Cache hit ratio: " + (1 - cache["pages read into cache"] / (cache["pages read into cache"] + cache["pages requested from the cache"])));
    
  • 檢查驅逐壓力:

    db.serverStatus().wiredTiger.cache["pages evicted by application threads"]
    

需要注意的事項:

  • 快取記憶體命中率低於 95
  • 高驅逐率
  • 快取記憶體大小一直維持在最大值
  • 執行驅逐的應用程式線程

估計工作集大小:

db.serverStatus().wiredTiger.cache["tracked dirty bytes in the cache"]

建議採取的行動:

  • 如果快取記憶體持續已滿,就擴充到記憶體更多的計劃。
  • 檢閱和最佳化索引 (移除不使用的索引)。
  • 限制查詢結果集的大小。
  • 使用投影縮小文件大小。
  • 考慮將舊資料歸檔。
  • 監控工作集大小趨勢。

記憶體分配最佳實務

  • WiredTiger 快取應該是可用 RAM 的 50% (預設值)。
  • 為其他程序留足記憶體。
  • 監控交換使用量,應將其減至最低。

步驟 10:檢視寫入關注和讀取偏好設定

寫入關注和讀取偏好設定會顯著影響效能和一致性。

  • 檢查目前寫入的關注事項:

    db.getWriteConcern()
    
  • 檢查複製集組態:

    rs.conf()
    
  • 寫入關注選項:

    寫入關注選項
    書面關注 延續性 效能 使用案例
    w: 1 非關鍵資料、高吞吐量
    w: "majority" 預設、平衡的方法
    w: <number> 中-高 中低 特定複製次數
    j: true 最高 最低 需要日誌同步的重要資料
  • 閱讀偏好選項:

    閱讀偏好選項
    閱讀偏好 一致性 效能 使用案例
    primary 最高 預設,強一致性
    primaryPreferred 中-高 回退至次級
    secondary 最終 分析、報告
    secondaryPreferred 最終 閱讀縮放
    nearest 最終 最高 最低延遲
  • 勾選申請中的讀取偏好:

    // Example in Node.js driver
    db.collection('users').find({}).readPreference('secondary')
    

需要注意的事項:

  • 對於非關鍵資料的寫入關注過於嚴格
  • 當最終一致性可接受時,使用 primary 讀取偏好設定
  • 未針對讀取繁重的工作負載利用輔助程式

建議採取的行動:

  • w: 1 用於高吞吐量、非關鍵寫入。
  • 重要資料使用 w: "majority" (預設值)。
  • 使用 secondarysecondaryPreferred 進行分析查詢。
  • 考慮 nearest 用於地理分散的應用程式。
  • 平衡一致性要求與效能需求。
  • 在負載下測試不同的配置。

步驟 11:監控備份和維護的影響

備份作業和維護任務會暫時影響效能。

IBM Cloud 備份排程

Databases for MongoDB 自動執行備份。 在 IBM Cloud 主控台的 Backups 下檢查您的備份排程。

檢查正在進行的備份作業:

db.currentOp({
  $or: [
    { op: "command", "command.backup": { $exists: true } },
    { desc: /^conn/ }
  ]
})

需要注意的事項:

  • 備份視窗期間效能下降
  • 備份期間磁碟 I/O 增加
  • 備份期間的複製滯後

建議採取的行動:

  • 在備份期間監控效能指標。
  • 如果備份持續影響效能,請考慮擴充。
  • 檢閱備份保留政策。
  • 規劃還原作業期間增加的資源使用量。

維護作業最佳實務

  • 在低流量時段安排指數建立。
  • 盡可能使用背景索引建立。
  • 在維護期間監控複製滯後。
  • 先在非生產中測試維護作業。
  • 與 IBM Cloud 維護窗口協調。