问题现象
现场运维人员持续收到监控预警,redis内存爆满,已超过10GB了,而且呈现持续增长却无降低趋势。正常情况,由于数据的定期清理以及数据消费,redis内存占用应为波浪形,维持在固定水平趋势上
故障处理
- 1.首先查看下redis内存占用情况内存使用情况果然如监控中所看到的,已经有10GB以上
- 2.使用redis-cli —bigkeys扫描一下
从bigkeys来看,只能看出有些SET类型的数据,members过多,看名字应该是spring维持的session过期相关key
- 3.尝试看一个set的大小,来计算下大概的内存占用smembers "spring:session:expirations:1599544020000"
从上图来看,一个member大概占用59bytes,通过bigkeys统计数据来看,一个只有4万多个members,这里算出来也就只有2.4MB内存占用
- 4.只能找第三方工具进行扫描了,rdstools(https://github.com/sripathikrishnan/redis-rdb-tools)应该是star较多的一个了,我们来体验下。为了不影响正式服务,将rdb文件传到测试服务器,在测试服务器上进行分析
pip install rdbtools python-lzfrdb -c memory ./dump.rdb --bytes 128 -f memory.csv
安装过程有个小插曲
从名字来看应该就是缺少python-dev包,centos这里yum install python-devel即可解决
- 5.分析memory.csv先通过命令来看看,我们找出最大的前10个key,由于key中存在特殊字符(序列化后的Java对象作为key)导致文本无法完全解析,但也大致看出了是哪些key
直接通过wps来看csv文件吧。这里排序后发现,有个list有1187万个元素,单个元素大小861B,总大小达到了恐怖的9.67GB
- 6.经过分析,此业务为最近更新,消费端未能正确连接到reis导致数据在redis中持续堆积。为了不影响正常使用,先把它删除掉,之后内存恢复正常
总结
- rdbtools实在是好用,能很快分析出内存占用情况。
- 业务上尽量不要用序列化后的对象作为redis中的key,虽然代码中使用不存在问题,但是对运维人员不友好,分析问题时增加了分析耗时。