redis过期删除策略

4 篇文章 0 订阅
3 篇文章 0 订阅

tips:

  Redis提供了四个命令来设置过期时间(生存时间)。

  ①、EXPIRE <key> <ttl> :表示将键 key 的生存时间设置为 ttl 秒。

  ②、PEXPIRE <key> <ttl> :表示将键 key 的生存时间设置为 ttl 毫秒。

  ③、EXPIREAT <key> <timestamp> :表示将键 key 的生存时间设置为 timestamp 所指定的秒数时间戳。

  ④、PEXPIREAT <key> <timestamp> :表示将键 key 的生存时间设置为 timestamp 所指定的毫秒数时间戳。

  PS:在Redis内部实现中,前面三个设置过期时间的命令最后都会转换成最后一个PEXPIREAT 命令来完成。

  另外补充两个知识点:

  一、移除键的过期时间

  PERSIST <key> :表示将key的过期时间移除。

  二、返回键的剩余生存时间

  TTL <key> :以秒的单位返回键 key 的剩余生存时间。

  PTTL <key> :以毫秒的单位返回键 key 的剩余生存时间

假如你的redis中存在有10w个key,这时有大量的key是设置了过期时间的,当key的过期时间到了之后,有以下几个问题:

1.redis是如何淘汰这些过期的数据的?

        首先我们需要知道redis获取一个key时,对过期时间的判定:

在Redis内部,每当我们设置一个键的过期时间时,Redis就会将该键带上过期时间存放到一个过期字典中。当我们查询一个键时,Redis便首先检查该键是否存在过期字典中,如果存在,那就获取其过期时间。然后将过期时间和当前系统时间进行比对,比系统时间大,那就没有过期;反之判定该键过期

        redis过期时删除数据得方式有三种:定期删除与惰性删除

        1.定期删除

        redis默认每隔100ms,就会随机抽取一些设置了过期时间的key,检查其是否过期,过期就删除,注意这里是随机抽取一部分,不是全部。因为如果redis中存在大量key时,比如10w个,这时不可能去检查所有的key,严重影响性能,cpu压力巨大。所以只是抽取部分key。正因为如此,会导致部分key过期了,但没有被随机抽取到。这时候就需要惰性删除进行补充,这也是redis设计时同时除了定期删除,还有惰性删除的原因。

        2.定时删除

        当我们设置一个key到redis时,用一个定时器来负责监视key,当这个key过期就自动删除,虽然内存及时释放,但是十分消耗CPU资源,在大并发请求下CPU要尽可能的把时间都用在处理请求,而不是删除key,定时删除能保证内存中数据的最大新鲜度,因为它保证过期键值会在过期后马上被删除,其所占用的内存也会随之释放。但是立即删除对cpu是最不友好的。因为删除操作会占用cpu的时间,如果刚好碰上了cpu很忙的时候,比如正在做交集或排序等计算的时候,就会给cpu造成额外的压力,一般情况下不会使用。

        3.惰性删除

        惰性删除是指当我们获取某个key的时候,再临时检查该key是否过期,过期则删除。惰性删除的缺点也很明显,就是如果一些key使用频率低,那么它可能长时间存在内存中,占用大量内存

redis使用的过期删除策略是:惰性删除+定期删除。使用这两种结合能很大程度上提高优化redis性能,降低冗余。但还是会有问题,假如定期删除刚好没有删除掉某些过期key,而且这些key又没有使用,这时候就不会触发惰性删除,这些key将长时间存在内存中,占用大量内存,这时候就需要使用内存淘汰机制处理掉这些key.

2.设置完一个键的过期时间后,到了这个时间,这个键还能获取到么?假如获取不到那这个键还占据着内存吗?

        答案是到了时间这个key是获取不到的,但是这个key有可能还占据着内存。redis采用的定期删除+惰性删除的过期策略,会导致某些key躲过了定期删除,并且在未使用时,不会发生惰性删除,而长时间滞留在内存中。

3.redis的内存淘汰机制

        redis可以配置内存淘汰策略,具体实现可以了解下LRU算法,根据自己项目的实际情况使用:
1)noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。(应该没人用吧)。
2)allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key。推荐使用,目前项目在用这种,这种用的最多。

        例如:有3个key,a最近10分钟使用了100次,b最近10分钟使用的50次,c最近一小时使用了1次。那么会淘汰掉c
3)allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个key。应该也没人用吧,你不删最少使用Key,去随机删。
4)volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的key。这种情况一般是把redis既当缓存,又做持久化存储的时候才用。不推荐
5)volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个key。依然不推荐
6)volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的key优先移除。不推荐
ps:如果没有设置 expire 的key, 不满足先决条件(prerequisites); 那么 volatile-lru, volatile-random 和 volatile-ttl 策略的行为, 和 noeviction(不删除) 基本上一致。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值