redis缓存删除策略及重大隐患

本文深入探讨Redis的缓存删除策略,包括被动删除与主动删除机制。解析了过期键的处理方式,如volatile-lru、volatile-lfu等,并讨论了主动删除策略的周期性随机测试过程及其潜在隐患。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

redis缓存删除策略及重大隐患

Redis对于过期键有三种清除策略:

被动删除:当读/写一个已经过期的key时,会触发惰性删除策略,直接删除掉这个过期key
注:被动删除:只有key被操作时(如GET),REDIS才会被动检查该key是否过期,如果过期则删除之并且返回NIL。

主动删除:由于惰性删除策略无法保证冷数据被及时删掉,所以Redis会定期主动淘汰一批已过期的key
当前已用内存超过maxmemory限定时,触发主动清理策略,策略包含以下几种:
1.volatile-lru(least recently used):最近最少使用算法,从设置了过期时间的键中选择空转时间最长的键值对清除掉;

2.volatile-lfu(least frequently used):最近最不经常使用算法,从设置了过期时间的键中选择某段时间之内使用频次最小的键值对清除掉;

3.volatile-ttl:从设置了过期时间的键中选择过期时间最早的键值对清除;

4.volatile-random:从设置了过期时间的键中,随机选择键进行清除;

5.allkeys-lru:最近最少使用算法,从所有的键中选择空转时间最长的键值对清除;

6.allkeys-lfu:最近最不经常使用算法,从所有的键中选择某段时间之内使用频次最少的键值对清除;

7.allkeys-random:所有的键中,随机选择键进行删除;

8.noeviction:不做任何的清理工作,在redis的内存超过限制之后,所有的写入操作都会返回错误;但是读操作都能正常的进行;

前缀为volatile-和allkeys-的区别在于二者选择要清除的键时的字典不同,volatile-前缀的策略代表从redisDb中的expire字典中选择键进行清除;allkeys-开头的策略代表从dict字典中选择键进行清除。

主动删除

Redis会周期性的随机测试一批设置了过期时间的key并进行处理。测试到的已过期的key将被删除。典型的方式为,Redis每秒做10次如下的步骤:

随机测试100个设置了过期时间的key
删除所有发现的已过期的key
若删除的key超过25个则重复步骤1 注:这里的意思是这一秒内会重复第一个步骤,如果没有超过25个那就不去重复步骤1,就意味着有900毫秒处于空转,要等到下一秒才会去重复步骤1。
这是一个基于概率的简单算法,基本的假设是抽出的样本能够代表整个key空间,redis持续清理过期的数据直至将要过期的key的百分比降到了25%以下。这也意味着在任何给定的时刻已经过期但仍占据着内存空间的key的量最多为每秒的写操作量除以4。

Redis-3.0.0中的默认值是10,代表每秒钟调用10次后台任务。

除了主动淘汰的频率外,Redis对每次淘汰任务执行的最大时长也有一个限定,这样保证了每次主动淘汰不会过多阻塞应用请求。

实验一:验证主动删除

数据库db254

常驻key:300 过期时间48小时

临时key: 30 过期时间10秒

查看key总量:dbsize

~/real_scripts/redis_batch_import.sh now 10 254

查看主动删除过程:
在这里插入图片描述

实验二:验证惰性删除暴露主动删除的缺陷

数据库db255

常驻key:3000000 过期时间48小时

临时key:300 过期时间5秒

步骤一:演示惰性删除

查看key总量

dbsize

查看常驻key的过期时长(单位秒)

ttl names1

触发惰性删除

set aa bb ex 10

10秒后

get aa
在这里插入图片描述

步骤二:暴露主动删除策略缺陷

插入300个临时key

~/real_scripts/redis_batch_import.sh now 100 255

查看key总量

dbsize

等待十秒再次查看key总量

dbsize

触发临时key 惰性删除

get nownamess1

查看key总量

dbsize

超过10秒通过统计发现过期的key 还没有被回收仍然占据内存,当我们通过访问这个key时,再次进行统计发现这个key已经被回收,触发了惰性删除策略。为什么过了10秒key仍然没有被回收,难道主动删除策略没有起作用吗,其实不是详见如下分析:

主动删除的缺陷如下:

每秒随机抽样100个理想情况下大概需要 3000000÷100=30000÷3600= 8.333333小时才能将总体全部抽样完成,也就是说当常驻key远远大于临时key时redis主动删除策略需要花费大量时间进行随机抽样,才能达到主动删除的目的。

这里会存在一个非常大的隐患,如果在这8小时内,继续有大key 涌入,就很可能造成内存穿透,引发key随机丢失的情况。

比如涌入70000个key(每个key 为147KB):147 × 70000÷1024÷1024 = 9.81GB

如果涌入14万个以上的key那么我们需要预留20GB 的内存空间才能保证不引发内存穿透。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值