当前位置:网站首页>一次生产环境redis内存占用居高不下问题排查

一次生产环境redis内存占用居高不下问题排查

2022-07-05 11:31:00 我们一直在路上

服务器在一次常规发布上线后,发现缓存过期速度远远小于配置的10min过期。

现象:刚刚登录进系统后台,过了1分钟就发现缓存过期,登录不上后台,进到阿里云的redis服务器,发现登录的key没有了,期间还遇到各种诡异的问题,莫名其妙登录进系统但过一会儿掉线,后来进入阿里云后台发现redis内存占用高达100%。我就猜到可能是有线程在大量的写缓存,然后把redis空间给吃满了,由于redis服务器配置的是volatile-lru策略:当内存要满的时候,又有大量缓存写入的时候,就删除设置了过期时间的key中的最近最久没有用的key。

然后我就跑到redis服务器把当前的rdb(内存快照) 下载一份到本地来分析到底是那个key 在疯狂写数据,找到了这个key,我就可以去程序中查找到使用这个key的代码,然后进行相应的处理。

登录进阿里云,下到到一个最新的备份

1、下载到一份全量key的rdb文件

然后执行以下命令需要安装python2.7并且加载rdb插件,生成csv文档。

 2、将此rdb文件使用rdbTools转化成csv文档。


    
     
  1. pip install rdb # 安装rdb
  2. rdb -c memory hins8714399_data_20191015223705.rdb > memory.csv # 将redis内存快照文件,存储到csv文档中

3、将改csv文档直接可以导入到mysql数据库中,然后使用mysql的查询,可以查询出内存占用最大的key 

 

注意一点的是 通过csv导入mysql默认生成字段类型都是varchar,我们这里需要把类型改为int类型,用于排序查询。

 4、mysql中生成了一个memory库,然后执行

SELECT * from memory ORDER BY size_in_bytes desc LIMIT 0, 10
    
     

按照使用内存从大到小,查询到占用内存前10的key 

找到了这些过期时间为null的key,发现 代码中没有针对这些key设置过期时间,是永久key,还有一些redis设置的队列进行消费的队列,写了大量的数据到永不过期的队列中,然后消费线程只有2个,倒是往队列加的快,队列消费的慢,后台我把消费redis队列的线程调成20、10、5找到一个最佳的线程数,CPU占用不太高,队列也没有堆积、充分利用了机器的性能,解决了实际需求。

总结:通过一番折腾,学会了如果解析redis的rdb快照文件,分析redis内存分布,内存占用,那个key占得多,那个key占得少,还有内存淘汰策略,为什么这个key要先过期,另一个要后过期。

 

扩展1:有兴趣的同学可以查看更多的redis内存淘汰策略

  • volatile-lru:从已设置过期时间的内存数据集中挑选最近最少使用的数据 淘汰;
  • volatile-ttl: 从已设置过期时间的内存数据集中挑选即将过期的数据 淘汰;
  • volatile-random:从已设置过期时间的内存数据集中任意挑选数据 淘汰;
  • allkeys-lru:从内存数据集中挑选最近最少使用的数据 淘汰;
  • allkeys-random:从数据集中任意挑选数据 淘汰;
  • no-enviction(驱逐):禁止驱逐数据。(默认淘汰策略。当redis内存数据达到maxmemory,在该策略下,直接返回OOM错误);
    关于maxmemory设置,通过在redis.conf中maxmemory参数设置,或者通过命令CONFIG SET动态修改
    关于数据淘汰策略的设置,通过在redis.conf中的maxmemory-policy参数设置,或者通过命令CONFIG SET动态修改
</article>
原网站

版权声明
本文为[我们一直在路上]所创,转载请带上原文链接,感谢
https://blog.csdn.net/weixin_40980639/article/details/125572682