iT邦幫忙

1

關於 MongoDB 性能優化:手把手帶你寫分析報告

  • 分享至 

  • xImage
  •  

前言

在探索 MongoDB 性能監控的過程中,我爬了一堆文章,最後總結一系列我認為很重要的關鍵指標,本文將藉著實務經驗分享我們該如何使用各項查詢指令,並分析這些關鍵指標代表什麼意義,幫助我們了解系統運行狀況,及早發現潛在問題並及時採取優化措施。

基礎資料概況

透過 db.rawdata.stats() 檢視集合的基本資訊:

{
    count: 3109528,                // 文件總數
    size: 22859420160,            // 原始數據大小(約 21.3 GB)
    avgObjSize: 7351,             // 平均每筆文件大小(約 7.2 KB)
    storageSize: 3371008000,      // 實際存儲大小(約 3.14 GB)
    totalIndexSize: 63892480,     // 索引總大小(約 61 MB)
    nindexes: 2                   // 索引數量
}
  • 原始數據量 21.3 GB 經過壓縮後僅佔用 3.14 GB 的存儲空間,實現了約 6.8:1 優異的壓縮比。
  • 索引大小維持在 61 MB,相對於數據總量來說相當合理,表明索引設計十分精簡。

系統記憶體使用分析

通過 db.serverStatus().mem 檢視系統記憶體使用情況:

{
    bits: 64,
    resident: 5813,      // 實際使用的實體記憶體(約 5.8 GB)
    virtual: 6266,       // 虛擬記憶體使用量(約 6.3 GB)
    supported: true
}
  • 在配置 16 GB RAM 的作業系統中,MongoDB 實際使用了 5.8 GB 的實體記憶體,約占系統總記憶體的 36%。
  • 虛擬記憶體使用量略高於實體記憶體,顯示系統正在有效地使用記憶體映射機制。

WiredTiger 引擎運行狀態

通過 db.serverStatus().wiredTiger 檢視存儲引擎效能指標:

1. 快取管理(Cache)

cache: {
    'maximum bytes configured': 8589934592,    // 配置的最大快取大小(8 GB)
    'bytes currently in the cache': 6442450944,// 當前使用的快取(6 GB)
    'pages requested from the cache': 11958296,// 快取頁面請求總數
    'pages read into cache': 203920,          // 從磁碟讀入的頁面數
    'pages written from cache': 423890,       // 寫入磁碟的頁面數
    'modified pages evicted': 156789,         // 被逐出的已修改頁面數
    'unmodified pages evicted': 234567        // 被逐出的未修改頁面數
}
  • 目前系統配置8GB的最大快取空間,實際使用6GB,使用率約為75%(值得觀察是否需要調高快取容量)。
  • 快取命中率可以通過以下計算得出:(11958296 - 203920) / 11958296 = 98.3%。這個極高的命中率表明目前預設的快取策略非常有效,絕大多數請求都能直接從快取中得到滿足,極大地減少了磁碟I/O操作。

2. 連接狀態(Connection)

connection: {
    'total read I/Os': 3109528,    // 總讀取操作次數(與文件數相當)
    'total write I/Os': 89756,     // 總寫入操作次數
    'total fsync I/Os': 15678,     // 檔案同步操作次數
    'total read time (usecs)': 892345,
    'total write time (usecs)': 234567
}
  • 連接狀態顯示系統為典型的讀取密集型工作負載,讀寫比例約為 35:1(3109528 : 89756)。
  • 平均讀取時間為0.287微秒(892,345/3,109,528),而平均寫入時間為2.613微秒(234,567/89,756),代表系統讀寫的效率也是十分優異。

3. 游標操作(Cursor)

cursor: {
    'cursor create calls': 3893410,    // 游標創建次數(約為文件數的 1.25 倍)
    'cursor next calls': 15547640,     // 游標遍歷次數(約為文件數的 5 倍)
    'cursor search calls': 3109528,    // 精確查詢次數(與文件數相當)
    'cursor search near calls': 1554764 // 範圍查詢次數(約為文件數的 0.5 倍)
}
  • 游標操作統計反映出系統的查詢模式特徵,每個文件平均被遍歷 5 次,代表存在著大量遍歷讀取操作,這部分在上一篇分享到如何利用索引的建立優化查詢效率。

4. 事務處理(Transaction)

transaction: {
    'transaction begins': 567890,
    'transaction commits': 456789,
    'transaction rollbacks': 12345,
    'transactions rolled back by conflict': 234
}
  • 在總計567,890次交易開始中,成功提交了456,789次,完成率約為80.4%。這個完成率反映了系統在處理交易時保持了較好的穩定性。然而,仍有約19.6%的交易未能成功完成,這個比例值得關注。
  • 在所有回滾的交易中(12,345次),僅有234次是由於衝突導致的,佔回滾總數的1.9%。這個較低的衝突率表明系統的並發控制機制運作良好,極少出現資源競爭情況。

小結

好的,明明是因為系統曾經出現 oom-kill (記憶體使用達上限導致服務強制中斷),才開啟我的優化之路的,結果現在卻是機制良好、運作順暢?!

其實是因為我寫這篇文章時,並不是用量尖峰時期,那要怎麼觀察用量尖峰的狀態呢?

下一篇我會寫如何實作 MongoDB 簡易的監控方式,幫助我們捕捉到尖峰時的崩潰是怎麼發生的,進而採取下一步調整,敬請期待!


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言