欢迎关注微信公众号:互联网全栈架构
号外:今天刷新公众号后台,竟然发现有了留言功能,这个功能可是盼望了好几年了,现在终于拥有了,真是喜出望外,欢迎大家留言讨论啊,感谢!
在Redis中,我们可以设置key的过期时间,比如两个小时,那么在两个小时以后,这些key通过什么方式进行删除?
另外,如果占用的内存达到最大限制以后,Redis如何进行处理?关于这两个问题,本文尝试把它们讲清楚。在面试中,这也是经常会被问到的问题。文章主要包括以下几个部分:
一、设置过期时间
二、过期数据的删除策略
三、内存淘汰策略
在Redis中,有些命令在创建key的时候可以同时设置它的过期时间,比如SET、SETEX:
# 创建key value,并设置key的过期时间
SET key value EX [过期时间]
SETEX key [过期时间] value
同时,所有数据类型的key都可以设置过期时间,通过下面的这几个命令来实现:
EXPIRE key seconds:设置key的过期时间,单位为秒
PEXPIRE key milliseconds:设置key的过期时间,单位为毫秒
EXPIREAT key unix-time-seconds:设置key的过期时间,参数为UNIX时间戳,以秒为单位
PEXPIREAT key unix-time-milliseconds:设置key的过期时间,参数为UNIX时间戳,以毫秒为单位
我们也可以使用ttl命令来查看key的剩余过期时间,它以秒为单位,而pttl也是同样的功能,只不过它以毫秒为单位。
1. 惰性删除:到了过期时间也不做任何处理,只有在访问这个key的时候才对它进行过期检查,如果没有过期,则返回数据;否则删除这个key。配置项lazyfree-lazy-eviction=yes开启惰性删除。
2. 定期删除:每隔一段时间就对一些key进行检查,如果已过期就把它删除,Redis还会限制删除操作的执行时间和频率,从而减少对于CPU的影响。通过参数hz可以设置操作的频率,比如配置hz 10,表示每秒会进行10次扫描,官方建议不要超过100,否则会对CPU造成较大压力。

可以看出,惰性删除对于CPU比较友好,但内存中可能残留了很多已经过期的key,而定期删除对于内存友好。采用惰性删除+定期删除相结合的方式,在合理使用CPU和内存之间达到一个平衡。
不管是惰性删除还是定期删除,都会有很多漏网之鱼,这时候就需要引入内存淘汰机制了,当内存超过一定的限度,需要按照规则清除一些数据,从而腾出更多的使用空间。
在Redis的配置文件中有一个配置项:maxmemory,它用于设置Redis实例能够使用的最大内存,当Redis占用的内存达到maxmemory设定的值以后,Redis会根据一定的策略来释放内存,它一共提供了8种内存淘汰策略:

这些策略的命名也有一定的规律,以单词volatile开头的,针对的是设置了过期时间的key,而allkeys针对的是所有的key。lru是Least Recently Used的缩写,表示最近最少使用,而lfu是Least Frequently Used的缩写,表示最不经常使用。以这样的方式记忆和理解,就简单方便多了。