1、为什么要设置过期
Redis是基于内存的非关系型数据库。既然基于内存,所以可知受到内存容量的限制,Redis中能够存储的数据量不会太大,所以可以为redis中的数据设置过期时间,到期后就可以按照设置的机制对这些过期的数据进行删除,从而腾出空间来存放接下来需要存储的新的数据。
2、过期策略
(1)定期删除
所谓定期删除,指的是 redis 默认是每隔固定的时间就随机抽取一些设置了过期时间的 key,检查其是否过期,如果过期就删除。
假设 redis 里放了 10w 个 key,都设置了过期时间,你每固定的时间,就检查 10w 个 key,那 redis 基本上就死了,cpu 负载会很高的,消耗在你的检查过期 key 上了。注意,这里可不是每隔固定时间就遍历所有的设置过期时间的 key,那样就是一场性能上的灾难。实际上 redis 是每隔固定时间随机抽取一些 key 来检查和删除的。
但是问题是,定期删除可能会导致很多过期 key 到了时间并没有被删除掉(因为定期删除是随机抽取,所以可能存在一些特别走运的漏网之鱼一直没有被抽取到,虽然已经过期了,但是一直占用着内存),所以就引入了惰性删除策略
(2)惰性删除
顾名思义,惰性删除是懒惰的删除策略,哪里体现懒惰了?不去主动抽取、不去主动检查、不去主动删除,而是在使用的时候,不得不检查是否过期的时候才去检查是否过期,所以懒惰。这就是说,在你获取某个 key 的时候,redis 会检查一下 ,这个 key 是否设置了过期时间以及是否过期了?如果设置了过期时间并且已经过期了就会删除,不会给你返回任何东西。也即,获取 key 的时候,如果此时 key 已经过期,就删除,不会返回任何东西。
(3)问题
如果定期删除漏掉了很多过期 key,然后你也没及时去查询数据,也即没有走惰性删除,此时就会有大量过期 key 堆积在内存里,导致 redis 内存块耗尽了。how to do?answer:内存淘汰机制。也就是说内存淘汰机制是在内存吃紧的时候才执行的机制。
3、内存淘汰机制
六种内存淘汰策略:
redis 内存淘汰机制有以下几个:
(1)noeviction: 当内存不足以容纳新写入数据时,新写入操作会报错(容纳不了新数据,就拒绝新数据写入,拒绝缓存服务)。
(2)allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的 key(这个是最常用的)。
(3)allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个 key。
(4)volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的 key
(5)volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个 key。
(6)volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的 key 优先移除。