Redis缓存淘汰策略

文章目录

  • noeviction
  • allkeys-lru
  • allkeys-lfu
  • volatile-lru
  • volatile-lfu
  • allkeys-random
  • volatile-random
  • volatile-ttl
  • 近似LRU算法
  • 近似LFU算法

  Redis缓存淘汰策略 cache eviction policy有8种之多。

noeviction

  当内存到达配置的最大值时新数据不会被保存,这个策略就是noeviction,可以说是非常坑的。

allkeys-lru

  关于最近最少使用Least Recently Used,其实是按最后一次访问时间进行的排序。可以在逻辑上用一个队列来建模,左边代表可以清理的,右边代表需要保留的。当内存不足时,从左到右清除队列里的数据。那么当一个元素被使用时,就移动到最右边。所以这个算法对跟使用次数是没关系的,只和最后一次的使用时间有关系,但是翻译为“最近最少使用”,这个最少就容易让人误解为要使用次数最少。其实他的英文Least没有加the,说明不是形容词的最高级,真正的意思是至少、起码,所以准确的翻译应该为“起码最近使用”。而allkeys是覆盖了所有的key,与通过redis命令加在key上面的过期时间无关。所以这个策略也是不建议使用的。这个算法常见的实现是LinkedHashMap,用Hash快速找到使用的key,用LinkedList维护淘汰队列。

allkeys-lfu

  LFU的翻译是最不经常使用frequently used,但是这个翻译是意译,中文算是准确了,就是访问次数最少的被淘汰。算法很简单,使用一个小顶堆来实现,使用次数最少的在堆顶,然后每次内存不足时从堆顶移除。随便插一句,Java的堆为什么叫堆?其实这是个历史名词,因为以前的时代,就是用小顶堆来维护内存的,内存的使用次数最小的(一般为0)在堆顶,所以每次要空闲内存的时候,就从堆顶拿内存就可以了,后来的内存分配算法已经不用堆了,但是堆这个历史名词还是保留了下来。同allkeys-lru一样,allkeys-lfu也是忽略key的过期时间,所以也不建议使用。

volatile-lru

  从设置了超时的key,也就是expire=true的key中使用LRU算法进行淘汰,不再赘述。但是要注意的是这个时候key不一定是过期的key,极有可能是还存活者的key。

volatile-lfu

  从设置了超时的key中使用LFU算法进行淘汰,不再赘述。

allkeys-random

  这从字面就可以理解,随机选个key淘汰,这也太坑了吧、

volatile-random

  从设置了超时的key里随机淘汰,还不算太坑。

volatile-ttl

  从设置了超时的key里淘汰剩余存活时间time-to-live最小的key,TTL就是time-to-live的缩写。

近似LRU算法

  Redis的LRU算法不是精确的LRU算法,也就是说并不是对所有的key进行最后一次访问时间管理,只是取一定的样本数据来进行粗略估算,所以样本数量取得越大,算法就越精确,具体需要用户自己根据实际情况配置。

近似LFU算法

  Redis的LFU算法虽然同LRU一样使用的是近似的抽样统计算法,但是原理有点不一样,内部使用了莫里斯计数器Morris counter进行次数统计。其默认是这样,100万次请求后,将莫里斯计数器设置为最大值,也就是使莫里斯计数器饱和Saturate ,然后每隔一个衰减周期decay time减少一次计数器的值。

你可能感兴趣的:(#,redis,redis,缓存,java)