Redis的过期策略有哪些?内存淘汰机制都有哪些?

问题起因

公司同学之前问了一个问题,说我们生产环境中怎么经常会丢一些数据?写进去,过一会可能就没了。我惊讶了一下,同学,你问这个问题说明redis你没用对呀。redis是缓存 你可能当存储了吧。

什么是缓存

用内存当缓存,内存是无限的么,内存空间是很宝贵而且是有限的,磁盘是廉价而且是大量的。可能一台机器就几十个g的内存,但是可以有几T的磁盘空间。redis主要是基于内存来进行高性能,高并发的读写操作的。
那么既然内存是有限的,比如redis就只能用10个g,你要是往里面写20个g的数据,会咋办?当然是干掉10个g的数据,然后就保留10个g的数据了,那干掉那些数据?保留那些数据?当然是保留常用的数据,干掉不常用的数据了
所以说,这是一个缓存最基本的概念了,数据会过期的,要么是你自己设置个过期时间,要么是redis自己给干掉。
set key value(1 小时)
set进去的key 1个小时之后就没了,就失效了。

我的数据明明都过期了,怎么还占着内存

还有一种就是如果你设置好了一个过期时间,你知道rdis是怎么给你弄成过期的么?什么时候删掉?如果你不知道,之前有个同学问过了为啥好多数据明明应该过期了,结果redis的内存占用还是很高?那是因为你不知道redis是如何删除那些过期的key的。
redis内存一共是10g的内存,你现在往里面写了5g的数据,结果这些数据明明你都设置了过期时间,要求这些数据一小时之后过期结果一小时以后你回来一看redis机器 怎么内存占用还是50%呢?5g数据过期了,我从redis里面查,是查不到了,,结果过期的数据还占用这redis的内存

解决方案

1)设置过期时间
我们set key的时候 都可以给一个expire time,就是过期时间,指定这个key比如说还能存活 1小时 ?10分钟?这个很有用,我们自己可以指定缓存到期就失效。
如果你设置一个一批key只能存活一小时,那么接下里一个小时以后 redis是怎么对这批key进行删除的。
这里采用的是定期删除+惰性删除的方式

什么是定期删除 和 惰性删除

所谓定期删除,指的是redis默认是每隔100ms就随机抽取一些设置了过期时间的key 检查其是否已经过期了。如果过期就删除。假设redis里放了10万个key,都设置了过期时间,你每隔几百毫秒,就检查10万个key那么redis基本就死了,cpu负载会非常的高,消耗在你检查的key上。注意这里可不是每隔100ms就遍历所有设置了过期时间的key,那样就是一场性能上的灾难。实际上redis每隔100ms就随机抽取一些key来检查和删除的。
但是问题是定期删除会导致很多过期key到时间并没有被删除掉,那咋整呢?所以就是惰性删除了这就是说 在你获取某个key的时候redis会检查一下,这个key如果设置了过期时间那么是否过期了?如果过期了此时就会删除,不会返回任何东西
并不是key到时间就会被删除掉,而是你查询这个key的时候,redis在懒惰的检查一下。
通过上述两种手段结合起来,保证过期的key一定会被干掉。
很简单,就是说,你的过期key,靠定期删除并没有被删除掉,还停留在内存里占用这你的内存,除非你的系统去检查那个key,才会被redis给删除掉
但是实际上这还是有问题的,如果定期删除漏掉了很多过期的key然后你也没及时去查,也就没有走惰性删除,此时会怎么样?如果大量过期的key堆积在内存里,导致redis内存块耗尽了咋整?
**解决方案 走内存淘汰机制

内存淘汰

如果redis内存占用过多的时候,此时会进行内存淘汰,有如下一些策略
redis10个key 现在已经满了redis 需要删除掉5个key
**
1个key最近1分钟被查询了100次
1个key最近10分钟被查询了50次
1个key最近1个小时被查询了1次
**
1)noeviction:当内存不足以容纳新写入的数据时,新写入操作会报错(这个一般不怎么用)
2)allkeys-lru:当内存不足以容纳新写入的数据时,在键空间中,移除最近最少使用的key(这个常用)
3)allkeys-random:当内存不足以容纳新写入的数据时,在键空间中,随机移除某个key (这个一般不怎么用)
4)volatile-lru:当内存不足以容纳新写入的数据时,在设置了过期时间的键空间中,移除最近最少使用的key (这个一般不用)
5)volatile-random:当内存不足以容纳新写入的数据时,在设置了过期时间的键空间中,随机移除某个key
6)volatile-ttl:当内存不足以容纳新写入的数据时,在键空间中,有更早过期时间的key优先移除。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章