1.内存回收
使用redis的时候我们需要给某些键值对设置有效期,redis中可以通过4个独立的命令来给一个键值设置过期时间:
(1)expire key ttl :将key的过期时间设置为 ttl秒
(2)pexpire key ttl :将key值的过期时间设置为 ttl 毫秒
(3)expireat key timestamp :将key的过期时间设置为指定的timestamp秒数
(4)pexpireat key timestamp :将key值的过期时间设置为指定的timestamp毫秒数
不管使用哪一种命令,redis底层都是通过pexpireat来设置过期时间的
查看剩余的过期时间:可以通过 ttl和pttl两个命令来查看
ttl key 返回key剩余过期秒数
pttl key 返回key剩余过期的毫秒数
如果未设置过期时间则这2个命令都返回 -1 ,如果设置了一个非法的过期时间,则都返回 -2。
2.过期策略
如果将一个过期的键删除,我们会有三种策略
(1)定时删除:为每一个键设置一个定时器,一旦过期时间到了,则将键删除。这种策略对内存很友好,但是对CPU不友好,因为每一个定时器都会占用一定的CPU资源。
(2)惰性删除:不管键有没有过期都不主动删除,等到每次去获取键时再判断是否过期,如果过期就删除该键,否则返回键对应的值。这种策略对内存不够友好,可能会浪费很多内存。
(3)定期扫描:系统每隔一段时间就定期扫描一次,发现过期的键就进行删除。这种策略相对来说是上面两种策略的折中方案,需要注意的是这个定期的频率要结合实际情况掌控好,使用这种方案有一个缺陷就是可能会出现已经过期的键也被返回。
在Redis中,选择的是策略(2)和策略(3)的综合使用,不过redis的定期扫描只会扫描设置了过期时间的键,因为设置了过期时间的键Redis会单独存储,所以不会出现扫描所有键的情况:
typedef struct redisDb{
dict *dict ; //所有键值对
dict * expires; //设置了过期时间的键值对
dict * blocking_keys ;//被阻塞的key
dict * watched_keys; //WATCHED keys
}
Redis的8种淘汰策略
首先redis提供了一个参数maxmemory来配置redis最大使用内存:maxmemory <bytes> 或者也可以通过命令config set maxmemory 1GB 来动态修改。如果没有设置该参数,那么在32位的操作系统中Redis最多使用3GB内存,而在64位的操作系统中则不作限制。
Redis中提供了8种淘汰策略,可以通过参数maxmemory-policy 进行配置:
ttl:设置了过期时间的key中,剩余时间更少的优先淘汰。
lru:最近最少使用的key,优先被淘汰。
lfu:最近访问频率最少的key,优先被淘汰。
random:随机淘汰内存中内容。
noeviction:无法再写入Redis,不会处理内存中的内容,是默认的淘汰策略。