Redis过期key是否立马被删除?

Redis过期key是否立马被删除?

答案是不会,Redis处理过期key主要有两种方式:

  • 惰性删除(客户端侧)
  • 定期随机删除(服务端侧)

惰性删除

当客户端请求查询时,判断当前key已过期,则会删除该key,删除key的主动权交给每次访问的请求。

弊端:只能处理还会访问的key,无法对一些不再会被访问的key进行删除。

该实现通过expiredIfNeeded函数实现,源码路径:src/db.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int expireIfNeeded(redisDb *db, robj *key, int force_delete_expired) {
// key 没有过期,return 0
if (!keyIsExpired(db,key)) return 0;
if (server.masterhost != NULL) {
if (server.current_client == server.master) return 0;
if (!force_delete_expired) return 1;
}

if (checkClientPauseTimeoutAndReturnIfPaused()) return 1;

/* Delete the key */
deleteExpiredKeyAndPropagate(db,key);
return 1;
}

定期删除

对于一些key过期后不再被访问,惰性删除永远无法对其进行删除,这会导致已过期的key不断积压,因此仅靠客户端侧的处理是不够的。

  • 如何让处理“占着茅坑不拉屎”的key?

服务端进行定期删除,顾名思义就是Redis默认每100 ms 执行一次,随机抽取一些设置了过期时间的key,判断是否过期,如发现已过期就直接删除。

注意:并不是检查所有key,而是随机抽取一定数量的key

具体步骤如下:

该过程通过activeExpireCycle函数实现,源码路径:src/expire.c

  • 为什么不检查所有设置过期时间的key?

Redis中存放了数以万计的key,如果每隔100 ms 就要轮询检查所有设置过期时间的key,会非常耗费CPU

  • 删除如何做到主从同步?

不论是惰性删除还是定期删除,当进行删除时,master会将删除指令记录到AOFslave节点

如果过期数据太多,定时删除无法完全删除(每次删除完过期的key还是超过25%),同时这些key再也不会被客户端请求,即也无法通过惰性删除,该如何解决?

答:内存淘汰机制