caffeine学习笔记

在项目中使用了caffeine,本文将会介绍其工具的原理

1.caffenine的缓存淘汰策略

Window-TinyLFU

1.新增缓存数据首先写入 Window Cache 区域。当 Window Cache 空间满时,LRU 算法发挥作用,最久未被访问的缓存项会被移出 Window Cache 。这个被移出的缓存项称为 Candidate (候选项),将面临 2 种情况:

如果 Probation Cache 未满,从 Window Cache 中移出的缓存项会直接写入 Probation Cache 中;

如果 Probation Cache 已满,则进入到 TinyLFU 过滤器,与 Protected Cache 移出的缓存项比较。根据 TinyLFU 算法确定该缓存项是淘汰还是写入 Probation Cache。

2.Probation Cache 中的缓存项的访问频率达到一定次数后,就会晋升到 Protected Cache 中。(Ps. 到 Protected 保护区的都是经过 2 层选拔的真热门数据)如果 Protected Cache 也满了,根据 LRU 算法,最久未被访问的缓存项会被移出 Protected Cache ,降级成为 Candidate ,进入到 TinyLFU 过滤器,与 Window Cache 移出的缓存项作比较,根据 TinyLFU 算法确定该缓存项是淘汰还是写入到 Probation Cache 中。

3.此时把目光聚焦到 TinyLFU 过滤器,它汇聚了来自 Window Cache 、Protected Cache 和 Probation Cache 3 个区域中被移出的缓存项。其中,从 Window Cache 和 Protected Cache 中移出的缓存项称为 Candidate ;而从 Probation Cache 中移出的缓存项称为 Victim (受害者) 。这 3 个区域移出的缓存项都是各自区域中最久未被使用的数据,在 TinyLFU 过滤器中进行竞争,竞争算法如下:

如果 Candidate 的访问频率 > Victim 的访问频率,则直接淘汰 Victim ;

如果 Candidate 的访问频率 <= Victim 的访问频率,此时分为两种情况:

如果 Candidate 的访问频率 < 5 ,则淘汰 Candidate ;

如果 Candidate 的访问频率 >= 5 ,则在 Candidate 和 Victim 中随机淘汰一个。

获胜者被称为 Winner ,就会被写入到 Probation Cache 中。

从上面的 W-TinyLFU 的原理描述可知,Caffeine 综合了 LFU 和 LRU 的优势,将不同特性的缓存项存入不同的缓存区域,最近刚产生的缓存项进入 Window Cache 区,不会被淘汰;访问频率高的缓存项进入 Protected Cache 区,也不会淘汰;介于这两者之间的缓存项存在 Probation 区,当缓存空间满了时,Probation 区的缓存项会根据访问频率判断是保留还是淘汰。

通过这种机制,很好的平衡了访问频率和访问时间新鲜程度两个维度因素,尽量将新鲜的缓存项和访问频率高的缓存项都保留在缓存中。同时在维护缓存项访问频率时,引入计数器饱和和衰减 (Count-Min Sketch, 下面会说) 机制,即节省了存储资源,也能较好的处理稀疏流量、短时超热点流量等传统 LRU 和 LFU 无法很好处理的场景。

W-TinyLFU 算法

W-TinyLFU 算法使用 Count-Min Sketch 算法存储访问频率,极大地节省了空间。

看到一个通俗解释:如果需要记录一个值,那我们需要通过多种 Hash 算法对其进行处理,然后在对应的 Hash 算法的记录中 +1。那为什么需要多种 Hash 算法呢?由于这是一个压缩算法必定会出现冲突,比如我们建立一个 byte 的数组,通过计算出每个数据的 Hash 的位置。比如张三和李四,他们两有可能 Hash 值都是相同,比如都是 1 。那 byte[1] 这个位置就会增加相应的频率,张三访问 1 万次,李四访问 1 次,那 byte[1] 这个位置就是 1万零1 ,如果取李四的访问评率的时候就会取出是 1万零1 ,但是李四命名只访问了1次啊!为了解决这个问题,所以用了多个 Hash 算法,可以理解为 long[][] 二维数组的一个概念。比如在第一个 Hash 算法中,张三和李四冲突了,但是在第二个,第三个 Hash 算法中很大的概率不冲突,比如一个算法大概有 1% 的概率冲突,那四个算法一起冲突的概率是 1% 的四次方。通过这个模式我们取李四的访问率的时候取所有算法中,李四访问最低频率的次数。所以他的名字叫 Count-Min Sketch 。

2.caffeine的数据结构

复制代码
final ConcurrentHashMap<Object, Node<K, V>> data;

写入数据:

将节点添加到策略和数据存储中。如果找到现有节点,则在允许的情况下更新其值

根据不同的更新策略,计算缓存过期时间后数据塞入map中。数据写入后,增加定时任务。注意此时当未自定义线程池时,将会使用默认的forkjoinpool中的线程池,默认线程池可能会影响主程序的执行效率。

复制代码
@NonNull
  Executor getExecutor() {
    return (executor == null) ? ForkJoinPool.commonPool() : executor;
  }

淘汰数据:

操作ConcurrentHashMap类型的data数据,

相关推荐
AI视觉网奇2 分钟前
ue 推送直播流 推流 linux 实战
笔记·学习·ue5
Mr YiRan8 分钟前
C++语言学习之面向对象
java·c++·学习
kkkkkkkkk_120116 分钟前
【强化学习】09周博磊强化学习纲要学习笔记——第五课上
笔记·深度学习·学习·强化学习
玩c#的小杜同学19 分钟前
工业级稳定性:如何利用生产者-消费者模型(BlockingCollection)解决串口/网口高频丢包问题?
笔记·学习·性能优化·c#·软件工程
laplace012326 分钟前
deque+yield+next语法
人工智能·笔记·python·agent·rag
一品威客网29 分钟前
教育 APP 升级!跨端开发支持“多设备学习,无缝衔接”
学习
瑶光守护者36 分钟前
【学习笔记】3GPP NR-NTN 移动性IRAT分析
笔记·学习·卫星通信·nr-ntn
望忆1 小时前
关于《Generative Adversarial Framework for Cold-Start Item Recommendation》一文的学习
学习
杂鱼Tong2 小时前
29. Revit API:扩展存储(ExtensibleStorage)
笔记
saoys2 小时前
Opencv 学习笔记:图像卷积操作(锐化核实战 + 数据类型避坑)
笔记·opencv·学习