redis内存溢出排查

1、背景
早上收到“系统登录接口异常”、“redis服务器内存利用率过高” ,结合来看怀疑redis导致登录功能异常

2、排查过程
tail -f /var/log/redis/redis-server.log
发现内存溢出报错

29258:M 08 Aug 2024 12:35:00.123 # Warning: memory over the limit
29258:M 08 Aug 2024 12:35:00.123 # Error: memory limit exceeded, write operation denied

redis-cli info memory

used_memory_human:7.7G
maxmemory_human:7.8G

那现在已经是实锤redis溢出了,看下是啥占用了那么多,查看占内存比较高的键

redis-cli --bigkeys

-------- summary -------

Sampled 12000000 keys in the keyspace!

redis-cli --bigkeys输出会显示最大占用内存的字符串key、set key、及hash key是啥,分别占了多少字节跟其他信息。但是最大那个key也不过几十M,不可能是某个key造成的,有可能是某种情况引发了百万级别的key创建塞满了redis内存

redis-cli keys “*” > /data/redis-key.log

把所有键名都导出来,发现大部分都是这种“f30a0485-b59f-4939-a41d-3955786b37e0”格式的键名,我恍然大悟,这是创建的会话id啊。

开发反馈会话id过期时间设置了两天,难道会话过期时间设置没生效,导致会话记录一直积在redis里面导致溢出?为了验证我的想法,我得去看下那些现有会话的存活时长有没有超过两天

1、把key的过期时间导出
cat /data/redis-key-100000.log | xargs -I key redis-cli ttl key > /data/key_ttl.log
2、过滤过期时间超过2天的key
cat /data/key_ttl.log | awk '{if($0 > 172800) print $0}'

结果一条都没过滤到,证明过期时间设置没有问题

既然过期时间设置没问题,就看创建出了什么问题,我随便拿了一个会话id的key,打印出它的值

redis-cli get 'f30a0485-b59f-4939-a41d-3955786b37e0'

具体结构就不展示了,但我得到了一个重要信息,这会话里面没有存有会话信息跟业务信息,只存了几个可有可无的值;我纳闷了,会话里不应该存登录信息用户信息啥的吗,为啥用户信息都是空的,这也能创建一个会话啊?证明没有登录就可以创建会话?为了验证我的想法,我去实验了一下:

打开我测试环境的项目,事先清了redis相关记录,我打开页面,没有登录,我立马回去看redis信息,它果真给我创建了一个会话。。。。。我这算是彻底知道咋回事了,肯定有人刷我们的网站,导致会话不断给创建。

后知后觉的我打开的nginx 的访问日志,发现有大量的IP在访问我们的网站

awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr

3、解决方案
1) bug修改
经过盘查,发现会话是egg的一个插件egg-seesion-redis自动创建的,只要请求来的没带我们规定的会话key键,而且有数据要写入(不管写入内容是啥,即便为空),就会立马给你创建一个会话,但是这不是我想要的结果,我想要的是登录后再创建会话

2)nginx IP封禁、限制ip每秒访问频率

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Redis 是一个开源的键值存储数据库,它在内存中操作数据,以提供极快的读写速度。如果 Redis 的内存使用超过了其自身的物理内存限制,可能会导致严重的性能问题甚至系统崩溃。这种情况被称为"内存溢出"或"Out of Memory (OOM)"。 当 Redis 内存溢出时,可能发生的现象包括: 1. **缓存失效**:Redis 无法在内存中容纳新的数据,可能导致缓存中的数据被丢弃,影响服务的响应速度。 2. **客户端连接断开**:为了释放内存资源,Redis 可能会主动断开客户端的连接,或者在达到某些设置的限制时,拒绝新连接。 3. **性能下降**:随着内存占用越来越多,Redis 的处理能力会显著降低,查询和操作的响应时间延长。 4. **系统级警告**:操作系统通常会有相应的告警机制,显示内存使用过高,提醒管理员介入。 5. **强制重启**:在严重情况下,Redis 或者宿主机可能会因为内存耗尽而强制重启,导致数据丢失或服务中断。 为避免 Redis 内存溢出,你可以采取以下措施: - **定期监控内存使用**:使用 Redis 的内置监控工具或第三方工具监控 Redis 的内存使用情况。 - **配置合适的内存限制**:调整 Redis 的 maxmemory、maxmemory-policy 等参数,以适应实际需求和硬件资源。 - **设置合理的内存分解策略**:例如,使用 volatile-lru 或 volatile-ttl 来自动删除旧数据,减少内存占用。 - **使用持久化机制**:定期将内存中的数据写入磁盘,以便在重启时恢复数据。 - **合理扩展硬件**:增加物理内存,或者优化服务器资源分配。 如果你正在处理这样的问题,具体解决方法可能需要根据你的 Redis 配置和实际情况来定制。如果有进一步的问题,请告诉我。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值