redis内存占用率持续飙升问题处理

生产环境的问题:春节前后,redis内存占用率持续飙升

redis内存占用率持续飙升问题处理_第1张图片


从业务端排查,并没有大量的新增key缓存,但是redis监控上能看到增加了几百万的key。

因为key数量达到了6000万,怀疑是过期key不能及时释放内存导致。

粗暴验证:

在低峰时段执行keys xxxx*命令遍历key,几秒后kill掉命令,发现redis key数量减少了,内存占用也降低了,说明问题原因和猜测的一致。

 

延展问题:

Redis里面如果有大量的key,怎样才能高效的找出过期的key并将其删除呢,难道是遍历每一个key吗(keys命令确实能触发内存释放)?假如同一时期过期的key非常多,Redis会不会因为一直处理过期事件,而导致读写指令的卡顿?

答:

keys *命令确实会阻塞其他命令的执行,导致慢查询。

那Redis是怎么解决的呢?

Redis4.0新增了lazy free特性,从根本上解决Big Key(主要指定元素较多集合类型Key)删除的风险。lazy free可译为惰性删除或延迟释放;当删除键的时候,redis提供异步延时释放key内存的功能,把key释放操作放在bio(Background I/O)单独的子线程(客户端读写操作使用的是另一个线程,除了CPU可能有争抢,两者互不影响)处理中,减少删除big key对redis主线程的阻塞。有效地避免删除big key带来的性能和可用性问题。

Redis使用惰性删除+定期删除相结合的方式处理过期的key。

惰性删除

所谓懒惰删除就是在客户端访问一个key的时候,redis会对key的过期时间进行检查,如果过期了就立即删除。

优点:不会占用太多的额外CPU资源,只在访问key的时候检查过期时间并删除。

缺点:如果一个过期的key长时间没有被访问,那这个key就会一直存留在内存之中,占用内存资源。

定期删除

定期删除的原理是,Redis会将所有设置了过期时间的key放入一个字典中,然后每隔一段时间从字典中随机取一些key检查过期时间并删除已过期的key。

Redis默认每秒进行10次过期扫描:

从过期字典中随机20个key

删除这20个key中已过期的

如果超过25%的key过期,则重复第一步

同时,为了保证不出现循环过度的情况,Redis还设置了扫描的时间上限,默认不会超过25ms。

既然是随机访问key,能保证所有的过期key都被访问到吗?

redis删除过期key的算法_深入理解Redis的内存回收机制_许吴倩的博客-CSDN博客

redis内存占用率持续飙升问题处理_第2张图片

参考:

定期删除功能源码

https://github.com/redis/redis/blob/23325c135f08365d1b7d4bf4fb1c9187fc7374b9/src/expire.c

定期删除功能源码解读

Redis源码剖析之数据过期(expire) - xindoo - 博客园

回到生产问题

让过期key及时释放内存的正确姿势

hz参数

The frequency at which Redis background tasks are performed. A higher value results in higher CPU consumption but smaller latency. We recommend that you do not specify a value larger than 100.

Redis 后台任务的执行频率。 较高的值会导致较高的 CPU 消耗但较小的延迟。 建议您不要指定大于 100 的值。

hz值每次调整增加30或40,观察CPU使用率、内存使用率、key数量变化情况、P99执行时延

因为缓存key非常多,约6000万左右,逐步增大hz到250左右,才有比较明显的效果。

修改后,cpu使用率仍然2%,P99执行时延保持不变,每分钟key过期数不再增加,说明再加大hz,已经没什么用了。

此时,key总数量和内存使用率已经在稳步下降了,问题得到解决!

redis内存占用率持续飙升问题处理_第3张图片

redis内存占用率持续飙升问题处理_第4张图片

你可能感兴趣的:(数据库,redis,缓存,数据库)