【Redis】key过期清除策略

引入

一个单实例Redis服务器最多能支持 2^32 个key,差不多就是 2.5个亿 。那么是不是说,我们可以无限制的向缓存中加入key呢?

显然不能。容量的瓶颈不在于Redis本身,而在于内存。这正是我们需要给key设置过期时间并清除的原因。

 
 

定时删除

定时删除就是在设置key的过期时间的同时,为该key创建一个定时器(timer)。定时器会察觉到key过期,并触发立即删除动作。

除了算法简单,这种删除策略只有一个好处——保证过期key快速被删除,立即释放内存。

但是,这种删除策略对CPU极其不友好。首先,计时器是一直在跑的,在Redis服务器中创建大量的计时器是不现实的;其次,对于当前正在处理的任务,删除key的动作无疑是一种浪费。Redis服务器应该优先处理当前客户发来的请求,而不是一心二用,老想着删除过期key这码事。

 
 

惰性删除

惰性删除是一种消极的删除策略,平时放任key不管,只在每次获取key时,检查该key是否过期。

与定时删除不同,该策略对CPU非常友好。体会一下,该策略只会在非做不可的情况下才会删除过期key,而不会在平时花费任何CPU时间去处理过期key的问题。

但是,惰性删除对内存极不友好。这很显然,当某个key过期后,它仍旧保留在内存中;更坏的情况下,该key永远不会再被访问,则该key永远不会被删除。这会导致大量无用数据占用内存。

 
 

定期删除

定期删除就是每隔一段时间,对Redis数据进行一次检查,并删除检测到的过期key。

定期删除是定时删除和惰性删除的折中处理方案,它又想兼顾CPU,又想兼顾内存。
 
该策略的重要难点在于,如何确定删除动作的时长和频率:

1)如果删除动作的时长过长或频率过高,定期删除策略会退化为定时删除策略,浪费CPU时间在与当前任务无关的删除过期key上面;

2)如果删除动作的时长过短或频率过低,定期删除策略就会和惰性删除策略一样,留有大量无用key占用内存造成浪费。
 
Redis官方文档提供了一种朴素的定期删除思路:

1)每隔10秒随机抽20个key进行检测;

2)删除其中的所有过期key;

3)如果有多余25%的key过期,则重复步骤(1)

 
 
 

补充:集群的时钟不同步导致的key过期混乱问题

集群中的所有Redis实例的时钟必须一致,否则会导致下面这种有趣可怕的现象:

在一台实例上,我们设置所有key的过期时间为1000s,然后我们把另一台实例的计算机时间设置为未来2000s。当我们把RDB文件同步过去的时候,会发现所有的key都立即失效了!!!

如何解决呢?利用 ntp(网络时间协议) 的ntpdate命令可轻易实现集群时钟的同步。

 
 

补充:主从复制中的过期key删除问题

首先,slave不能让任何key过期,只能等待master让key过期。具体的实现是,当master中的一个key过期,便会自动合成一个针对该key的del命令,并将该命令发送给slave。

但是,del命令可能没有及时到来,slave中就会出现逻辑上(实际上)已经过期但没来得及删除的key。这时,slave会使用独自的逻辑时钟来声明该key不存在。

在lua脚本执行期间master阻塞的,所以不会触发任何key过期事件。换句话说,lua脚本执行时,master概念上的时间是停滞的、冻结的。这可以防止key在脚本中间过期,保证将相同的脚本发送到slave,从而在二者的数据集中产生相同的效果。

 
 

补充:设置key过期时间的相关命令

expire key ttl设置key的生存时间为ttl秒
pexpire key ttl设置key的生存时间为ttl毫秒
expireat key timestamp设置key在timestamp秒时刻过期
pexpireat key timestamp设置key在timestamp毫秒时刻过期
persist key移除key的过期时间

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

☘️ 玩转Redis专题!

🍄 不来博客里瞧一瞧吗

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值