目錄
比奇**網
mongodb 提供了非常強大的效能分析及監控的命令,諸如 mongostat、mongotop 可以讓我們對資料庫的執行態效能瞭如指掌。
然而,這次我們在效能環境上就遇到乙個非常棘手的問題:
某服務介面在 1-5分鐘內偶現超時導致業務失敗!
在介面呼叫上返回超時屬於前端的判斷,通常是設定的乙個閾值(比如 3s)。
由於問題是偶現,且沒辦法發現有明顯的規律,很難直接判斷出原因。
而平台在做了微服務拆分之後,問題定位的難度加大了不少,且當前的呼叫鏈功能也不夠完善。
業務診斷
在一番分析後,梳理出介面呼叫的關係圖如下:
其中,服務a 通過 rpc呼叫服務b的介面,而服務b 又通過 mongodb 進行資料讀寫。
mongomanager 是 用於管理 mongodb 的乙個**服務,主要是實現一些資料備份、監控的任務。
在採集了一些資料之後,我們基本把問題範圍鎖定到了 mongodb 資料庫上面,這些手段包括:
從介面監控及 wiredshark 抓包結果中確認到,db 操作的響應時間都出現了偶現的超長(3s以上)。
而通過 commandlistener 將慢操作輸出統計後,得到的圖表如下:
其中典型的慢操作語句如:
query:
update: }
然而,這些慢操作並沒有明顯的問題嫌疑,除了以寫操作為主之外,索引的命中也沒有問題。
資料庫診斷
接下來,我們將焦點集中到了資料庫上,檢查了 cpu、記憶體、網路、磁碟這些常規指標後並沒有發現什麼異常。
通過mongostat觀察到的如下圖:
圖- mongostat
其中的乙個異常點是netout 會有偶現的積壓情況。
然後是嘗試通過db.currentop()這個命令來看看能不能揪出慢操作背後的元凶。
currentop 還是比較好用的,尤其是在定位一些長時間慢操作問題上然而,我的想法落空了,這個辦法並沒有任何發現! 因為問題屬於偶現,所以執行currentop 需要一些好的運氣..
儘管如此,我們還是大概能判定,在出現慢操作的時候,資料庫出現了命令積壓(卡頓)的情況
"可能存在某個定時器的鎖,對業務操作產生了阻塞!"
那麼,鎖從**來? 我們將目光移向了 mongomanager,的確這個程式承載了許多管理上的功能,包括監控、備份、公升級這些瑣事..
其中,執行資料庫資訊採集的監控定時器存在最大的嫌疑!,那麼問題又來了,
"如果是定時器導致的卡頓,為什麼慢操作卻沒有定時產生的規律呢?"
這個問題在前面也對我們產生了很大的困擾,但乙個比較合理的解釋是:
"mongomanager 是多節點的,而其中定時器是按照 時間間隔來運作的,而不是整點觸發。"
這樣就能解釋,為什麼慢操作通常都是在1-5分鐘內不規律的出現了。
為了證實這個想法,我們直接將 mongomanager 逐個關閉到僅剩下乙個,最終通過commandlistener收集到的慢操作圖表如下:
看,這次的慢操作非常的規律,基本每5分鐘就會出現一次卡頓!
然後我們將全部的 mongomanager 關閉,業務的慢操作完全消失了。
經過前面的問題定位,我們已經能確定是mongomanager的定時器搞的鬼了。
接下來走讀**,發現有下面這樣的一段實現:
為了便於理解,上述的**做了比較多的簡化,大致的步驟是:public void testdboperation()
if (allcollections.isempty())
//test a random collection
string randomcollection = allcollections.get((int) (allcollections.size() * math.random()));
//issue find operation
database.getcollection(randomcollection).find().first();
} catch (exception e)
}
上述的**由定時器在5分鐘觸發一次,跟出現慢操作的條件是吻合的。
其中 listcollections 會獲取到乙個集合的列表,我們猜測,這個操作可能會阻塞資料庫的操作。
通過搜尋官方文件,我們發現該操作使用了乙個共享讀鎖(s):
圖-listcollection鎖
mongodb 鎖機制
為了說明阻塞的產生,這裡需要解釋下mongodb的鎖機制:
在資料庫內部有下面這幾種鎖:
意向鎖提供了資料庫系統的"多粒度鎖"的能力,是提公升併發能力的關鍵手段, wiredtiger 也是基於此來實現行級鎖的。
幾種鎖的互斥關係如下表所示:
鎖型別sxis
ixstf
tfxf
fffis
tftt
ixfft
t 基於此,我們可以得出這樣的結論:
由定時器產生 的 listcollections 操作會對資料庫產生讀鎖(s),從而對文件寫操作(資料庫的意向寫鎖ix)產生了阻塞。
那麼,listcollections 從監控的意義上來看是不應該對資料庫產生阻塞的。
我們認為這應該是mongodb 3.4版本乙個bug,而server-34243 這裡提交的乙個issue已經得到解決。
在最新的 4.x版本文件中,可以發現 listcollections 的許可權已經變更成了 意向讀鎖(is)。
通過 4.0 版本的 releasenotes 可以確認這點:
在了解了事情的來龍去脈之後,我們可以確定這是 mongodb 3.4 版本的乙個不嚴謹的實現導致的問題。the command listcollections takes intent shared lock on the database.
in previous versions, the command takes shared lock on the database.
由於無法直接公升級整個資料庫版本(代價太大), 我們在監控程式上做了優化,即將 listcollections 結果進行了快取,避免定時器每次都去操作這個命令,而問題最終得到了解決。
"監控不是銀彈,濫用也會有坑",至少從這次的事件中,我們得到了乙個教訓!
而要在這個問題上舉一反三的話,那就是需要警惕一些資料庫操作潛在的鎖問題了,比如:
以上的這些事情,你 get 到了嗎?
是什麼造成了資料庫的卡頓
目錄 宣告 本文同步發表於 mongodb 中文社群,傳送門 mongodb 提供了非常強大的效能分析及監控的命令,諸如 mongostat mongotop 可以讓我們對 資料庫的執行態效能瞭如指掌。然而,這次我們在效能環境上就遇到乙個非常棘手的問題 某服務介面在 1 5分鐘內偶現超時導致業務失敗...
是什麼造成了資料庫的卡頓
目錄宣告 本文同步發表於 mongodb 中文社群,傳送門 mongodb 提供了非常強大的效能分析及監控的命令,諸如 mongostat mongotop 可以讓我們對資料庫的執行態效能瞭如指掌。然而,這次我們在效能環境上就遇到乙個非常棘手的問題 某服務介面在 1 5分鐘內偶現超時導致業務失敗!在...
是什麼造成了資料庫的卡頓
目錄 三 找出元凶 四 解決思路 宣告 本文同步發表於 mongodb 中文社群,傳送門 mongodb 提供了非常強大的效能分析及監控的命令,諸如 mongostat mongotop 可以讓我們對資料庫的執行態效能瞭如指掌。然而,這次我們在效能環境上就遇到乙個非常棘手的問題 某服務介面在 1 5...