转缓存缓存算法和缓存框架简介Lfree

“缓存就是存贮数据(使用频繁的数据)的临时地方,因为取原始数据的代价太大了,所以我可以取得快一些。”

这就是programmerone(programmerone是一个面试者)在面试中的回答(一个月前,他向公司提交了简历,想要应聘要求在缓存,缓存框架,大规模数据操作有着丰富经验的java开发职位)。

programmerone通过hashtable实现了他自己的缓存,但是他知道的只是他的缓存和他那存储着150条记录的hashtable,这就是他认为的大规模数据(缓存=hashtable,只需要在hashtable查找就好了),所以,让我们来看看面试的过程吧。

面试官:你选择的缓存方案,是基于什么标准的?

programmerone:呃,(想了5分钟)嗯,基于,基于,基于数据(咳嗽……)

面试官:exceseme!能不能重复一下?

programmerone:数据?!

面试官:好的。说说几种缓存算法以及它们的作用

programmerone:(凝视着面试官,脸上露出了很奇怪的表情,没有人知道原来人类可以做出这种表情)

面试官:好吧,那我换个说法,当缓存达到容量时,会怎么做?

programmerone:容量?嗯(思考……hashtable的容量时没有限制的,我能任意增加条目,它会自动扩充容量的)(这是programmerone的想法,但是他没有说出来)

说到做到

programmerone离开之后,他想要知道这个面试者说的问题和答案,所以他上网去查,programmerone对缓存一无所知,除了:当我需要缓存的时候,我就会用hashtable。

为什么我们需要缓存?

1.用户很烦,在抱怨,甚至不去用这个应用了(这是大多数情况下都会发生的)

2.数据库为打包回家,离开这个应用,然后,就出现了大麻烦(没地方去存储数据了)(发生在极少数情况下)

上帝派来了缓存

在几年之后,IBM(60年代)的研究人员引进了一个新概念,它叫“缓存”。

什么是缓存?

正如开篇所讲,缓存是“存贮数据(使用频繁的数据)的临时地方,因为取原始数据的代价太大了,所以我可以取得快一些。”

缓存可以认为是数据的池,这些数据是从数据库里的真实数据复制出来的,并且为了能别取回,被标上了标签(键ID)。太棒了

programmerone已经知道这点了,但是他还不知道下面的缓存术语。

命中:

当客户发起一个请求(我们说他想要查看一个产品信息),我们的应用接受这个请求,并且如果是在第一次检查缓存的时候,需要去数据库读取产品信息。

如果在缓存中,一个条目通过一个标记被找到了,这个条目就会被使用、我们就叫它缓存命中。所以,命中率也就不难理解了。

CacheMiss:

但是这里需要注意两点:

1.如果还有缓存的空间,那么,没有命中的对象会被存储到缓存中来。

2.如果缓存慢了,而又没有命中缓存,那么就会按照某一种策略,把缓存中的旧对象踢出,而把新的对象加入缓存池。而这些策略统称为替代策略(缓存算法),这些策略会决定到底应该提出哪些对象。

存储成本:

索引成本:

和存储成本相仿。

失效:

当存在缓存中的数据需要更新时,就意味着缓存中的这个数据失效了。

替代策略:

当缓存没有命中时,并且缓存容量已经满了,就需要在缓存中踢出一个老的条目,加入一条新的条目,而到底应该踢出什么条目,就由替代策略决定。

最优替代策略:

最优的替代策略就是想把缓存中最没用的条目给踢出去,但是未来是不能够被预知的,所以这种策略是不可能实现的。但是有很多策略,都是朝着这个目前去努力。

Java街恶梦:

programmerone:nihahha,我要把你弄失效!(疯狂的状态)

缓存对象:别别,让我活着,他们还需要我,我还有孩子。

programmerone:每个缓存对象在失效之前都会那样说。你从什么时候开始有孩子的?不用担心,现在就永远消失吧!

哈哈哈哈哈……programmerone恐怖的笑着,但是警笛打破了沉静,警察把programmerone抓了起来,并且控告他杀死了(失效)一个仍需被使用的缓存对象,他被押到了监狱。

缓存算法

没有人能说清哪种缓存算法优于其他的缓存算法

LeastFrequentlyUsed(LFU):

大家好,我是LFU,我会计算为每个缓存对象计算他们被使用的频率。我会把最不常用的缓存对象踢走。

LeastRecentlyUser(LRU):

我是LRU缓存算法,我把最近最少使用的缓存对象给踢走。

我总是需要去了解在什么时候,用了哪个缓存对象。如果有人想要了解我为什么总能把最近最少使用的对象踢掉,是非常困难的。

浏览器就是使用了我(LRU)作为缓存算法。新的对象会被放在缓存的顶部,当缓存达到了容量极限,我会把底部的对象踢走,而技巧就是:我会把最新被访问的缓存对象,放到缓存池的顶部。

所以,经常被读取的缓存对象就会一直呆在缓存池中。有两种方法可以实现我,array或者是linkedlist。

我的速度很快,我也可以被数据访问模式适配。我有一个大家庭,他们都可以完善我,甚至做的比我更好(我确实有时会嫉妒,但是没关系)。我家庭的一些成员包括LRU2和2Q,他们就是为了完善LRU而存在的。

LeastRecentlyUsed2(LRU2):

我是LeastRecentlyUsed2,有人叫我最近最少使用twice,我更喜欢这个叫法。我会把被两次访问过的对象放入缓存池,当缓存池满了之后,我会把有两次最少使用的缓存对象踢走。因为需要跟踪对象2次,访问负载就会随着缓存池的增加而增加。如果把我用在大容量的缓存池中,就会有问题。另外,我还需要跟踪那么不在缓存的对象,因为他们还没有被第二次读取。我比LRU好,而且是adoptivetoaccess模式。

TwoQueues(2Q):

我是TwoQueues;我把被访问的数据放到LRU的缓存中,如果这个对象再一次被访问,我就把他转移到第二个、更大的LRU缓存。

我踢走缓存对象是为了保持第一个缓存池是第二个缓存池的1/3。当缓存的访问负载是固定的时候,把LRU换成LRU2,就比增加缓存的容量更好。这种机制使得我比LRU2更好,我也是LRU家族中的一员,而且是adoptivetoaccess模式。

AdaptiveReplacementCache(ARC):

我是ARC,有人说我是介于LRU和LFU之间,为了提高效果,我是由2个LRU组成,第一个,也就是L1,包含的条目是最近只被使用过一次的,而第二个LRU,也就是L2,包含的是最近被使用过两次的条目。因此,L1放的是新的对象,而L2放的是常用的对象。所以,别人才会认为我是介于LRU和LFU之间的,不过没关系,我不介意。

我被认为是性能最好的缓存算法之一,能够自调,并且是低负载的。我也保存着历史对象,这样,我就可以记住那些被移除的对象,同时,也让我可以看到被移除的对象是否可以留下,取而代之的是踢走别的对象。我的记忆力很差,但是我很快,适用性也强。

MostRecentlyUsed(MRU):

我是数据库内存缓存中是多么的常见!每当一次缓存记录的使用,我会把它放到栈的顶端。当栈满了的时候,你猜怎么着?我会把栈顶的对象给换成新进来的对象!

FirstinFirstout(FIFO):

我是先进先出,我是一个低负载的算法,并且对缓存对象的管理要求不高。我通过一个队列去跟踪所有的缓存对象,最近最常用的缓存对象放在后面,而更早的缓存对象放在前面,当缓存容量满时,排在前面的缓存对象会被踢走,然后把新的缓存对象加进去。我很快,但是我并不适用。

SecondChance:

大家好,我是secondchance,我是通过FIFO修改而来的,被大家叫做secondchance缓存算法,我比FIFO好的地方是我改善了FIFO的成本。我是FIFO一样也是在观察队列的前端,但是很FIFO的立刻踢出不同,我会检查即将要被踢出的对象有没有之前被使用过的标志(1一个bit表示),没有没有被使用过,我就把他踢出;否则,我会把这个标志位清除,然后把这个缓存对象当做新增缓存对象加入队列。你可以想象就这就像一个环队列。当我再一次在队头碰到这个对象时,由于他已经没有这个标志位了,所以我立刻就把他踢开了。我在速度上比FIFO快。

CLock:

我是Clock,一个更好的FIFO,也比secondchance更好。因为我不会像secondchance那样把有标志的缓存对象放到队列的尾部,但是也可以达到secondchance的效果。

我持有一个装有缓存对象的环形列表,头指针指向列表中最老的缓存对象。当缓存miss发生并且没有新的缓存空间时,我会问问指针指向的缓存对象的标志位去决定我应该怎么做。如果标志是0,我会直接用新的缓存对象替代这个缓存对象;如果标志位是1,我会把头指针递增,然后重复这个过程,知道新的缓存对象能够被放入。我比secondchance更快。

Simpletime-based:

Extendedtime-basedexpiration:

Slidingtime-basedexpiration:

其他的缓存算法还考虑到了下面几点:

成本:如果缓存对象有不同的成本,应该把那些难以获得的对象保存下来。

容量:如果缓存对象有不同的大小,应该把那些大的缓存对象清除,这样就可以让更多的小缓存对象进来了。

根据缓存对象的大小而不管其他的缓存算法可能是有必要的。

电子邮件!

在这一部分中,我们来看看如何实现这些著名的缓存算法。以下的代码只是示例用的,如果你想自己实现缓存算法,可能自己还得加上一些额外的工作。

LeftOver机制

RandomCache

我是随机缓存,我随意的替换缓存实体,没人敢抱怨。你可以说那个被替换的实体很倒霉。通过这些行为,我随意的去处缓存实体。我比FIFO机制好,在某些情况下,我甚至比LRU好,但是,通常LRU都会比我好。

每当我们讨论缓存时,总是会对如下几个词比较熟悉,

Write-back,write-through,write-around

似乎,缓存主要是为“写”设计的,其实这是错误的理解,写从缓存中获得的好处是非常有限的,缓存主要是为“读”服务的。

之所以我们要顺带提一下,在一个缓存系统中,如何处理写的顺序,是因为,在写的过程中,需要动态的更新缓存(否则就会产生数据不一致性的问题),以及后端主存。这三个词都是用来表示如何处理写更新的。就是用什么方式来处理写。

在一个有缓存的层次结构中,如何理解缓存是为“读”服务的?这涉及到读请求的处理序列。对于每一个读请求,我们都会用如下的操作序列去处理它:

1.在缓存中查找请求对应的数据

a.如果找到,则直接返回给客户

b.如果没找到,则把请求的数据读入缓存(更新缓存),然后把数据返回给客户

那么我们来想想,在设计缓存时,我们应该从哪几方面考虑来达到这个缓存的设计目标呢?根据我们上面提到的读请求的操作序列,我们可以从如下几个方面来思考:

1.我们应该尽量多的用有用的数据填满缓存。也就是说,我们要充分利用缓存。

a.这是缓存模块和其它模块不同的地方,并不是说缓存中的数据越少越好,而是有用的数据越多越好。

b.这里有个非常好的列子,就是Windows的内存占用率总是非常高,很多人都表示过不满。其实这是一个非常好的设计。Windows总是试图尽量利用那些空闲的内存,用来缓存磁盘上的数据,以此来提高系统的整体性能。否则你那么大的内存,就为了拿来好看?

2.如何获取“有用”的数据。这里,“有用”的数据的定义就是可能在不久的将来会被client用到的数据。为了得到有用的数据,我们需要预估客户端应用的I/O模式,比如顺序读写,随机读写等等。这里就涉及到了“pre-fetch”算法。

a.Pre-fetch(预取算法):是一种预测客户端应用下次读写的数据在哪里的算法,并且把客户要用的数据提前放入缓存中,以此来提高读的响应速度。

3.问题来了,如果缓存已经满了,那么如何存放新的需要缓存的单元呢?这就牵涉到缓存设计的另一端:淘汰算法。

a.相比于pre-fetch,淘汰算法(replacementpolicy)更加重要。因为对于随机的I/O,预取算法是无能为力的。

b.淘汰算法的关键是如何判断一个单元的数据比另一个单元的数据更加重要。但需要淘汰一个数据单元时,丢弃掉最不重要的那个数据单元,并且用它来存放新的数据。

4.缓存算法设计的另外一个重要的考虑因素是算法的复杂度。或者说是实现或运行算法带来的额外开销。我们希望算法容易实现,并且额外开销不随着缓存大小的改变而改变。包括容量的额外开销和计算的额外开销。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

5.LIRS(LowInter-referenceRecencySet)(频率)

a.详细描述参考:“LIRS:Anefficientlowinter-referencerecencysetreplacementpolicytoimprovebuffercacheperformance”

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

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

a.FBR(Frequency-basedreplacement):详细描述请参考“Datacachemanagementusingfrequency-basedreplacement”。这个算法的不足之处在于:

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

b.LRFU(LeastRecently/FrequentlyUsed):参考“LRFU:Aspectrumofpoliciesthatsubsumestheleastrecentlyusedandleastfrequentlyusedpolicies”

c.ALRFU(adaptiveLRFU):参考“Ontheexistenceofaspectrumofpoliciesthatsubsumestheleastrecentlyusedandleastfrequentlyusedpolicies”

7.临时距离分布(Temporaldistancedistribution)

a.MQ(multi-queuereplacementpolicyMQ):参考“Themulti-queuereplacementalgorithmforsecondlevelbuffercaches”

8.ARC:adaptivereplacementcache(IBM),adjustedreplacementcache(ZFS)

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

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

THE END
1.人行大额支付系统一般在什么时候进入日间状态?声明: 本网站大部分资源来源于用户创建编辑,上传,机构合作,自有兼职答题团队,如有侵犯了你的权益,请发送邮箱到feedback@deepthink.net.cn 本网站将在三个工作日内移除相关内容,刷刷题对内容所造成的任何后果不承担法律上的任何义务或责任 https://www.shuashuati.com/ti/3e7666adefb04a1ebce5a8e6c1a7080e.html?fm=bda4091543e65a419801fb99ced60a3d7c
2.婴儿痉挛症一般在什么时候发作?有问必答主要表现为点头、弯腰、上肢外展、内收、弯腰、屈膝、握拳或四肢伸直、僵硬、头后仰、眼上翻或凝视等...https://www.120ask.com/question/104857925.htm
3.2019年护理部上半年三基第二场次及补考理论考试(N2C.第二狭窄部在食管与作支气管交叉处 D.第三狭窄部距中切牙45cm 20.低钾血症的病人最早的临床表现是() A.恶心呕吐 B.腹胀 C.软瘫 D.肌无力 21新生儿窒息复苏时胸外按压与正压呼吸比为() A.15:2 B.3:1 C.4:1 D.30:2 22.预产期从什么时候起推算() A.末次月经第一天 B.末次月经最后一天...https://www.wjx.cn/jq/44351776.aspx
4.《设计师要懂心理学》丨NOTES渐进呈现,仅在用户需要时才展示他们需要的信息,用链接引导用户获得更多详情。如果必须在让用户点击和让用户动脑之间做取舍,那么多几次点击,少一点思考吧。在你使用渐进呈现之前,搞清楚多数用户需要什么信息,且在什么时候需要。 有些心理活动难度更大 理论上,你可以使用户承受三类负荷:认知(包括记忆)负荷、视觉负荷和动...https://www.jianshu.com/p/f1ec7e24b5fa
5.高压锅顿完汤后多长时间能打开宣威火腿,成品形似琵琶,脚细直伸,皮薄肉嫩;皮面呈棕色或淡黄色,切面肌肉呈玫瑰色,骨呈深红色,好似一股血气凝聚在内,油润有光泽,脂肪呈乳白色或微 2020-11-03 其他 公司一般在什么时候解禁原始股 1、上市公司解禁原始股、通过股权分置改革的日期一般是从上市日起的1~3年内。2、解禁原始股中的原始股是指...http://m.qicaisi.com/bk-3666.shtml
1.自译特别鼎谈三宅唱x滨口龙介x三浦哲哉「时间」是如何附着于...──『ケイコ 目を澄ませて』の演出をめぐって?2022映画「ケイコ 目を澄ませて」製作委員会/COMME DES CINéMAS前言三宅唱导演的新作《惠子,凝视》于2022年12月16日公开上映。16毫米胶片映出清澈通透的光线和骤然静默下来的澄净空气;寡言的惠子,她眼中所映之物与自然流逝的时间被精心摄取,每一个层叠累积...https://movie.douban.com/review/15832622/
2.《咎狗SA夫夫相性一百问》舒弥^第1章^最新更新:20090937、两人在一起时最让你心跳加速的事情是? S:他露出销魂表情的时候 A:……凝视我的时候 弥:总之都是压倒或被压倒之前的部分……XDD 38、你曾向对方撒过谎吗?你善于撒谎吗? S:有这个必要吗? 弥:(揉额角)好吧Akira说 A:……没有 弥:好乖的Akirao~o(∩_∩)o… A:才不是……! 39、什么时候觉得最...https://www.jjwxc.net/onebook.php?novelid=475233
3.赞公共文明引导员6篇(全文)C、自己高兴的时候 D、节假日的下午或平日晚饭后 24、到别人家做客时,应该:(C)A、随手乱翻 B、长时间逗留 C、不宜带年幼的孩子,更不宜在别人家责骂孩子 D、到处乱闯 25、如果有人错打了你的电话,你应该:(C)A、埋怨辱骂对方 B、粗暴地挂断 https://www.99xueshu.com/w/file0bhodosu.html
4.社交的礼仪15篇交换名片是建立人际关系的第一步,适合在与人初相识的时候,作完自我介绍或经他人介绍以后进行。一般情况是: 地位低的人向地位高的人递名片; 男性先向女性递名片; 当对方不止一人时,应先将名片递给职位较高或年龄较大的人; 如分不清职位和年龄,可依照座次递名片,应给对方每人一张,以免厚此薄彼。 https://www.fwsir.com/fanwen/html/fanwen_20211207233815_1508479.html
5.人教版四年级下册语文教案15篇2、与高兴相近的词语有哪些?(板书:快乐)你什么时候会很快乐?我们今天来学习一篇课文,作者得出了这样的感受,板书完整课题:给予是快乐的。 二、出示目标 三、自学指导 自学指导1 1、谁给予了谁什么 2、在怎样的情况下给予的? (1、保罗的哥哥把新轿车给予保罗2、小男孩要把欢乐给予弟弟、保罗把自己的欢乐给予...https://teacher.ruiwen.com/jiaoxueziliao/jiaoan/313641.html
6.经典人生语录(精选15篇)16、向新朋友介绍女友时,请搂着她的腰,而不是站在一旁用手指点。 17、走的最快的是最美的风景 伤的最深的是最真的感情。 18、人生最大的悲哀,并不是在于你得不到或者失去的, 19、而是你根本不知道你自己要的是什么! 20、长大后之所以这么努力、只是因为小时候吹过的牛逼! https://www.oh100.com/a/202206/4802949.html
7.抖音打卡圣地第一次去瑞士到底该怎么玩?二、什么时候去瑞士比较合适? 6月至10月以前是瑞士旅行的黄金时节,整体气温约在18至28度,清爽宜人且没有霜雪干扰,不论沿着雪山、碧湖健行,或搭火车山间蜿蜒而过,都令人心旷神怡,爱拍照的同学尤其会开心到不行,因为随手拍,定格的画面都是傲视朋友圈内的风光大片,蓝天、白云,彷彿隔着手机荧幕都闻得到空气里清新宜...https://m.mafengwo.cn/gonglve/ziyouxing/117682.html
8.面试的技巧(15篇)很多时候,尤其是没有从事过销售的人在面试时会很紧张,有时语无伦次,有时紧张的手脚都在发抖,其实大可不必这样,其实现在选择销售人员时一般并不是看你是否经验多少,而是你个人的修为和内涵,也就是说发展潜力如何?没有做过销售的并不是坏处,因为你只要有潜力,那么经过培训之后再加上个人的努力,说不定,你也会成...https://www.wenshubang.com/mianshiwenti/1853308.html
9.职场的礼仪常识在社交场合交谈时,一定要注意眼神的礼仪,目光要坦然、温和、大方、亲切,正视对方的两眼与嘴部的三角区,表示对对方的尊重,但凝视的时间不可太长,因为长时间凝视对方,会让对方感到紧张、难堪。如果面对熟人、朋友、同事,可以用从容的眼光来表达问候,征求意见,这时目光可以多停留一些时间。与人对视时,切忌迅速移开,不...https://www.jy135.com/zhichang/627682.html
10.店员培训流程与顾客接触的最佳时机有以下几个时刻: A.当顾客长时间凝视某一药品,若有所思时; B.当顾客抬起头来的时候; C.当顾客突然停下脚步时; D.当顾客的眼睛在搜寻时; E.当顾客与店员的眼光接触时; 此时,优秀的店员一般会以三种方式与顾客初步接触:与顾客随意打个招呼,直接向顾客介绍她中意的药品,询问顾客的购买意...https://www.360wenmi.com/f/filewe6cu523.html
11.星露谷莉亚行程在哪里莉亚时间表一般的行程 时间 地点 10:00 AM 早晨起来,在她的小屋里雕塑。 12:00 PM 离开小屋走到西面树林中的湖边。站在湖的西岸,凝视着水面。 4:00 PM 离开湖,走到树林中其他地方画画。 6:30 PM 回到树林中的湖边。站在湖的西岸,凝视着水面。 7:30 PM 离开树林,回到她的小屋里。 https://m.3733.com/news/159266.html