面试必问:Redis 过期删除与内存淘汰策略,看完这篇就够了
目录
过期删除策略和内存淘汰策略有什么区别?
过期删除策略:删除过期的键值内容,redis采用的是惰性删除+过期删除
惰性删除:Redis 不会主动去扫描并删除已过期的键,而是在客户端访问这个键的时候(比如读 / 写操作),才会先调用
expireIfNeeded检查它是否过期。如果已经过期,就执行删除(同步或异步,取决于配置),然后返回null;如果没过期,就正常处理请求。
内存淘汰策略:是内存满了的时候redis触发的策略,来淘汰一些不必要的内存资源,腾出空间,保存新的内容
介绍一下Redis 内存淘汰策略
32位的操作系统中maxmemory最大是3GB内存,因32位机器最大支持4GB的内存资源, 加上操作系统本身占用的内存资源,3GB是最大可用内存,这样样可以防止redis实例因内存不足而崩溃
内存淘汰策略分为8种,细分为不进行数据淘汰与进行数据淘汰

不进行数据淘汰
neoviction:即在运行内存超过设置的最大内存时,不删除键值、而是返回错误不能新增,但是删除和查询还是可以的
进行数据淘汰策略
分为为「在设置了过期时间的数据中进行淘汰」和「在所有数据范围内进行淘汰」
在设置了过期时间的数据中进行淘汰
volatile-random:随机淘汰设置了过期时间的键值
volatitle-ttl:优先淘汰更早过期的键值
volatile-lfu(least frequently used):淘汰最小频率的使用的键值
volatitle-lru(least recently used):淘汰最近使用的使用最少的,就是最久未用的
在所有数据范围内进行淘汰
allkeys-random:所有数据进行随机淘汰
allkeys-lfu:所有数据里淘汰使用频率最小的键值
allkeys-lru:所有数据里淘汰最久未用的键值
介绍一下Redis过期删除策略
redis采用惰性删除+定期删除策略,以求在合理使用cpu和内存资源之间做平衡
惰性删除
惰性删除策略由db.c文件实现:
int expireIfNeeded(redisDb *db, robj *key) {
// 判断 key 是否过期
if (!keyIsExpired(db,key)) return 0;
....
/* 删除过期键 */
....
// 如果 server.lazyfree_lazy_expire 为 1 表示异步删除,反之同步删除;
return server.lazyfree_lazy_expire ? dbAsyncDelete(db,key) :
dbSyncDelete(db,key);
}
每次redis访问key或修改之前,都会用expireIfNeeded检测是否过期
若过期了,就删除这个key,异步/同步删除key根据lazyfree_lazy_expire的参数配置决定(redis4.0开始提供参数)
同步删除:就是删除key之后再给前端返回null,但是如果key的值过于大可能就会响应很慢
异步删除:标记这个值,先给前端返回null,再在后台慢慢删除key

定期删除
定期删除是一段时间随机抽查一定数量的key,看是否过期,过期就删除
一段时间是多久
在redis里默认是hz 10 ,也就是每秒十次检查key,时间可以在redis.conf里面配置修改,需要注意的是,key不是全量检测,而是随机性抽查部分key
抽查多少key
定期删除的代码实现在expire.c里面,代码里的方法写死了为20个key每次
定期删除流程
1.先随机抽查20个key
2.检测是否有过期的key,过期则删除
3.过期的key如果数量超过了4,也就是20个的25%,则会再次抽查,直到过期的数量少于25%为止
过期删除为了防止陷入循环过度,设置了循环最大时长,默认为25ms。
伪代码如下:
do {
//已过期的数量
expired = 0;
//随机抽取的数量
num = 20;
while (num--) {
//1. 从过期字典中随机抽取 1 个 key
//2. 判断该 key 是否过期,如果已过期则进行删除,同时对 expired++
}
// 超过时间限制则退出
if (timelimit_exit) return;
/* 如果本轮检查的已过期 key 的数量,超过 25%,则继续随机抽查,否则退出本轮检查 */
} while (expired > 20/4);
流程如下

Redis的缓存失效会不会立即删除?
不会,redis删除采用惰性删除+定期删除策略
惰性删除:缓存过期后不会主动删除,而是访问时判断是否过期之后再删除
定期删除:一段时间后抽查key是否过期,过期则删除
那为什么我不过期立即删除?
如果过期的key比较多 ,删除key就需要消耗cpu大量时间,如果在内存充足而cpu时间比较紧张的情况下,cpu时间用在的删除过期key和无关的任务上,会严重拖慢服务器响应速度,降低系统吞吐量,所以立即删除并不友好
更多推荐




所有评论(0)