Redis内存占用过大如何分析?
问题背景
前几天突然收到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》