一次Redis內存飆升的排查

一、現象

在該項目中,多個微服務使用一臺Redis虛擬機,項目開發完成後,進入試運行階段,在項目平穩運行五天後,Redis使用的虛擬機內存在某一時刻突然飆升,很短的時間內內存耗盡,Redis虛擬機宕機,所有微服務連接Redis超時無法使用。
異常圖片

二、問題排查

  1. 懷疑在某一時刻出現大量寫入數據導致內存飆升。我們的業務存到redis的數據量幾乎是可以預估的,應該向之前一樣平穩,除非對方公司突然增加很多合作方,但是並沒有這樣的情況。爲了確認不是這個原因所導致的,我們查看了Redis的Info,看到Redis使用的峯值也才5Mb左右,所以應該不是這個原因導致的。
  2. Redis連接未釋放,導致大量連接耗盡內存。我們設置的連接池最大連接數爲1000,根據我們的業務場景幾乎是不可能耗盡的。第一次排查時,因爲對方公司重啓了Redis服務器,所以沒法看到宕機時的連接數,但是一直也想不到其他原因。第二次出現該問題時通過Redis Manager看了Redis連接數,果然是連接數達到了1000左右的問題。

三、問題產生根本原因

我們定位到了問題產生原因爲連接增加耗盡了內存,接下來我們要從代碼中分析是什麼原因導致了連接數的持續增加。

  1. 高併發導致,我們的Redis操作都是在線程池管理的線程中進行,線程池最大線程數也就20,幾個微服務加起來也不超過200,故排除
  2. 使用後沒有釋放連接,我們使用RedisTemplate進行redis操作,應該用完會釋放。唯一需要手動釋放的地方,是在一個Redis工具類中使用了Redis的事務支持,所以定位問題應該出現在這裏。

在這裏插入圖片描述
由於團隊內是共享該工具類的,如果幾個微服務同時出現該問題,連接數能夠立刻飆升。

四、解決方案

在網上也看到很多人在使用多線程進行Redis事務操作時也出現了該類問題,他們給出的解決方案是增加線程池大小。但是我覺得並不能實質性的解決問題。我覺得如果要使用保證事務性的化可以考慮使用Lua腳本,將事務操作都放在腳本中進行(在看分佈式鎖實現時學來的)。
對我們這個項目來說,其實這段代碼是沒有任何意義的,這段事務中僅有一個操作而已,也不太清楚寫這段代碼小夥伴的用途。
最後,我們將這段代碼的事務支持取消了,Redis就沒有再出現該問題。

五、總結

對於我來說,這也是第一次在分佈式環境中排查該類問題,也是剛學Redis而已,不過和師兄一起解決這個問題的過程,受益匪淺。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章