MongoDB 效能瓶頸分析
阿新 • • 發佈:2019-02-05
一、前情簡介
半個月前,公司的MongoDB壓力由於使用者量暴增導致壓力急劇增加,讀寫能力下降。
因為對於Mongos 的叢集分片機制的瞭解和測試還不是很充分,所以開始使用最簡單的辦法來解決:提高配置。
眾所周知,MongoDB是出了名的吃記憶體。當時定義出來提高MongoDB的辦法很簡單,插記憶體。
但是由於機房問題,插記憶體需要拔電源,導致停止產品的服務,所以經過研究後。
用我們備用的R710 64GB記憶體伺服器來替代線上的R410 32GB記憶體的伺服器。
二、操作方式
(1)首先是確認防火牆,埠是否開放,MongoDB1.82升級2.02安裝成功,所有操作在內網進行。
(2)使用Rsync將R410伺服器的MongoDB主庫資料 同步到R710中。
同步結束之後,刪除R710本地Local檔案。以從庫模式啟動,開始同步R410中MongoDB主庫的資料。
在同步延時在1s左右。確認資料及時同步。
(3)在確認資料同步後,切斷所有資料庫Write操作的入口。使MongoDB主庫的資料不再出現變動。
這之後確認從庫的資料已經與主庫完全同步。進入主庫,shutDownServer()。停止主庫服務。
然後進入從庫,shutDownServer。停止從庫服務。
然後再將R710中的從庫以主庫的模式重新啟動。這時同時切換所有訪問資料庫程式的Hosts。使其從R410的主機IP指向到R710的主機IP。這時啟動所有服務。
三、啟動後的驚心動魄
啟動服務之後,MongoDB並沒有像我們想象中的瘋狂的佔用記憶體,起初只是佔用了2.5G左右的記憶體。
使用者在頻繁的訪問資料庫,通過MongoStat觀察到。使用者的QR和QW也就是讀寫佇列不停堆積。Locked值居高不下。
明顯是處理不過來。建立的conn連線數越來越多,導致客戶端頻繁的出發TimeOut。
最後甚至引起了MongoDB鎖死,不再執行任何操作。寫入佇列堆積到20000+。
之後進行查詢,網上說MongoDB2.02 + R710需要在啟動引數中追加numactl --interleave=all 。
經過新增後,鬆了一口氣,因為無效。
之後的幾天頻繁出現問題,MongoDB佔用記憶體最高只打到5GB的熱點資料。
在昨天中午資料庫徹底鎖死宕機。
問題被定位在R710的硬體裝置不相容上。
被迫在白天的時候重新操作了一次之前的工作,將資料庫遷移回R410。
在晚上的時候進行觀測,發現資料依然不夠理想。還是一樣的效果。
之後開始懷疑是因為MongoDB1.82升級到2.02導致的問題,開始查閱資料。但是依然毫無進展。
四、一些效能優化
之後進行Nginx和MongoDB的log觀察。發現每分鐘大概14000的動態請求。而MongoDB的log一直在展示一些可怕的慢查詢,最長的一次竟然有370秒!
MonogoDB有個很坑爹的地方就Auth驗證,我之前的日誌還描述過這個東西,但是沒想到每次建立連線時的密碼驗證竟然成了瓶頸所在。希望大家慎用。可以選擇封閉MongoDB所在主機的外網IP,然後使用內網無密碼訪問最佳。
之後進行伺服器效能優化,在頻繁呼叫的幾個介面緊急使用快取來緩解問題。而一些不重要不需要及時更新的查詢則切換到從庫進行查詢。並切掉了一些需要及時更新的資料介面也訪問從庫,需要mark下資料庫緩解後再調整回去。
經過追查每一個表的索引發現,資料表中有很多冗餘索引,有一些沒有作為索引條件查詢,有一些已經被建為聯合索引,卻依然沒有刪除掉。果斷Drop掉這些Index。
這之後資料的讀寫佇列在300-1000左右,依然是不健康的狀態。
五、再一次定位問題
這之後MongoDB一直在不健康的狀態但是並沒有再一次宕機。不過危險依然存在。
MongoDB的佔用的記憶體熱點資料依然是5GB左右。崩潰了。
定位問題到MongoDB的資料由於不在記憶體中,所以導致讀寫速度障礙。
寫了一段Java程式進行R710資料庫資料迴圈插入,希望能測試出是否可以提高記憶體佔用量。
果然,結果是插入一段時間之後。MongoDB的記憶體佔用已經到達36GB。理想中的結果。
不過線上環境不能隨便插入資料,所以使用python寫了一段全表掃描資料的指令碼執行。
結果竟然無效。
推論是插入會直接放入熱點中,查詢可能是需要經歷一段時間和幾次的命中才會。坑爹。
目前能做的就是等待,等待MongoDB的熱點記憶體佔用提高,才能緩解所有問題。直到Mongos測試OK
六、其實。。最重要的地方在這裡
問題主因就是優化不足,還輕率的進行了資料庫切換。
MongoDB在R410時候執行,所有的熱點資料在記憶體對映Mapping。而R710沒有,需要再規則下重新進行對映。
最坑爹的就是這裡。這段時間需要很久。而資料庫重啟導致使用者重連服務,暴起的連線數和請求數直接壓垮資料庫。
甚至會導致資料庫啟動就宕機的危險。
七、動作要謹慎。Over
半個月前,公司的MongoDB壓力由於使用者量暴增導致壓力急劇增加,讀寫能力下降。
因為對於Mongos 的叢集分片機制的瞭解和測試還不是很充分,所以開始使用最簡單的辦法來解決:提高配置。
眾所周知,MongoDB是出了名的吃記憶體。當時定義出來提高MongoDB的辦法很簡單,插記憶體。
但是由於機房問題,插記憶體需要拔電源,導致停止產品的服務,所以經過研究後。
用我們備用的R710 64GB記憶體伺服器來替代線上的R410 32GB記憶體的伺服器。
二、操作方式
(1)首先是確認防火牆,埠是否開放,MongoDB1.82升級2.02安裝成功,所有操作在內網進行。
(2)使用Rsync將R410伺服器的MongoDB主庫資料
同步結束之後,刪除R710本地Local檔案。以從庫模式啟動,開始同步R410中MongoDB主庫的資料。
在同步延時在1s左右。確認資料及時同步。
(3)在確認資料同步後,切斷所有資料庫Write操作的入口。使MongoDB主庫的資料不再出現變動。
這之後確認從庫的資料已經與主庫完全同步。進入主庫,shutDownServer()。停止主庫服務。
然後進入從庫,shutDownServer。停止從庫服務。
然後再將R710中的從庫以主庫的模式重新啟動。這時同時切換所有訪問資料庫程式的Hosts。使其從R410的主機IP指向到R710的主機IP。這時啟動所有服務。
三、啟動後的驚心動魄
啟動服務之後,MongoDB並沒有像我們想象中的瘋狂的佔用記憶體,起初只是佔用了2.5G左右的記憶體。
使用者在頻繁的訪問資料庫,通過MongoStat觀察到。使用者的QR和QW也就是讀寫佇列不停堆積。Locked值居高不下。
明顯是處理不過來。建立的conn連線數越來越多,導致客戶端頻繁的出發TimeOut。
最後甚至引起了MongoDB鎖死,不再執行任何操作。寫入佇列堆積到20000+。
之後進行查詢,網上說MongoDB2.02 + R710需要在啟動引數中追加numactl --interleave=all 。
經過新增後,鬆了一口氣,因為無效。
之後的幾天頻繁出現問題,MongoDB佔用記憶體最高只打到5GB的熱點資料。
在昨天中午資料庫徹底鎖死宕機。
問題被定位在R710的硬體裝置不相容上。
被迫在白天的時候重新操作了一次之前的工作,將資料庫遷移回R410。
在晚上的時候進行觀測,發現資料依然不夠理想。還是一樣的效果。
之後開始懷疑是因為MongoDB1.82升級到2.02導致的問題,開始查閱資料。但是依然毫無進展。
四、一些效能優化
之後進行Nginx和MongoDB的log觀察。發現每分鐘大概14000的動態請求。而MongoDB的log一直在展示一些可怕的慢查詢,最長的一次竟然有370秒!
MonogoDB有個很坑爹的地方就Auth驗證,我之前的日誌還描述過這個東西,但是沒想到每次建立連線時的密碼驗證竟然成了瓶頸所在。希望大家慎用。可以選擇封閉MongoDB所在主機的外網IP,然後使用內網無密碼訪問最佳。
之後進行伺服器效能優化,在頻繁呼叫的幾個介面緊急使用快取來緩解問題。而一些不重要不需要及時更新的查詢則切換到從庫進行查詢。並切掉了一些需要及時更新的資料介面也訪問從庫,需要mark下資料庫緩解後再調整回去。
經過追查每一個表的索引發現,資料表中有很多冗餘索引,有一些沒有作為索引條件查詢,有一些已經被建為聯合索引,卻依然沒有刪除掉。果斷Drop掉這些Index。
這之後資料的讀寫佇列在300-1000左右,依然是不健康的狀態。
五、再一次定位問題
這之後MongoDB一直在不健康的狀態但是並沒有再一次宕機。不過危險依然存在。
MongoDB的佔用的記憶體熱點資料依然是5GB左右。崩潰了。
定位問題到MongoDB的資料由於不在記憶體中,所以導致讀寫速度障礙。
寫了一段Java程式進行R710資料庫資料迴圈插入,希望能測試出是否可以提高記憶體佔用量。
果然,結果是插入一段時間之後。MongoDB的記憶體佔用已經到達36GB。理想中的結果。
不過線上環境不能隨便插入資料,所以使用python寫了一段全表掃描資料的指令碼執行。
結果竟然無效。
推論是插入會直接放入熱點中,查詢可能是需要經歷一段時間和幾次的命中才會。坑爹。
目前能做的就是等待,等待MongoDB的熱點記憶體佔用提高,才能緩解所有問題。直到Mongos測試OK
六、其實。。最重要的地方在這裡
問題主因就是優化不足,還輕率的進行了資料庫切換。
MongoDB在R410時候執行,所有的熱點資料在記憶體對映Mapping。而R710沒有,需要再規則下重新進行對映。
最坑爹的就是這裡。這段時間需要很久。而資料庫重啟導致使用者重連服務,暴起的連線數和請求數直接壓垮資料庫。
甚至會導致資料庫啟動就宕機的危險。
七、動作要謹慎。Over