缓存
什么是缓存?
存贮数据(使用频繁的数据)的临时地方,因为取原始数据的代价太大了,所以我可以取得快一些。
Cache hit & Cache miss 的定义理解
Cache miss之后怎么办?
如果缓存区还有空间,可以把该次请求的数据存到缓存区
如果缓存慢了,又没有命中缓存,那么建立替换算法,将缓存区中的outdated的数据替换掉
存储成本
当缓存没有数据,我们从数据库中取得数据,存到缓存的时空成本
。
索引成本
为缓存构建索引的时空成本
。
缓存算法
Least Frequently Used (LFU)
我是LFU
,我会统计每一个缓存数据的使用频率,我会把使用最少的缓存替换出缓存区。
Least Recently Used (LRU)
我会把最近最少使用的缓存数据踢走。
浏览器就是使用了我(LRU)作为缓存算法。新的对象会被放在缓存的顶部,当缓存达到了容量极限,我会把底部的对象踢走,而技巧就是:我会把最新被访问的缓存对象,放到缓存池的顶部。
所以,经常被读取的缓存对象就会一直呆在缓存池中。有两种方法可以实现我,array 或者是 linked list。
LRU2
和2Q
是我的兄弟,他们是为了完善我而存在的。
Least Recently Used 2
我会把访问过两次的对象放进缓存区。
因为需要跟踪访问对象2次,所以随着数据量增多,访问负载和存储成本都会变多。
2 Queues (2Q)
我会把访问到的对象存到LRU中,如果这个对象被再次访问,那么把他放到第二个,更大的LRU中。
我踢走缓存对象是保持第一个缓存池是第二个缓存池的1/3.
当缓存的访问负载是固定的时候,把LRU换成LRU2,会比增加LRU的容量更好。
我的性能比前两者更出色,并且我是adoptive to access
模式。
Adaptive Replacement Cache
我由两个LRU组成。
第一个L1, 包含的是最近只被使用过一次的。
第二个L2, 包含的是使用过两次的对象。
我能够自调,并且是低负载的。我也保存着历史对象,这样,我就可以记住那些被移除的对象,同时,也让我可以看到被移除的对象是否可以留下,取而代之的是踢走别的对象。
Most Recently Used (MRU)
MRU是和LRU相对立的,MRU会移除最近最多使用的对象。why?
在缓存系统中找出最少最近的对象是需要较高的时空成本。
MRU是:每当有一次请求,就会把这个访问的对象放到栈顶,当栈满了,我就会用新请求的对象来替换栈顶的对象。
FIFO
低负载,低效管理的方法。
Second Chance
再来一次机会的缓存算法,是对FIFO的优化。
SC跟FIFO一样,在队首观察元素,进行踢出。
不同的是,SC对每一个对象都多了一个标志位,每次新加入队列的对象,标志位都为1。如果在队首要踢出该元素,则把他的标志位置0,重新加入队列,相当于给他第二次机会。如果该踢出元素的标志位是0,则直接将他踢出。
CLock
CLock是一个更好的环形FIFO。
Clock的头部指针指向队列中最老的对象。当缓存miss发生,同时没有存储空间时,我会首先检查指针指向的对象的标志位的状态,再决定操作,如果标志是0,我会直接用新数据替换这个老对象;如果标志是1,则会指针向前走一步,同时重复上一个步骤。直到新的缓存对象被放入。
Simple time-based
我会对新增的对象加以保存周期,同时去掉周期失效的对象。
参考
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。