背景
问题起源于生产上应用redis做的一个临时缓存的场景,调用方首先调用某个容器的生成接口,该接口会生成临时缓存的数据放到redis中,然后调用方在调用获取数据内容的接口从任何一台容器中获取放置在redis中的临时数据。
还原问题场景
由于临时数据仅仅只是为了在第二步获取数据内容时从任一个容器都可以访问到,所以临时数据需要删除,因此应用设计了一个单独线程来清理临时redis数据的内容,一开始清理逻辑时判断临时数据放到redis的时间是否已经超过了3S,如果是,那么直接删除,后来,有同事反馈说,我们不能这么删除,因为我们没法保证临时数据在3s内肯定调用方已经调用完获取数据的接口获取到数据,所以保险起见,我们用expire设置过期时间为1s,这样相当于临时数据至少存活4S,更充分的保证调用方已经调用获取数据接口获取到了数据,于是我们的应用这样上线了,但是刚上线没多久,Redis就告警内存不足,于是就有了这次关于expire设置过期时间的工作原理的记录
redis.expire工作原理
expire设置一个很短的过期时间 和 直接delete相比有什么不一样呢? delete能及时回收redis的内存,那么expire为什么不能及时回收内存呢?这里就要讲到了redis是如何清理过期数据的,首先redis会使用惰性删除和定时清理的策略删除过期的key
惰性删除
所谓的惰性删除策略是指当访问redis的某个过期的redis的key时,redis会直接删除过期的key,并回收过期key所占据的内存
定时删除策略
Redis服务器默认每隔100ms过期检查一次数据库,检查的间隔可以通过Redis.conf进行配置,每次过期检查都会执行以下操作
1.首先从所有设置了过期时间的的key集合中随机抽取20个候选的key,判断key是否过期,如果过期,那么就进行删除并且回收内存,并记录下20个候选key中总共有多少个key过期了
2.如果步骤一中过期的key的数量/20个候选key的数量的占比大于25%,那么继续循环删除,否则等待下一轮的循环检查
不过为了防止有大量的key要删除导致的redis卡死,每一轮循环Redis设置了最长的删除流程的上限不超过25ms,超过则等待下一轮检查文章来源:https://www.toymoban.com/news/detail-567704.html
总结
从上述Redis对过期时间的key的清理策略可知,当短时间内有大量的key过期,并且很多是大key时,redis服务器是来不及删除这么多的过期key的,如果此时新的key不断的生成,而过期的key来不及及时删除,此时就可能导致redis内存不足. 那回到一开始的问题,为什么你使用delete直接删除不会导致redis内存问题呢?首先一方面是delete删除可以直接回收内存,而且由于是客户端来进行删除,只有在删除之后才会再次申请新的redis的key,所以相当于也变相的把新key的生成速度降低了,这两者综合导致redis内存并没有被打爆文章来源地址https://www.toymoban.com/news/detail-567704.html
到了这里,关于redis 设置expire=0和直接调用delete删除key的区别的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!