4

LRU进阶之LRU-K和2Q

背景

在上篇文章中,我们重点介绍了缓存算法(页面置换算法)之LRU算法,(原文地址:缓存算法(页面置换算法)之LRU算法)

上文所介绍的LRU算法实现虽然简单,并且在大量频繁访问热点页面时十分高效,但同样也有一个缺点,就是如果该热点页面在偶然一个时间节点被其他大量仅访问了一次的页面所取代,那自然造成了浪费。

为了解决上述问题,本文将会为大家介绍LRU-K和2Q算法。

LRU-K算法

算法思想

LRU-K中的k,其实是指最近访问页面的次数,所以我们不难理解,上文所介绍的LRU算法其实就是LRU-1,但是因为仅访问1次就能替代别人,可能会造成“缓存污染”的问题,因此提出了LRU-K的概念。

其核心思想就是将访问一次就能替代的“1”提升为"K"。

原理解析

与LRU算法不同,LRU-K算法需要维护两个队列:历史队列缓存队列

历史队列保存着每次访问的页面,当页面访问次数达到了k次,该页面出栈,并保存至缓存队列;若尚未达到k次则继续保存,直至历史队列也满了,那就根据一定的缓存策略(FIFO、LRU、LFU)进行淘汰。

缓存队列则是保存已经访问k次的页面,当该队列满了之后,则淘汰最后一个页面,也就是第k次访问距离现在最久的那个页面。

详细说明

image.png

  1. 页面第一次被访问,添加到历史队列中。
  2. 当历史队列中的页面满了,根据一定的缓存策略(FIFO、LRU、LFU)进行淘汰老的页面。

image.png

3.当历史队列中的某个页面第k次访问时,该页面从历史队列中出栈,并存放至缓存队列。

image.png

4.缓存队列中的页面再次被访问k次时,历史队列中该页面出栈,并且更新缓存队列中该页面的位置。

image.png

5.当缓存队列需要淘汰页面时,淘汰最后一个页面,也就是第k次访问距离现在最久的那个页面。

小结

它的命中率要比LRU要高,但是因为需要维护一个历史队列,因此内存消耗会比LRU多。

实际应用中LRU-2是综合各种因素后最优的选择,LRU-3或者更大的K值命中率会高,但适应性差,需要大量的数据访问才能将历史访问记录清除掉。

Two queues(2Q)

算法思想

2Q算法其实是LRU-K的一个具体版本:LRU-2。并且2Q历史队列是采用FIFO的方法进行缓存的。(FIFO在本文就不在重复阐述了,感兴趣的读者请查阅上一篇文章,原文地址:缓存算法(页面置换算法)之LRU算法)

原理解析

同样维护两个队列:历史队列(采用FIFO的淘汰策略)和缓存队列(采用LRU-1的淘汰策略)

  1. 新访问的数据插入到FIFO队列
  2. 如果数据在FIFO队列中一直没有被再次访问,则最终按照FIFO规则淘汰
  3. 如果数据在FIFO队列中被再次访问,则将数据移到LRU队列头部
  4. 如果数据在LRU队列再次被访问,则将数据移到LRU队列头部
  5. LRU队列淘汰末尾的数据

小结

缺点跟LRU-K一致,其实2Q算法就是LRU-2,并且历史队列采用了FIFO的淘汰策略。

Muti Queue(MQ)

MQ算法其实是2Q算法的一个扩展。
2Q算法维护两个队列,而MQ算法根据访问频率将数据划分为多个队列,不同的队列具有不同的访问优先级。

其核心思想是:优先缓存访问次数多的数据

举个例子🌰:如果在高优先级队列中一个页面长时间没有被访问,当新页面进栈,没位置存放时,该长时间未被访问的页面就出栈,进入低一级优先级的队列中。

MQ算法需要维护多个队列以及多个页面的数据,成本较大。

参考文章:
https://www.jianshu.com/p/c4e4d55706ff
https://www.cnblogs.com/George1994/p/7137007.html?utm_source=tuicool&utm_medium=referral


TheWalkingFat
522 声望32 粉丝