# 有效期TTL(Time to live)
设置有效期的作用: 1.节省空间; 2.做到数据弱一致性,有效期失效后,可以保证数据的一致性。
Redis的过期策略一般有以下三种:
【1】定时过期: 每个设置过期时间的key
都需要创建一个定时器,到过期时间就会立即清除。该策略可以立即清除过期的数据,对内存很友好;但是会占用大量的CPU资源去处理过期的数据,从而影响缓存的响应时间和吞吐量。
【2】惰性过期: 只有当访问一个key
时,才会判断该key
是否已过期,过期则清除。该策略可以最大化地节省CPU资源,却对内存非常不友好。极端情况可能出现大量的过期key没有再次被访问,从而不会被清除,占用大量内存。
【3】定期过期: 每隔一定的时间,会扫描一定数量的数据库的expires
字典中一定数量的key
,并清除其中已过期的key
。该策略是前两者的一个折中方案。通过调整定时扫描的时间间隔和每次扫描的限定耗时,可以在不同情况下使得CPU和内存资源达到最优的平衡效果。
expires
字典会保存所有设置了过期时间的key
的过期时间数据,其中,key
是指向键空间中的某个键的指针,value
是该键的毫秒精度的UNIX
时间戳表示的过期时间。键空间是指该Redis
集群中保存的所有键。
Redis过期删除采用的是惰性过期和定期过期两种策略的组合: Redis先采用定期删除,默认是每100ms
检测一次,遇到过期的key
则进行删除,这里的检测并不是顺序检测,而是随机检测。那这样会有部分key
未被检测到。Redis
会在我们读/写一个已经过期的key
时,触发Redis
的惰性删除策略,直接回干掉过期的key
定时删除策略缺点: 定时删除,用一个定时器来负责监视key
,过期则自动删除。虽然内存及时释放,但是十分消耗CPU
资源。在大并发请求下,CPU
要将时间应用在处理请求,而不是删除key
,因此没有采用这一策略.
定期删除+惰性删除策略缺点: 如果定期删除没删除key
。然后你也没即时去请求key
,也就是说惰性删除也没生效。这样,redis
的内存会越来越高。那么就应该采用内存淘汰机制。
# 淘汰策略
Redis淘汰策略的配置:
【1】maxmemory
最大使用内存数量,默认内存设置为0
,相当于基于物理机的最大值
【2】maxmemory-policy noeviction
淘汰策略
Redis
自身实现了缓存淘汰,当Redis
缓存内存不足时,对新写入且需要申请额外空间的数据时的一种内存优化方案。
【1】noeviction
:当内存不足以容纳新写入数据时,新写入操作会报错。
【2】allkeys-lru
:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key。
【3】allkeys-random
:当内存不足以容纳新写入数据时,在键空间中,随机移除某个key。
【4】volatile-lru
:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的key。
【5】volatile-random
:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个key。
【6】volatile-ttl
:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的key优先移除。
redis 4.x
后支持LFU
策略,最少频率使用allkeys-lfu
、volatile-lfu
LRU(Least recently used,最近最少使用): LRU
算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”。
基本思路: 新数据插入到列表头部;每当缓存命中(即缓存数据被访问),则将数据移到列表头部;当列表满的时候,将列表尾部的数据丢弃。
LFU(Least Frequently Used 最近最少使用算法): 它是基于“如果一个数据在最近一段时间内使用次数很少,那么在将来一段时间内被使用的可能性也很小”的思路。相对于LRU
消耗CPU
资源较多。
举例说明:假设LFU
方法的时期T为10分钟,如下数据为10分钟内的数据,内存块大小为3。下面为访问的顺序即redis存放的顺序:
3、2、3、2、1、4
如上:1、2、3已将redis
内存消耗完,当4进来时,LRU
淘汰策略,会按照顺序淘汰掉3,LFU
会统计1、2、3这段时间访问的次数,最终淘汰掉最少访问次数的1。从而也可以特殊结论LRU
适合大文件,LFU
适合小文件。