缓存设计总结
Posted 大军001
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了缓存设计总结相关的知识,希望对你有一定的参考价值。
常见的缓存实现方式有:FIFO,LRU,LFU。
使用顺序推荐:FIFO<LRU<LFU
FIFO
先进先出,所谓的先进先出就是对于先进入缓存中的数据进行优先淘汰的策略。这种策略虽然使用起来非常简单,实际上会导致命中率很低,效率很低。举个例子:有一个非常热门的数据,第一个进入队列的,然后先进先出淘汰的策略就会把这个热门的数据给淘汰掉,这样实际上是很不合理的,不推荐使用。
LRU
最近最少使用策略,顾名思义就是淘汰最近一段时间内使用频率最少的那些项,这个的算法策略是优于FIFO的,但是也有不合理的地方,例如:有一个很热门的数据在之前非常频繁的使用到,但是最近一段时间内由于没有怎么用到在淘汰的时候就被淘汰掉了,所以这是不太合理的;
LRU的具体实现方式可以参照我的另外一篇博客有详细解读:LRU算法
通过上述可知,Java自带的实现LRU缓存算法是通过LinkedHashMap实现的,这种方式会有以下几个问题:
(1)全局锁,锁的竞争会比较严重,尤其是当调用量比较大的时候,性能将会大打折扣。
(2)不支持过期时间的缓存过期策略,不太灵活。
(3)不支持自动刷新。
非常著名的Guava Cache就是提供了很好的缓存方案。它提供了基于容量,时间以及引用类型的缓存策略,其中基于容量的方式就是通过LRU算法实现的,不过它实现的方式是通过采用了类似ConcurrentHashMap的算法实现的,分段加锁,解决了LinkedHashMap中存在的全局加锁的问题;另外还可以通过缓存过期时间来设置缓存策略,这个同样也是比LinkedHashMap高级;最后Guava Cache还可以基于引用的类型来设置缓存策略,更加高级,Java引用类型可以看我的另外一篇博客:Java引用类型
基于Guava Cache的种种优点,所以平常一般不建议通过LinkedHashMap来实现缓存;Guava Cache是一种比较好的方式,但是下面将会有更优的方案来实现缓存算法。
LFU
最近最少频率使用,这种缓存算法相对上面两种又有了更高一级的优化,通过记录数据使用的频率,最终通过频率的高低进行淘汰,不过这样可能需要更高的空间(在现在来看磁盘空间已经不是什么问题了)。
其中高性能缓存Caffeine就是基于LFU算法实现的,具体参考我的另外一篇博客:高性能缓存Caffeine
以上是关于缓存设计总结的主要内容,如果未能解决你的问题,请参考以下文章
atitit。浏览器缓存机制 and 微信浏览器防止缓存的设计 attilax 总结