Caffeine--缓存组件
Caffeine
- 概念
- 缓存
- 手动加载
- 自动加载
- 手动异步加载
- 自动异步加载
- 驱逐策略
- 基于容量
- 基于时间
- 基于引用
- 移除
- 显式移除
概念
Caffeine是一个基于Java8开发的提供了近乎最佳命中率的高性能的缓存库。与ConcurrentMap有点相似。最根本的区别是ConcurrentMap将会持有所有加入到缓存当中的元素,直到它们被从缓存当中手动移除。Caffeine的缓存Cache 通常会被配置成自动驱逐缓存中元素,以限制其内存占用。在某些场景下,LoadingCache和AsyncLoadingCache尤为重要。
Caffeine提供了灵活的构造器去创建一个拥有下列特性的缓存:
(1)自动加载元素到缓存当中,异步加载的方式也可供选择
(2)当达到最大容量的时候可以使用基于就近度和频率的算法进行基于容量的驱逐
(3)将根据缓存中的元素上一次访问或者被修改的时间进行基于过期时间的驱逐
(4)当向缓存中一个已经过时的元素进行访问的时候将会进行异步刷新
(5)key将自动被弱引用所封装
(6)value将自动被弱引用或者软引用所封装
(7)驱逐(或移除)缓存中的元素时将会进行通知
(8)写入传播到一个外部数据源当中
(9)持续计算缓存的访问统计指标
缓存
Caffeine提供了四种缓存添加策略:手动加载,自动加载,手动异步加载和自动异步加载。
手动加载
Cache<String, String> cache = Caffeine.newBuilder().expireAfterWrite(10, TimeUnit.MINUTES).maximumSize(10000).build();// 查找一个缓存元素, 没有查找到的时候返回nullString s=cache.getIfPresent("xiaohei");// 查找缓存,如果缓存不存在则生成缓存元素, 如果无法生成则返回nulls= cache.get("xiaohei", k -> new String("啥也没有"));// 添加或者更新一个缓存元素cache.put("xiaohei1", new String());// 移除一个缓存元素cache.invalidate("xiaohei");
Cache 接口提供了显式搜索查找、更新和移除缓存元素的能力。
推荐使用cache.get(key, k -> value)操作来在缓存中不存在该key对应的缓存元素的时候进行计算生成并直接写入至缓存内,而当该key对应的缓存元素存在的时候将会直接返回存在的缓存值。一次 cache.put(key, value) 操作将会直接写入或者更新缓存里的缓存元素,在缓存中已经存在的该key对应缓存值都会直接被覆盖。也可以使用Cache.asMap()所暴露出来的ConcurrentMap的方法对缓存进行操作。
自动加载
LoadingCache<String, String> cache = Caffeine.newBuilder().maximumSize(10000).expireAfterWrite(10, TimeUnit.MINUTES).build(key -> new String("啥也没有"));
// 查找缓存,如果缓存不存在则生成缓存元素, 如果无法生成则返回nullString s = cache.get("xiaohei");
// 批量查找缓存,如果缓存不存在则生成缓存元素Map<String, String> map = cache.getAll(Arrays.asList(new String[]{"xiaohei1", "xiaohei2"}));
一个LoadingCache是一个Cache 附加上CacheLoader能力之后的缓存实现。默认情况下,在getAll 方法中,将会对每个不存在对应缓存的key调用一次CacheLoader.load来生成缓存元素。
手动异步加载
AsyncCache<String, String> cache = Caffeine.newBuilder().expireAfterWrite(10, TimeUnit.MINUTES).maximumSize(10000).buildAsync();// 查找一个缓存元素, 没有查找到的时候返回nullCompletableFuture<String> graph = cache.getIfPresent("xiaohei");// 查找缓存元素,如果不存在,则异步生成graph = cache.get("xiaohei", k -> new String("xiaoheissss"));// 添加或者更新一个缓存元素cache.put("xiaobai", graph);// 移除一个缓存元素cache.synchronous().invalidate("xiaohei");
一个AsyncCache是Cache的一个变体,AsyncCache提供了在Executor上生成缓存元素并返回 CompletableFuture的能力。这给出了在当前流行的响应式编程模型中利用缓存的能力。
synchronous()方法给Cache提供了阻塞直到异步缓存生成完毕的能力。也可以使用 AsyncCache.asMap()所暴露出来的ConcurrentMap的方法对缓存进行操作。默认的线程池实现是 ForkJoinPool.commonPool() ,也可以通过覆盖并实现 Caffeine.executor(Executor)方法来自定义线程池选择。
自动异步加载
AsyncLoadingCache<String, String> cache = Caffeine.newBuilder().maximumSize(10000).expireAfterWrite(10, TimeUnit.MINUTES)// 你可以选择: 去异步的封装一段同步操作来生成缓存元素.buildAsync(key -> new String(key));// 你也可以选择: 构建一个异步缓存元素操作并返回一个future
// .buildAsync((key, executor) -> createExpensiveGraphAsync(key, executor));// 查找缓存元素,如果其不存在,将会异步进行生成CompletableFuture<String> graph = cache.get("xiaohei");
// 批量查找缓存元素,如果其不存在,将会异步进行生成CompletableFuture<Map<String, String>> graphs = cache.getAll(Arrays.asList(new String[]{"xiaohei1", "xiaohei2"}));
一个 AsyncLoadingCache是一个AsyncCache加上AsyncCacheLoader能力的实现。在需要同步的方式去生成缓存元素的时候,CacheLoader是合适的选择。而在异步生成缓存的场景下,AsyncCacheLoader则是更合适的选择并且它会返回一个 CompletableFuture。默认情况下,在getAll 方法中,将会对每个不存在对应缓存的key调用一次 AsyncCacheLoader.asyncLoad 来生成缓存元素。 可以通过实现一个 AsyncCacheLoader.asyncLoadAll并在其中为没有在参数中请求的key也生成对应的缓存元素。如果对应某个key生成的缓存元素与包含这个key的一组集合剩余的key所对应的元素一致,那么在asyncLoadAll中也可以同时加载剩下的key对应的元素到缓存当中。
驱逐策略
基于容量
Caffeine提供了三种驱逐策略,分别是基于容量,基于时间和基于引用三种类型。
// 基于缓存内的元素个数进行驱逐
LoadingCache<String, String> graphs = Caffeine.newBuilder().maximumSize(10000).build(key -> new String(key));
// 基于缓存内元素权重进行驱逐
LoadingCache<String, String> graphs = Caffeine.newBuilder().maximumWeight(10000).weigher((String s, String s1) -> s1.length()).build(key -> new String(key));
基于缓存内的元素个数进行驱逐策略中,使用Caffeine.maximumSize(long)。缓存将会尝试通过基于就近度和频率的算法来驱逐掉不会再被使用到的元素。
缓存中的元素可能有不同的内存占用–需要借助Caffeine.weigher(Weigher)方法来界定每个元素的权重并通过 Caffeine.maximumWeight(long)方法来界定缓存中元素的总权重来实现上述的场景。在基于权重驱逐的策略下,一个缓存元素的权重计算是在其创建和更新时,此后其权重值都是静态存在的,在两个元素之间进行权重的比较的时候,并不会根据进行相对权重的比较。
基于时间
// 基于固定的过期时间驱逐策略LoadingCache<String, String> graphs1 = Caffeine.newBuilder().expireAfterAccess(5, TimeUnit.MINUTES).build(key -> new String());LoadingCache<String, String> graphs2 = Caffeine.newBuilder().expireAfterWrite(10, TimeUnit.MINUTES).build(key -> new String());// 基于不同的过期驱逐策略LoadingCache<String, String> graphs = Caffeine.newBuilder().expireAfter(new Expiry<String, String>() {@Overridepublic long expireAfterCreate(@NonNull String s, @NonNull String s2, long l) {return 0;}@Overridepublic long expireAfterUpdate(@NonNull String s, @NonNull String s2, long l, @NonNegative long l1) {return 0;}@Overridepublic long expireAfterRead(@NonNull String s, @NonNull String s2, long l, @NonNegative long l1) {return 0;}}).build(key -> new String());
expireAfterAccess(long, TimeUnit): 一个元素在上一次读写操作后一段时间之后,在指定的时间后没有被再次访问将会被认定为过期项。在当被缓存的元素时被绑定在一个session上时,当session因为不活跃而使元素过期的情况下,这是理想的选择。
expireAfterWrite(long, TimeUnit): 一个元素将会在其创建或者最近一次被更新之后的一段时间后被认定为过期项。在对被缓存的元素的时效性存在要求的场景下,这是理想的选择。
expireAfter(Expiry): 一个元素将会在指定的时间后被认定为过期项。当被缓存的元素过期时间收到外部资源影响的时候,这是理想的选择。
基于引用
// 当key和缓存元素都不再存在其他强引用的时候驱逐LoadingCache<String, String> graphs1 = Caffeine.newBuilder().weakKeys().weakValues().build(key -> new String());// 当进行GC的时候进行驱逐LoadingCache<String, String> graphs2 = Caffeine.newBuilder().softValues().build(key -> new String());
Caffeine 允许去让GC去帮助清理缓存当中的元素,其中key支持弱引用,而value则支持弱引用和软引用。AsyncCache不支持软引用和弱引用。
Caffeine.weakKeys():在保存key的时候将会进行弱引用。这允许在GC的过程中,当key没有被任何强引用指向的时候去将缓存元素回收。由于GC只依赖于引用相等性。这导致在这个情况下,缓存将会通过引用相等(==)而不是对象相等 equals()去进行key之间的比较。
Caffeine.weakValues():在保存value的时候将会使用弱引用。这允许在GC的过程中,当value没有被任何强引用指向的时候去将缓存元素回收。由于GC只依赖于引用相等性。这导致在这个情况下,缓存将会通过引用相等(==)而不是对象相等 equals()去进行value之间的比较。
Caffeine.softValues():在保存value的时候将会使用软引用。为了相应内存的需要,在GC过程中被软引用的对象将会被通过LRU算法回收。由于使用软引用可能会影响整体性能,我们还是建议通过使用基于缓存容量的驱逐策略代替软引用的使用。同样的,使用 softValues() 将会通过引用相等(==)而不是对象相等equals()去进行value之间的比较。
移除
驱逐:缓存元素因为策略被移除
失效:缓存元素被手动移除
移除:由于驱逐或者失效而最终导致的结果
显式移除
可以手动去让某个缓存元素失效而不是只能等待其因为策略而被驱逐。
// 失效key
cache.invalidate("小黑");
// 批量失效key
cache.invalidateAll(Arrays.asList(new String[]{"xiaohei1", "xiaohei2"}));
// 失效所有的key
cache.invalidateAll();
相关文章:
Caffeine--缓存组件
Caffeine 概念缓存手动加载自动加载手动异步加载自动异步加载 驱逐策略基于容量基于时间基于引用 移除显式移除 概念 Caffeine是一个基于Java8开发的提供了近乎最佳命中率的高性能的缓存库。与ConcurrentMap有点相似。最根本的区别是ConcurrentMap将会持有所有加入到缓存当中的…...
Centos7:Jenkins+gitlab+node项目启动(1)
Centos7:Jenkinsgitlabnode项目启动(1) Centos7:Jenkinsgitlabnode项目启动(1)-CSDN博客 Centos7:Jenkinsgitlabnode项目启动(2) Centos7:Jenkinsgitlabnode项目启动(2)-CSDN博客 Centos7:Jenkinsgitlabnode项目启…...
starrocks集群fe/be节点进程守护脚本
自建starrocks集群,有时候服务会挂掉,无法自动拉起服务,于是采用supervisor进行进程守护。可能是版本的原因,supervisor程序总是异常,无法对fe//be进行守护。于是写了个简易脚本。 #!/bin/bash AppNameFecom.starrock…...
奇富科技跻身国际AI学术顶级会议ICASSP 2024,AI智能感知能力迈入新纪元
近日,2024年IEEE声学、语音与信号处理国际会议ICASSP 2024(2024 IEEE International Conference on Acoustics, Speech, and Signal Processing)宣布录用奇富科技关于语音情感计算的最新研究成果论文“MS-SENet: Enhancing Speech Emotion Re…...
如何在Android Termux中使用SFTP实现远程传输文件
文章目录 1. 安装openSSH2. 安装cpolar3. 远程SFTP连接配置4. 远程SFTP访问5. 配置固定远程连接地址6、结语 SFTP(SSH File Transfer Protocol)是一种基于SSH(Secure Shell)安全协议的文件传输协议。与FTP协议相比,SFT…...
高频知识汇总 | 【操作系统】面试题汇总(万字长博通俗易懂)
前言 这篇我亲手整理的【操作系统】资料,融入了我个人的理解。当初我在研习八股文时,深感复习时的困扰,网上资料虽多,却过于繁杂,有的甚至冗余。例如,文件管理这部分,在实际面试中很少涉及&…...
【前端框架】NPM概述及使用简介
什么是 NPM npm之于Node,就像pip之于Python,gem之于Ruby,composer之于PHP。 npm是Node官方提供的包管理工具,他已经成了Node包的标准发布平台,用于Node包的发布、传播、依赖控制。npm提供了命令行工具,使你可以方便地下载、安装、升级、删除包,也可以让你作为开发者发布…...
C# LINQ
一、前言 学习心得:C# 入门经典第8版书中的第22章《LINQ》 二、LINQ to XML 我们可以通过LINQ to XML来创造xml文件 如下示例,我们用LINQ to XML来创造。 <Books><CSharp Time"2019"><book>C# 入门经典</book><…...
云原生机器学习平台cube-studio开源项目及代码简要介绍
1. cube-studio介绍 云原生机器学习平台cube-studio介绍:https://juejin.cn/column/7084516480871563272 cube-studio是开源的云原生机器学习平台,目前包含特征平台,支持在/离线特征;数据源管理,支持结构数据和媒体标…...
大小端存储是什么鬼?
以下内容为本人的著作,如需要转载,请声明原文链接 微信公众号「ENG八戒」https://mp.weixin.qq.com/s/htYGddzO2xPl9kDN4lANpQ 大小端存储的划分是为了解决长度大于一个字节的数据类型内容在存储地址上以不同顺序分布的问题。 比如16位的short整形&…...
WEB:探索开源PDF.js技术应用
1、简述 PDF.js 是一个由 Mozilla 开发的开源 JavaScript 库,用于在浏览器中渲染 PDF 文档。它的目标是提供一个纯粹的前端解决方案,摆脱了依赖插件或外部程序的束缚,使得在任何支持 JavaScript 的浏览器中都可以轻松地显示 PDF 文档。 2、…...
数据分析之词云图绘制
试验任务概述:如下为所给CSDN博客信息表,分别汇总了ai, algo, big-data, blockchain, hardware, math, miniprog等7个标签的博客。对CSDN不同领域标签类别的博客内容进行词频统计,绘制词频统计图,并根据词频统计的结果绘制词云图。…...
【赠书第13期】边缘计算系统设计与实践
文章目录 前言 1 硬件架构设计 2 软件框架设计 3 网络结构设计 4 安全性、可扩展性和性能优化 5 推荐图书 6 粉丝福利 前言 边缘计算是一种新兴的计算模式,它将计算资源推向网络边缘,以更好地满足实时性、低延迟和大规模设备连接的需求。边缘计算…...
数据库01_增删改查
1、什么是数据?什么是数据库? 数据:描述事物的符号记录称为数据。数据是数据库中存储的基本对象。数据库:存放数据的仓库,数据库中可以保存文本型数据、二进制数据、多媒体数据等数据 2、数据库的发展 第一阶段&…...
MySQL——进阶篇
二、进阶篇🚩 1. 存储引擎🍆 1.1 MSQL体系结构 连接层: 连接处理,连接认证,每个客户端的权限 服务层: 绝大部分核心功能,可跨存储引擎 可插拔存储引擎: 需要的时候可以添加或拔掉…...
Python 网络编程之搭建简易服务器和客户端
用Python搭建简易的CS架构并通信 文章目录 用Python搭建简易的CS架构并通信前言一、基本结构二、代码编写1.服务器端2.客户端 三、效果展示总结 前言 本文主要是用Python写一个CS架构的东西,包括服务器和客户端。程序运行后在客户端输入消息,服务器端会…...
往年面试精选题目(前50道)
常用的集合和区别,list和set区别 Map:key-value键值对,常见的有:HashMap、Hashtable、ConcurrentHashMap以及TreeMap等。Map不能包含重复的key,但是可以包含相同的value。 Set:不包含重复元素的集合&#…...
解决服务器Tab键不能补全问题
编辑~/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-keyboard-shortcuts.xml 命令:vim ~/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-keyboard-shortcuts.xml替换:<property name“<Super>Tab” type“string” value“switch_window…...
人工智能 机器学习 深度学习:概念,关系,及区别说明
如果过去几年,您读过科技主题的文章,您可能会遇到一些新词汇,如人工智能(Artificial Intelligence)、机器学习(Machine Learning)和深度学习(Deep Learning)等。这三个词…...
数据库——LAMP的搭建及MySQL基操
1.实验内容及原理 1. 在 Windows 系统中安装 VMWare 虚拟机,在 VMWare 中安装 Ubuntu 系统,并在 Ubuntu 中搭建 LAMP 实验环境。 2. 使用 MySQL 进行一些基本操作: (1)登录 MySQL,在 MySQL 中创建用户,并对…...
利用最小二乘法找圆心和半径
#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...
挑战杯推荐项目
“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 - 个性化梦境…...
大话软工笔记—需求分析概述
需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...
浪潮交换机配置track检测实现高速公路收费网络主备切换NQA
浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求,本次涉及的主要是收费汇聚交换机的配置,浪潮网络设备在高速项目很少,通…...
人机融合智能 | “人智交互”跨学科新领域
本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...
MySQL 部分重点知识篇
一、数据库对象 1. 主键 定义 :主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 :确保数据的完整性,便于数据的查询和管理。 示例 :在学生信息表中,学号可以作为主键ÿ…...
日常一水C
多态 言简意赅:就是一个对象面对同一事件时做出的不同反应 而之前的继承中说过,当子类和父类的函数名相同时,会隐藏父类的同名函数转而调用子类的同名函数,如果要调用父类的同名函数,那么就需要对父类进行引用&#…...
AI语音助手的Python实现
引言 语音助手(如小爱同学、Siri)通过语音识别、自然语言处理(NLP)和语音合成技术,为用户提供直观、高效的交互体验。随着人工智能的普及,Python开发者可以利用开源库和AI模型,快速构建自定义语音助手。本文由浅入深,详细介绍如何使用Python开发AI语音助手,涵盖基础功…...
