問題背景
前幾天突然收到Redis內存超標的報警,趕緊看了下監控,看到這個曲線吸了一口涼氣,這增長速度也太快了,需要快速定位出問題,不然就要爆了。
這個Redis由多個應用共享,我們就有2個問題需要解決:
- 首先要找出是哪個應用在占用Redis內存;
- 其次是到底是某個key值太大,還是數量太多引起的?
為解答這2個問題,首先通過redis-cli進入redis看看,立馬發現對這2個問題基本束手無策,這里面總共有20W以上的鍵,不太可能一個個過過去,redis-cli本身也不支持按大小對key值排序,也不支持對鍵值分組統計,我們需要換個思路。看看有沒有第三方的Redis內存分析工具。經過一番搜索,最終找到了一個完全滿足要求又易用的工具——Redis Insight,我也同時對比了其他純命令行工具,比如redis-rdb-tools,RMA等等,但是發現執行速度慢很多,結果也不直觀。
下面我們看下使用Redis Insight如何解決這個問題。
使用Redis Insight定位問題
由於是線上環境,Redis端口正常是不會開放的,有條件的直接連接從庫做分析是最快的。沒條件的,一般先Redis緩存備份,導出為rdb文件,然后導入到本地的redis。連接以后,直接找到下圖的Memory Analysis,使用離線分析或者在線分析都行,開始分析以后等結果就行了。
等待分析完成后,直接進到Keyspace Summary
,先確定是哪個應用在占用Redis內存。一般來說,不同應用會使用不同的命名空間,因此根據命名空間可以確定出具體是哪個應用在占用內存。如下圖所示,第1個占了6.45GB,顯然就是這個應用了。第1個問題解決了。
進入到該命名空間內部,看下它的具體鍵值情況按內存分布的情況,最大的是55M,離6.3G還遠着。這時注意到3~4MB的鍵比較多,這個不太正常,正常應用都不會存這么大的,於是統計了下1M以上的鍵值,有幾千個,差不多就是占用了6G多,所以既不是某個鍵值特別大,也不是小空間的鍵數特別多引起的,而是空間占用偏大的鍵數量多導致的。接着挑幾個具體的鍵,看下它們的鍵的具體內容是什么特征。其中一個鍵的內容如下:
經過推測,應該是應用的Session。又抽了幾個,都是相同的內容,可以斷定應該是應用的Session存儲了不合理的信息,於是去應用那邊結合代碼排查,果然是存在這個問題。代碼調整后,這個問題就消失了。
參考文檔
《redis使用rdb文件恢復數據》
《怎么分析和優化Redis的內存使用率》
《the-top-6-free-redis-memory-analysis-tools》