Redis内存淘汰及回收策略都是Redis内存优化兜底的策略,那它们是如何进行兜底的呢?先来说明一下什么是内存淘汰和内存回收策略:
- Redis内存淘汰:当Redis的内存使用超过配置的限制时,根据一定的策略删除一些键,以释放内存空间
- Redis内存回收:Redis通过定期删除和惰性删除两种方式来清除过期的键,以保证数据的时效性和减少内存占用
内存淘汰策略
Redis内存淘汰策略是指当Redis的内存使用超过配置的最大值时,如何选择一些键进行删除,以释放空间给新的数据。Redis提供了八种内存淘汰策略,分别是:
- noeviction:不会淘汰任何键,达到内存限制后返回错误
- allkeys-random:在所有键中,随机删除键
- volatile-random:在设置了过期时间的键中,随机删除键
- allkeys-lru:通过LRU算法淘汰最近最少使用的键,保留最近使用的键
- volatile-lru:从设置了过期时间的键中,通过LRU算法淘汰最近最少使用的键
- allkeys-lfu:从所有键中淘汰使用频率最少的键。从所有键中驱逐使用频率最少的键
- volatile-lfu:从设置了过期时间的键中,通过LFU算法淘汰使用频率最少的键
- volatile-ttl:从设置了过期时间的键中,淘汰马上就要过期的键
LRU和LFU
LRU(Least Recently Used)算法为最近最少使用算法,根据数据的历史访问记录来进行淘汰数据,优先移除最近最少使用的数据,这种算法认为最近使用的数据很大概率将会再次被使用
LFU(least frequently used)算法为最少频率使用算法,优先移除使用频率最少的数据,这种算法认为使用频率高的数据很大概率将会再次被使用
LRU和Redis的近似LRU
LRU(least frequently used)算法为最近最少使用算法,根据数据的历史访问记录来进行淘汰数据,优先移除最近最少使用的数据,这种算法认为最近使用的数据很大概率将会再次被使用
什么是LRU
在算法的选择上,Redis需要能够快速地查询、添加、删除数据,也就是说查询、添加、删除的时间复杂读需为O(1)。哈希表能保证查询数据的时间复杂度为O(1)。而双向链表能保证添加、删除数据的时间复杂度为O(1),如下:
Redis的近似LRU
如前文所述,真实的 LRU 算法需要用链表管理所有的数据,每次访问一个数据就要移动链表节点,这样会占用额外的空间和时间。而Redis通过近似 LRU 算法,随机抽样一些键,然后比较它们的访问时间戳