Caffeine技术可以参看深度文章缓存之王 Caffeine 架构、源码、原理 (5W长文)
常用的缓存技术为:
1、Caffeine cache:(推荐):Caffeine采用了W-TinyLFU(LUR和LFU的优点结合)开源的缓存技术。
缓存性能接近理论最优,属于是Guava Cache的增强版。建议使用cache.get(key,k - > value) 的方式,get 方法将一个参数为 key 的 Function (createExpensiveGraph) 作为参数传入。如果缓存中不存在该键,则调用这个 Function 函数,并将返回值作为该缓存的值插入缓存中。get 方法是以阻塞方式执行调用,即使多个线程同时请求该值也只会调用一次Function方法。这样可以避免与其他线程的写入竞争,这也是为什么使用 get 优于 getIfPresent 的原因。
2、Guava cache:Guava Cache是由Google开源的基于LRU替换算法的缓存技术,支持最大容量限制,两种过期删除策略(插入时间和访问时间),支持简单的统计功能。Spring已经放弃GUava改为用Caffeine.
3、Enchache:缓存支持堆内缓存,堆外缓存和磁盘缓存;支持多种集群方案,解决数据共享问题。缺点:性能比Caffeine差.
为何不用HashMap?因为HashMap没有缓存失效策略.
缓存的常用淘汰算法:
LFU: the least frequency used:最不经常食用算法(一段时间内,使用次数最低,最先置换或者清除),适合局部周期性流量.
TinyLFU:=LRU + ?LFU,解决LFU的三大问题设计出来的; 问题1和问题2 也就是访问频率修改和记录占用的时间和空间开销,采用Count-Min-Sketch算法解决;该算法看成是布隆过滤器的同源的数值版算法. 问题3用Caffeine的Freshness Mechanism来提出过往频率很高但之后不经常用的缓存.
W-TinyLFU:Caffeine采用的默认淘汰机制(和jvm的分代模型垃圾回收机制略同)
LRU:the least recently used:最近最少使用算法(最后一次使用时间距离当前替换时候的时间差,时间差越大,最先置换或者清除);适合局部突发流量;
LRU-K:增加队列记录历史访问次数,当访问次数大于k,才会进入缓存LRU队列.
LRU-Two-queue:一个FIFO队列,一个LRU队列,新元素首先进入FIFO队列,当再次访问才进入LRU队列;
FIFO:队列先进先出,最先访问的最先淘汰;
本地缓存考虑的三大关键因素:
1、本地缓存数据的预热问题:数据量很大时的预热时机和性能问题:
2、分布式集群节点本地缓存数据更新一致性问题:(可以采用JDHotKey或者Redis的广播队列)
3、本地缓存占用内存空间可控问题:是否存在冷数据突然预热,热数据暴增