闲话缓存:算法

从前面的文章中,我们已经了解到了缓存设计的目标,缓存设计应该考虑的因素。今天我们来看看一系列缓存算法以及它们如何去解决问题的。同时,我们也会涉及到各种缓存算法的优缺点。

这里我并不想讨论与预取(pre-fetch)相关的算法,主要是考虑各种淘汰算法。因为相比于预取算法,淘汰算法具有更大的通用性,对缓存好坏影响更大。

1.      时间(完全从最近使用的时间角度考虑)

a.      LRU(least recently used):这种策略就是永远替换掉最近最少使用的缓存单元。它是最古老,应用最广泛的的一种淘汰算法。它的致命的缺陷就是没有考虑缓存单元的使用频率,在某些I/O 模式中,会把一些有价值的缓存单元替换出去。比如,假设我们有10个缓存单元,客户端应用来了一次顺序读写,这样可能把这10个现有的缓存单元替换出去,而把这次顺序读写的数据缓存起来。但是,这种顺序读写的数据在以后都不会被再次用到。反而,那些因为顺序读而被替换出去的缓存单元却是更有价值的。为此,有了各种各样的基于LRU的优化策略被提出来。

2.      频率(完全从使用频率的角度考虑)

a.      LFU(least frequently used): IRM(独立的引用模型)提供了一种用来获取频率的负载特性。它趋向于淘汰最近使用频率最少的缓存单元。这种策略的弊端是:

                                                  i.      它的实现复杂度于缓存大小成对数关系(logarithmic);

                                                ii.      对最近的缓存单元的访问情况基本没考虑;

                                              iii.      对访问模式的改变基本上没有应变的策略。

3.      LRU-2(LRU-K):一种对LRU的改进型策略 (频率)

a.      LRU-2于LFU很相似,如果我们不考虑它对缓存单元引用频率进化分布的自适应性。它的基本思想是对每一个缓存单元,记住最近两次访问的时间。总是淘汰最近两次时间间隔最长的缓存单元。在IRM的假设下,对于任何知道最多两次最近引用缓存单元的在线算法,我们可以得出LRU-2具有最高的命中率。

b.      但是LRU-2也有一些实际的限制:

                                                  i.      它需要维护一个优先级队列。也就是说它具有对数的实现复杂度;

                                                ii.      它需要一个可调参数:CIP(correlated information period)。

c.       在现实中,对数的实现复杂度是一个非常严重的overhead(负担)。所以另外一个策略2Q被提了出来。

4.      2Q:对LRU-2的改进策略 (频率)

a.      相对于LRU-2,2Q的主要改进是用一个简单的LRU list取代了LRU-2中的优先级队列。其它的2Q和LRU-2基本相同。

b.      但是在2Q中,LRU-2的第二个不足还是存在,并且更严重了。因为它需要两个可调参数:Kin和Kout

c.       为什么可调参数一个很严重的限制?这是我们在实施一个系统时,必须确定这些参数,而且不可更改。一旦确定了一组参数,这个缓存系统往往只能对某一类workload表现很好。也就是这种缓存系统缺少了自适应性。

5.      LIRS(Low Inter-reference Recency Set)(频率)

a.      详细描述参考:“LIRS: An efficient low inter-reference recency set replacement policy to improve buffer cache performance”

b.      第一个不足在于需要两个可调参数Llirs 和Lhirs 

c.       它的第二个缺点在于,在最坏的情况下,它需要一个“栈修剪”。这个操作需要遍历数量庞大的缓存单元。

6.      时间和频率(同时考虑时间和频率的算法:LRU和LFU)

a.      FBR(Frequency-based replacement):详细描述请参考“Data cache management using frequency-based replacement”。这个算法的不足之处在于:

                                                  i.      需要可调参数:缓存中三块的大小,Cmax 和Amax:大小调整的时间周期。

                                                ii.      Cache pollution(解决cache污染的机制)

b.      LRFU(Least Recently/Frequently Used): 参考“LRFU: A spectrum of policies that subsumes the least recently used and least frequently used policies”

c.       ALRFU(adaptive LRFU): 参考“On the existence of a spectrum of policies that subsumes the least recently used and least frequently used policies”

7.      临时距离分布(Temporal distance distribution)

a.      MQ(multi-queue replacement policy MQ ): 参考“The multi-queue replacement algorithm for second level buffer caches”

8.      ARC: adaptive replacement cache(IBM), adjusted replacement cache(ZFS)

a.      一种自适应,低成本的淘汰算法

b.      它集合了LRU和LFU的优点,并且没有额外的使用和实现成本。

c.       它可以更具workload的改变而自动的改变淘汰策略。

ARC是目前应用非常广泛的一种淘汰算法。我们应该详细的研究它,并实现它。在ZFS源码中就是它的完整实现。当然,ZFS中的实现和IBM当初提出的内容有点改变。这个我们留在下篇文章中讲述。

时间: 2024-10-29 18:19:31

闲话缓存:算法的相关文章

hibernate一级缓存,二级缓存,三级缓存,缓存算法及配置。

什么是缓存(我的理解):在内存中开辟一块空间,把原来在硬盘上的东西,放到内存当中,当需要用到一些数据时,直接在内存中查找,而不是到硬盘上查找.这块内存中的空间就是缓存.缓存能提高程序的运行效率. 一级缓存(session级的缓存):在一个session中load同一个对象2次,load时,hibernate首先在session缓存中查找对象,如果没找到就到数据库中去load.因此,在同一个session中load一个对象2次,只会发出一条sql语句.而在2个session中load同一个对象则会

“索引缓存算法”成果交付仪式

最新发现与创新 本报讯 (记者冯国梧 通讯员张轶帆)由南开大学博士生童健聪发明的索引缓存算法,目前已经在百度系统使用, 让亿万网民开始享受到了更快捷的搜索服务.近日,百度公司与南开大学举办了"索引缓存算法"成果交付仪式,标志着这一校企合作产出的重大技术成果正式投入百度系统使用并开始申请专利. 据介绍,搜索引擎每天至少要承担数十亿次的搜索任务,然而随着热搜词的增多,缓存的处理空间却很有限,这就导致一些高频搜索的内容被推挤到硬盘,增长了响应时间,影响了用户体验,长此以往甚至有可能导致用户流

PreloadDataCache支持预取的数据缓存,使用简单,支持多种缓存算法,支持不同网络类型,扩展性强

主要特性:(1).使用简单 (2).可自动预取新数据 (3).可选择多种缓存算法(包括FIFO.LIFO.LRU.MRU.LFU.MFU等15种)或自定义缓存算法 (4).省流量性能佳(有且仅有一个线程获取数据) (5).支持不同类型网络处理 (6)缓存可序列化到本地 缓存可从文件中恢复 (7).扩展性强 (8). 包含map的大多数接口 适用:Java和Android开发中获取数据较耗时的应用,如网络通讯.响应慢数据获取,在类似网易新闻.花瓣这类应用中可以起到很好的效果.对于图片缓存可直接使用

闲话缓存:概述

每当我们讨论缓存时,总是会对如下几个词比较熟悉, Write-back,  write-through, write-around 似乎,缓存主要是为"写"设计的,其实这是错误的理解,写从缓存中获得的好处是非常有限的,缓存主要是为"读"服务的. 之所以我们要顺带提一下,在一个缓存系统中,如何处理写的顺序,是因为,在写的过程中,需要动态的更新缓存(否则就会产生数据不一致性的问题),以及后端主存.这三个词都是用来表示如何处理写更新的.就是用什么方式来处理写. 在一个有缓

闲话缓存:ZFS 读缓存深入研究-ARC(二)

Solaris ZFS ARC的改动(相对于IBM ARC) 如我前面所说,ZFS实现的ARC和IBM提出的ARC淘汰算法并不是完全一致的.在某些方面,它做了一些扩展: ·         ZFS ARC是一个缓存容量可变的缓存算法,它的容量可以根据系统可用内存的状态进行调整.当系统内存比较充裕的时候,它的容量可以自动增加.当系统内存比较紧张(其它事情需要内存)的时候,它的容量可以自动减少. ·         ZFS ARC可以同时支持多种块大小.原始的实现假设所有的块都是相同大小的. ·  

缓存、缓存算法(转)

转自http://blog.jobbole.com/30940/ 命中: 当客户发起一个请求(我们说他想要查看一个产品信息),我们的应用接受这个请求,并且如果是在第一次检查缓存的时候,需要去数据库读取产品信息. 如果在缓存中,一个条目通过一个标记被找到了,这个条目就会被使用.我们就叫它缓存命中.所以,命中率也就不难理解了.   Cache Miss: 但是这里需要注意两点: 1. 如果还有缓存的空间,那么,没有命中的对象会被存储到缓存中来. 2. 如果缓存慢了,而又没有命中缓存,那么就会按照某一

闲话缓存:ZFS 读缓存深入研究-ARC(一)

在Solaris ZFS 中实现的ARC(Adjustable Replacement Cache)读缓存淘汰算法真是很有意义的一块软件代码.它是基于IBM的Megiddo和Modha提出的ARC(Adaptive Replacement Cache)淘汰算法演化而来的.但是ZFS的开发者们对IBM 的ARC算法做了一些扩展,以更适用于ZFS的应用场景.ZFS ARC的最早实现展现在FAST 2003的会议上,并在杂志<;Login:>的一篇文章中被详细描述. 注:关于杂志<:Login

Java 自定义实现 LRU 缓存算法

背景 LinkedHashMap继承自HashMap,内部提供了一个removeEldestEntry方法,该方法正是实现LRU策略的关键所在, 且HashMap内部专门为LinkedHashMap提供了3个专用回调方法,afterNodeAccess. afterNodeInsertion.afterNodeRemoval,这3个方法的字面意思非常容易理解,就是节点访问后.节点插入后.节点删除后 分别执行的行为.基于以上行为LinkedHashMap就可以实现一个LRUCache的功能了. 关

关于LRU缓存的实现算法讨论

业务模型 读.写.删的比例大致是7:3:1,至少要支持500w条缓存,平均每条缓存6k,要求设计一套性能比较好 的缓存算法. 算法分析 不考虑MemCached,Velocity等现成的key-value缓存方案,也不考虑脱离.NET gc自己管理内存,不考 虑随机读取数据及顺序读取数据的场景,目前想到的有如下几种LRU缓存方案 算法 分析 SortedDictionary .NET自带的,内部用二叉搜索树(应该不是普通树,至少是做过优化的树)实现的,检索为O (log n),比普通的Dicti