Redis过期判定与内存回收策略
Redis的key过期判定
一般而言,使用Redis都是作为缓存存在的,要明确一点,缓存中的数据不重要,他会随着访问而变化,所以是热数据。缓存的介质时内存。内存会有大小,所以redis里的数据怎么能随着业务变化,只保留热数据?
我们会将redis的key设置一个有效期,设置有效期一般有两种方式推导出来,一种时业务逻辑(比如说银行中每一天的数据过了凌晨0点,那么那一天的数据都会存起来,不会用到,那么有效期就是一天)还有一种是业务运转推导出来(因为内存是有限的,随着访问的变化,淘汰掉冷数据)。
注意:redis的key有效期不会随着访问而延长,只会发生了写操作,才会踢出延期时间,持久化了(ttl返回了-1)。
redis中的key过期后,并不是马上删除该key,方式为被动与主动。
被动的方式:一个key过期了,客户端假设又一次访问过期的key时,发现已经过期了,返回client的nil,然后删除该key,这样会导致key过期后仍然会存在,浪费了内存。
主动的方式:redis会每秒执行10次轮询操作。随机抽取20个检查,删除所有过期的key,如果删除的key多于25%,那么由执行一遍。这样会让过期的key比例下降到25%以下。
Redis内存回收策略
Redis的内存是可以修改的。所以当maxmemory到达最大的时候,由redis的maxmemory-policy配置指令进行配置。有6种不同内存回收策略。
如果redis当作数据库使用,noeviction需要。而缓存的话需要LRU与LFU,allkeys是自己没设置过期的key,volatile是自己设置过期的key使用。
LRU是最近最少使用(最长时间)淘汰算法,LFU是最不经常使用(最少次)淘汰算法(Least Frequently Used)。LFU是淘汰一段时间内,使用次数最少的页面。
LFU,内部维护一个计数器,按照引用计数进行排列:
优点:可以更好的表示热度数据,LFU效率要优于LRU,且能够避免周期性或者偶发性的操作导致缓存命中率下降的问题。
缺点:需要记录所有数据的访问记录,内存消耗较高;需要基于引用计数排序,性能消耗较高。
LRU内部是一个双向链表。