DAY22 MongoDB Profiler 幾個指令抓拖垮系統的元兇
Profiler 查詢推薦指令
1 | db.system.profile.find() |
一般我們不會這樣做,因為資訊又多又難閱讀,可以加上一些查詢條件。
例如 limit(x)
或者指定某些操作 op
等等。
以下直接推薦我常在使用的指令:
直接找出最慢的
利用執行時間、倒序來找出最慢的幾個。
為了方便閱讀也加入.limit()
、.pretty()
語法,後面就不贅述。
1 | db.system.profile.find().sort({ millis: -1 }).limit(5).pretty(); |
利用操作類別查詢
如果你確定慢的 op 是什麼,也可以針對 op 直接排序。
1 | db.system.profile.find({"op":"query"}).sort({ millis: -1 }); |
查詢是否有 COLLSCAN
1 | db.system.profile.find({"planSummary": "COLLSCAN"}); |
利用發生時間來查詢
有設定好最低可接受的執行時間門檻的話,可以用這個方法定期檢查是否有新增慢的查詢。
1 | db.system.profile.find().sort({ ts: -1 }); |
查詢特定時間區
1 | db.system.profile.find({ |
查詢特定Collection
1 | db.system.profile.find({ ns: 'target.collection' }); |
查找過多文件的查詢
1 | db.system.profile.find({ docsExamined: { $gt : 10000 }}).sort({ ts: -1 }); |
profile size
profile 在系統是有預設 1 Mb 的大小,如果要改變,必須先關閉、刪除現有 profile、重建最後重新開起。因此強烈建議在服務開啟之前就先決定好。
指令如下:
1 |
|
心得
其實在查找效能低落的操作,會用到的指令大概就是這些了,蠻考驗的是對各個參數的熟悉度。
第一階段是了解各個參數,第二階段是定期自動化取得 profile 內容,第三階段是配合自定義的規則來告警,要做到自動化還是需要時間與資源的投入。
問題爆發通常是在線上環境,但你敢在線上環境開profiler嗎?
如果在開發階段就開著 profiler,執行測試後都有回報其結果,就能減少不該存在的操作一路上到正式環境。(舉個最簡單例子,定期察看是否有 Collection scan 就幫助很大了)
有的人反對開 profiler 會慢,但會慢多少?開著 level 1 也有過濾雜訊的功能,我再測試了一下影響並不顯著,況且開發環境從來就不是效能測試的地方,另外就是它是存在 capped collection
,實在不用太擔心效能影響劇烈的狀況。
以上我說的是正式營運環境之前,建議可以開。