Caffeine Cache解析(一):接口设计与TinyLFU
Caffeine is a high performance Java caching library providing a near optimal hit rate.
- 自动加载value, 支持异步加载
- 基于size的eviction:frequency and recency
- 基于时间的过期策略:last access or last write
- 异步更新value
- key支持weak reference
- value支持weak reference和soft reference
- 淘汰(或移除)通知
- todo
- 缓存获取数据统计
Caffeine的性能benchmark可参考Caffeine Benchmarks,
可以看到Caffeine在不同读写比的情况下, 吞吐量比Guava Cache和Jdk内置的HashMap都有较大提升。
接下来了解下Caffeine的使用、接口设计和TinyLFU简介。
使用
// manual cache,Cache-Aside模式Cache<String, String> cache = Caffeine.newBuilder().expireAfterWrite(Duration.ofHours(1)).build();// null表示不存在key@Nullable String val = cache.getIfPresent("hello");if (val == null) {cache.put("hello", "world");}// key不存在则走后面的loading functionString val2 = cache.get("hello", key -> "world");// loading cache,Read-Through模式LoadingCache<String, String> loadingCache = Caffeine.newBuilder().expireAfterAccess(Duration.ofMinutes(10)).maximumSize(2000).build(new CacheLoader<String, String>() {@Overridepublic @Nullable String load(@NonNull String s) throws Exception {// your loading logicreturn "";}});// 不存在会自动loadingString val3 = loadingCache.get("hello");
接口设计
CacheCache按不同维度划分:
- kv是否有限:Bounded or Unbounded,判断参见方法
com.github.benmanes.caffeine.cache.Caffeine#isBounded
,大部分场景都使用BoundedCache - 是否自动loading: ManualCache和LoadingCache
- 是否异步: Cache和AsyncCache
对应接口UML如下(实现类只画出了BoundedCache),其接口和类均位于com.github.benmanes.caffeine.cache
包下:
可以看到,核心的kv存储是放在了LocalCache
接口(本质是一个ConcurrentMap
)下,而其他的Loading和Async接口在存储基础上附加了自动加载value和异步加载的能力,以同步接口为例,接口能力如下:
Cache
: 提供缓存基础能力,包含设置、读取、失效、获取缓存统计数据等功能;LoadingCache
: 提供自动加载能力,在Cache
基础上新增不存在则loading value的读取以及refresh方法;LocalCache
: 提供核心存储能力,线程安全和原子能力保证,继承自java.util.concurrent.ConcurrentMap
;LocalManualCache
: 基于LocalCache
做存储的非自动Loading Cache;LocalLoadingCache
: 继承自LocalManualCache
,新增Loading功能。
关于以上接口的一个关键抽象实现类BoundedLocalCache
,其作用解释如下:
This class performs a best-effort bounding of a ConcurrentHashMap using a page-replacement algorithm to determine which entries to evict when the capacity is exceeded.
TinyLFU & W-TinyLFU
在看BoundedLocalCache
类前先来了解下TinyLFU & W-TinyLFU算法,
算法出自论文:TinyLFU: A Highly Efficient Cache Admission Policy
- admission policy:控制一个元素是否能进入缓存
- eviction policy:当缓存满了时选择哪一个元素剔除缓存
论文中提出的TinyLFU指的是admission policy,
TinyLFU可以和 LRU 、SLRU 的eviction policy组合。
比如 论文中使用W-TinyLFU + LRU + SLRU的组合进行实验:
Window Tiny LFU (W-TinyLFU) … consists of two cache areas.
The main cache employs the SLRU eviction policy and TinyLFU admission policy
while the window cache employs an LRU eviction policy without any admission policy.
可以看到 W-TinyLFU 的main cache area 使用 TinyLFU 作为 admission policy。
TinyLFU 在 LFU的基础上 加了Tiny,而Tiny体现在counter计数(和frequency正相关) 的记录上。
通常大部分缓存的元素访问频率都会很小,如果使用integer来记录counter计数,会导致空间浪费,因此
TinyLFU 借助 approximate counting scheme
来记录counter计数,其原理和bloom filter类似,而 schema的具体实现有:
Counting Bloom Filter
CM-Sketch
: Caffeine中使用该实现,参见类com.github.benmanes.caffeine.cache.FrequencySketch
,论文可参考:An Improved Data Stream Summary: The Count-Min Sketch and its Applications
Caffeine中的CM-Sketch
使用4bit记录counter次数,最大只能到15,
并使用long[]
类型存储,一个元素可存储16个计数器,long[]
即相当于论文中的二维数组。
此外还增加了一个DoorKeeper
即一个Bloom Filter
来优先存储读取次数为1的元素,次数大于1的才会进入CM-Sketch
结构中。
此外,TinyLFU利用Freshness Mechanism保证TinyLFU计数器记录的次数不会无限制扩大:
Every time we add an item to the approximation sketch, we increment a counter.
Once this counter reaches the sample size (W), we divide it and all other counters in the
approximation sketch by 2.
对应的可以在FrequencySketch
类的increment
方法中找到reset
方法的调用:
// This class maintains a 4-bit CountMinSketch.
// The maximum frequency of an element is limited to 15 (4-bits)
// and an aging process periodically halves the popularity of all elements.
final class FrequencySketch<E> {...int sampleSize;int size;public void ensureCapacity(@NonNegative long maximumSize) {...sampleSize = (maximumSize == 0) ? 10 : (10 * maximum);if (sampleSize <= 0) {sampleSize = Integer.MAX_VALUE;}size = 0;}// 计数器次数小于15时才会增加计数器public void increment(@NonNull E e) {...boolean added = ...if (added && (++size == sampleSize)) {reset();}}...
}
相关文章:

Caffeine Cache解析(一):接口设计与TinyLFU
Caffeine is a high performance Java caching library providing a near optimal hit rate. 自动加载value, 支持异步加载基于size的eviction:frequency and recency基于时间的过期策略:last access or last write异步更新valuekey支持weak referenceva…...

深入探索LINUX中AWK命令:强大的文本处理工具
深入探索LINUX中AWK命令:强大的文本处理工具 AWK 是一种编程语言,专为文本和数据处理设计,它以其强大的文本处理能力和简洁的语法在 Unix/Linux 系统中占据了重要地位。AWK 程序由一系列的模式(pattern)和动作(action)组成,对于输…...

数字化转型:解决项目管理困境的新路径
在当今这个飞速发展的数字化时代,企业如同在汹涌波涛中航行的船只,承受着前所未有的变革压力。而作为企业运作核心环节之一的项目管理,同样面临着巨大的挑战。 传统项目管理模式中的种种问题,犹如顽固的礁石,阻碍着项目…...

Arthas常用的命令(三)--monitor、jad 、stack
monitor:监控方法的执行情况 监控指定类中方法的执行情况 用来监视一个时间段中指定方法的执行次数,成功次数,失败次数,耗时等这些信息 参数说明 方法拥有一个命名参数 [c:],意思是统计周期(cycle of ou…...

Power BI之常用DAX函数使用介绍——提供数据源练习
前述: 本次使用数据是包含产品表、客户表、区域表、销售订单表的一份销售订单数据,数据源链接如下: 链接:https://pan.baidu.com/s/1micl_09hFrgz2aUBERkeZg 提取码:y17e 一、CALCULATE 1.语法结构 语法结构CALCUL…...

SQL-触发器(trigger)的详解以及代码演示
一、触发器的概念 触发器是一种特殊的存储过程,但是触发器不存在输入和输出参数,所以不能被显式的去调用,而是与特定的表相关联,当表中的数据发生变化时,触发器被激活并执行其定义的SQL代码。触发器可以是行级触发器&…...

【devops】x-ui 实现一键安装 x-ray 打造高速国际冲浪 | xray管理平台
一、部署X-UI篇 1、Github 地址&说明 github地址如下: https://github.com/FranzKafkaYu/x-ui?tabreadme-ov-file 2、一键部署 2.1、更新并安装curl #Ubuntu、Deibian系统 apt update && apt upgrade -y apt install curl -y #CentOS7 系统 yum…...

Linux系统编程——进程标识、进程创建
一、进程标识(pid) 每个进程都有一个非负整数形式的唯一编号,即 PID。PID 在任何时刻都是唯一的,但是可以重用,当进程终止并被回收以后,其 PID 就可以为其它进程所用。进程的 PID 由系统内核根据延迟重用算…...

【超级福利】openMind开源实习来袭,奖励高达万元,解锁你的AI实践新篇章!
亲爱的小伙伴们,是不是梦想着能在真实的项目中大展拳脚,却又苦于找不到合适的舞台?别担心,OpenI启智社区携手openMind Library工具链,为你量身打造了一场开源实习盛宴,保证让你的学习不再无聊,技…...

React JSX 使用条件语句渲染UI的两种写法
只针对函数组件 1. 第一种写法: function App({ id }) {return id1? <h1>hello</h1> : <h1>world</h1>; } 或者: function App({ id }) {return (<h1>{id1 && "hello" || id2 && "wo…...

谷歌-BERT-第四步:模型部署
1 需求 需求1:基于gradio实现大模型的WEB UI交互界面 2 接口 3 示例 import gradio as gr from transformers import *classifier pipeline("text-classification", model"./model", tokenizer"./model")gr.Interface.from_pipel…...

猫咪化身蒲公英,浮毛满屋乱飞,有哪些宠物空气净化器值得购买?
不掉毛的猫咪究竟是谁在养? 当初去朋友家玩,被猫咪捕获芳心,没多久自己也领养了一只。没想到啊,这就意味着要和猫毛纠缠一辈子了。平时白天上班不在家,它就在一边跑动一边掉毛,回到家我都能推断它的行动路…...

端到端的开源OCR模型:GOT-OCR-2.0,支持场景文本、文档、乐谱、图表、数学公式等内容识别!
今天给大家分享一个端到端的开源 OCR 模型,号称 OCR 2.0! 支持场景文本、文档、乐谱、图表、数学公式等内容识别,拿到了 BLEU 0.972 高分。 从给出的演示图来看,一些非常复杂的数学公式都能正确的识别,颇为强大。模型…...

自注意力机制self-attention中QKV矩阵的含义
自注意力机制(Self-Attention)是Transformer模型的核心组件,其中Q、K、V矩阵分别代表查询(Query)、键(Key)、值(Value)。它们的作用和含义可以通过信息匹配过程来理解。在…...

【前端】Bootstrap:栅格系统 (Grid System)
Bootstrap的栅格系统是该框架的核心部分之一,能够让开发者轻松创建响应式网页布局,适配各种屏幕尺寸和设备。栅格系统通过将页面划分为12列的布局结构,开发者可以根据内容的重要性和设计需求灵活控制元素的宽度和排列。 在这篇文章中&#x…...

一文读懂,SSL证书怎么验签安装使用?
SSL证书目前已经有越来越多的企业网站开始使用,安装SSL证书后,原有的http协议将会变成安全性更好的https加密协议,这对保护用户的信息安全,保障企业及用户的利益起着重要作用。 一张SSL证书的获取,需要经历不少环节&a…...

Mysql(八) --- 视图
文章目录 前言1.什么是视图?2.创建视图3. 使用视图4. 修改数据4.1.注意事项 5. 删除视图6.视图的优点 前言 前面我们学习了索引,这次我们来学习视图 1.什么是视图? 视图是一个虚拟的表,它是基于一个或多个基本表或其他视图的查询…...

SQL注入原理、类型、危害与防御
SQL注入的原理概念 SQL注入是一种常见的网络攻击技术,攻击者通过在Web应用程序的输入字段中注入恶意构造的SQL代码,以欺骗后端数据库执行非预期的SQL命令。这种攻击可以导致数据泄露、权限提升、数据篡改甚至系统瘫痪。SQL注入可以分为多种类型…...

第2讲 数据库系统的结构抽象与演变
基本内容 数据库系统的标准结构?数据模型?数据库系统的演变与发展?重难点 一组概念的区分:三级模式两层映像,物理独立性和逻辑独立性一组概念的区分:数据→模式→数据模型几种数据模型的差异:网状/层次模型→关系模型→数据模型数据库系统的标准结构 (1)数据库系统的分…...

Git创建开发分支命名规则
git checkout -b feature/branchname 和 git checkout -b branchname 这两条命令的主要区别在于新分支的命名。 主要区别 分支命名: git checkout -b feature/branchname:新分支的名字是 feature/branchname,表示该分支属于一个特性开发&…...

【纯前端excel导出】vue2纯前端导出excel,使用xlsx插件,修改样式、合并单元格
一、使用第三方插件 1、安装 npm install xlsx-js-style 2、引入 import xlsx from xlsx-js-style xlsx插件是基础的导出,不可以修改样式,直接xlsx-style插件式修改样式的,所以这里直接用二者合体插件即可 二、页面使用 1、数据源 [{"…...

如何在极速浏览器中实现谷歌浏览器的扩展功能
在当今数字化时代,浏览器扩展功能极大地增强了我们的在线体验。尤其是谷歌浏览器,以其丰富的扩展生态而闻名。但是,如果你想在极速浏览器中使用这些谷歌浏览器的扩展功能,该怎么办呢?本文将为你详细解析如何实现这一目…...

Web安全 - 跨站点请求伪造CSRF(Cross Site Request Forgery)
文章目录 OWASP 2023 TOP 10CSRF 导图CSRF的基本概念CSRF的工作原理常见CSRF攻击模式CSRF防御策略补充建议应用场景实战防御策略选择1. CSRF Token(首选)2. SameSite Cookie属性3. 验证Referer和Origin4. 多因素认证 实现方案CSRF Token实现SameSite Coo…...

C++游戏开发完整学习路径
C游戏开发完整学习路径 引言 随着游戏行业的迅速发展,C作为主要的游戏开发语言,因其高效性和灵活性,依然受到广泛欢迎。C不仅在大型游戏开发中被广泛使用,而且在游戏引擎的构建、性能优化和复杂算法的实现中也扮演着关键角色。本…...

vue3之 shallowRef、markRaw
shallowRef 用于创建一个浅层响应式引用,只对顶层属性进行响应式处理。 markRaw 用于标记一个对象,使其完全跳过 Vue 的响应式系统。 这两者都可以用于优化性能,避免不必要的响应式开销,特别是在处理大型对象或第三方库对象时。 …...

影刀RPA实战:操作Mysql数据库
1.摘要 影刀RPA(Robotic Process Automation)是一种软件自动化工具,它可以模拟人类用户执行各种重复性任务,其中包括对数据库的操作。 我们可以使用软件自动化指令,通过获取数据库窗口对象来操作数据库,也…...

【c++】c++11多线程开发
2 C多线程 本文是参考爱编程的大丙c多线程部分内容,按照自己的理解对其进行整理的一篇学习笔记,具体一些APi的详细说明请参考大丙老师教程。 代码性能的问题主要包括两部分的内容,一个是前面提到资源的获取和释放,另外一个就是多…...

PW37R_V1 产品规格书
概述 PW37R_V1是一款采用3.7英寸黑白红三色电子纸显示的电子标签,采用一种先进的无线自动更新系统,实现无线传输。 通过http,mqtt协议更新数据和控制该款电子标签的显示等操作,显示内容可自定义。内置电池供电,可Typ…...

android11 usb摄像头添加多分辨率支持
部分借鉴于:https://blog.csdn.net/weixin_45639314/article/details/142210634 目录 一、需求介绍 二、UVC介绍 三、解析 四、补丁修改 1、预览的限制主要存在于hal层和framework层 2、添加所需要的分辨率: 3、hal层修改 4、frameworks 5、备…...

【开源免费】基于SpringBoot+Vue.JS房屋租赁系统(JAVA毕业设计)
本文项目编号 T 020 ,文末自助获取源码 \color{red}{T020,文末自助获取源码} T020,文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 查…...