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,表示该分支属于一个特性开发&…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...

【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...

跨链模式:多链互操作架构与性能扩展方案
跨链模式:多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈:模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展(H2Cross架构): 适配层…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案
随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
重启Eureka集群中的节点,对已经注册的服务有什么影响
先看答案,如果正确地操作,重启Eureka集群中的节点,对已经注册的服务影响非常小,甚至可以做到无感知。 但如果操作不当,可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...

vulnyx Blogger writeup
信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面,gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress,说明目标所使用的cms是wordpress,访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...

数学建模-滑翔伞伞翼面积的设计,运动状态计算和优化 !
我们考虑滑翔伞的伞翼面积设计问题以及运动状态描述。滑翔伞的性能主要取决于伞翼面积、气动特性以及飞行员的重量。我们的目标是建立数学模型来描述滑翔伞的运动状态,并优化伞翼面积的设计。 一、问题分析 滑翔伞在飞行过程中受到重力、升力和阻力的作用。升力和阻力与伞翼面…...