机器配置
系统:CentOS6.7
配置:4C8G
应用:Redis Cluster,实例化
现象
1、无法启动redis,启动后系统OOM,直接杀死
2、Redis: OOM command not allowed when used memory > ‘maxmemory’
原因
内存已满,不允许数据在写入
注:
used_memory_human表示已用内存
used_memory_rss表示系统给redis分配的内存(即常驻内存)
mem_fragmentation_ratio=used_memory_rss/used_memory比例,一般情况下,used_memory_rss略高于used_memory,当内存碎片较多时,则mem_fragmentation_ratio会较大,可以反映内存碎片是否很多
解决过程
1、首先查看redis的内存使用,如上图。可以看到已用内存5G多,常驻内存3.8G多。而我们的机器内存只有8G可用。明显内存已经充爆。接下来想到的就应该是key的量太大了还是value的量太大了。
2、找出redis中的key。
###查看key的个数(最好是把key拿出来分析)
keys *
echo "keys *" |/usr/local/redis/bin/redis-cli -p 6381 > /tmp/6381.log
3、分析发现key中有650000的common:order:LogCacheKey这样的key,接下来我们需要确认下这些key的大小
###查看key大小的命令
debug object
echo 'debug object "common:order:LogCacheKey90bef863-dfc7-4739-8404-9b6624a70196"' |/usr/local/redis/bin/redis-cli -p 6381
4、分析发现common:order:LogCacheKey所占用的内存为3G左右。因此找到元凶为这个key所导致的。
5、清理key
for i in `grep common:order:Log 6381.log`;do echo "del $i" |/usr/local/redis/bin/redis-cli -p 6381; done
6、key已经找到删除,现在要查找是哪个应用产生的。
因为开发人员没在,那从运维角度,我是从网络流量来分析的,使用iftop
根据流量大小,找到对应的主机,联系到开发人员确认。
小技巧
如果key少的话,可以直接取出每个key对应的value的大小,按照从大到小的顺序排序
for i in `cat /tmp/6379.log`;do echo -n "$i "; echo "debug object $i"|/usr/local/redis/bin/redis-cli -p 6379|awk -F '[ |:]+' '{print $9}';done|sort -r -n -k2
总结
1、问题发生后,用最快最简单的方式先把问题解决。减少影响的时间。比如升级扩大内存。
2、此次遇到的问题是在测试环境,如果确认redis中数据可以清除,可以使用暴力的方式直接清空本地的实例化文件,将内存释放出来。但是生产环境切不可进行此操作。