缓存分享(1)——Guava Cache原理及最佳实践

news2024/11/16 3:37:19

Guava Cache原理及最佳实践

  • 1. Guava Cache是什么
    • 1.1 简介
    • 1.2 核心功能
    • 1.3 适用场景
  • 2. Guava Cache的使用
    • 2.1 创建LoadingCache缓存
    • 2.2 创建CallableCache缓存

缓存的种类有很多,需要根据不同的应用场景来选择不同的cache,比如分布式缓存如redis、memcached,还有本地(进程内)缓存如:ehcache、GuavaCache、Caffeine。本篇主要围绕全内存缓存-Guava Cache做一些详细的讲解和分析。

1. Guava Cache是什么

1.1 简介

Guava cache是一个支持高并发的线程安全的本地缓存。多线程情况下也可以安全的访问或者更新Cache。这些都是借鉴了ConcurrentHashMap的结果,不过,guava cache 又有自己的特性 :

"automatic loading of entries into the cache"

即 :当cache中不存在要查找的entry的时候,它会自动执行用户自定义的加载逻辑,加载成功后再将entry存入缓存并返回给用户未过期的entry,如果不存在或者已过期,则需要load,同时为防止多线程并发下重复加载,需要先锁定,获得加载资格的线程(获得锁的线程)创建一个LoadingValueRefrerence并放入map中,其他线程等待结果返回。

1.2 核心功能

  • 自动将entry节点加载进缓存结构中;
  • 当缓存的数据超过设置的最大值时,使用LRU算法移除;
  • 具备根据entry节点上次被访问或者写入时间计算它的过期机制;
  • 缓存的key被封装在WeakReference引用内;
  • 缓存的Value被封装在WeakReferenceSoftReference引用内;
  • 统计缓存使用过程中命中率、异常率、未命中率等统计数据。

小结:
Guava Cache说简单点就是一个支持LRU的ConcurrentHashMap,并提供了基于容量,时间和引用的缓存回收方式。(简单概括)

1.3 适用场景

  • 愿意消耗一些内存空间来提升速度(以空间换时间,提升处理速度);
    • 能够预计某些key会被查询一次以上;
    • 缓存中存放的数据总量不会超出内存容量(Guava Cache是单个应用运行时的本地缓存)。
  • 计数器(如可以利用基于时间的过期机制作为限流计数)

2. Guava Cache的使用

GuavaCache使用时主要分二种模式:LoadingCacheCallableCache
核心区别在于:LoadingCache创建时需要有合理的默认方法来加载或计算与键关联的值,CallableCache创建时无需关联固定的CacheLoader使用起来更加灵活。

前置准备:

// RPC调用方法,用于获取数据
private static List<String> rpcCall(String cityId) {
    // 模仿从数据库中取数据
    try {
        switch (cityId) {
            case "0101":
	            System.out.println("load cityId:" + cityId);
                return ImmutableList.of("上海", "北京", "广州", "深圳");
        }
    } catch (Exception e) {
        // 记日志
    }
    return Collections.EMPTY_LIST;
}

2.1 创建LoadingCache缓存

使用CacheBuilder来构建LoadingCache实例,可以链式调用多个方法来配置缓存的行为。其中CacheLoader可以理解为一个固定的加载器,在创建LoadingCache时指定,然后简单地重写V load(K key) throws Exception方法,就可以达到当检索不存在的时候自动加载数据的效果。

//创建一个LoadingCache,并可以进行一些简单的缓存配置
private static LoadingCache<String, Optional<List<String>> > loadingCache = CacheBuilder.newBuilder()
    //配置最大容量为100,基于容量进行回收
    .maximumSize(100)
    //配置写入后多久使缓存过期-下文会讲述
    .expireAfterWrite(3, TimeUnit.SECONDS)
    //配置写入后多久刷新缓存-下文会讲述
    .refreshAfterWrite(3, TimeUnit.SECONDS)
    //key使用弱引用-WeakReference
    .weakKeys()
    //当Entry被移除时的监听器
    .removalListener(notification -> System.out.println("notification=" + notification))
    //创建一个CacheLoader,重写load方法,以实现"当get时缓存不存在,则load,放到缓存并返回的效果
    .build(new CacheLoader<String, Optional<List<String>>>() {
        //重点,自动写缓存数据的方法,必须要实现
        @Override
        public Optional<List<String>> load(String cityId) throws Exception {
            return Optional.ofNullable(rpcCall(cityId));
        }
        //异步刷新缓存-下文会讲述
        @Override
        public ListenableFuture<Optional<List<String>>> reload(String cityId, Optional<List<String>> oldValue) throws Exception {
            return super.reload(cityId, oldValue);
        }
    });

// 测试
public static void main(String[] args) {

    try {
        System.out.println("load from cache once : " + loadingCache.get("0101").orElse(Lists.newArrayList()));
        Thread.sleep(4000);
        System.out.println("load from cache two : " + loadingCache.get("0101").orElse(Lists.newArrayList()));
        Thread.sleep(2000);
        System.out.println("load from cache three : " + loadingCache.get("0101").orElse(Lists.newArrayList()));
        Thread.sleep(2000);
        System.out.println("load not exist key from cache : " + loadingCache.get("0103").orElse(Lists.newArrayList()));

    } catch (ExecutionException | InterruptedException e) {
        //记录日志
    }
}

执行结果
在这里插入图片描述

2.2 创建CallableCache缓存

在上面的build方法中是可以不用创建CacheLoader的,不管有没有CacheLoader,都是支持Callable的。Callable在get时可以指定,效果跟CacheLoader一样,区别就是两者定义的时间点不一样,Callable更加灵活,可以理解为Callable是对CacheLoader的扩展。CallableCache的方式最大的特点在于可以在get的时候动态的指定load的数据源

//创建一个callableCache,并可以进行一些简单的缓存配置
private static Cache<String, Optional<List<String>>> callableCache = CacheBuilder.newBuilder()
    //最大容量为100(基于容量进行回收)
    .maximumSize(100)
    //配置写入后多久使缓存过期-下文会讲述
    .expireAfterWrite(3, TimeUnit.SECONDS)
    //key使用弱引用-WeakReference
    .weakKeys()
    //当Entry被移除时的监听器
    .removalListener(notification -> System.out.println("notification=" + notification))
    //不指定CacheLoader
    .build();

// 测试
public static void main(String[] args) {
    try {
        System.out.println("load from callableCache once : " + callableCache.get("0101", () -> Optional.ofNullable(rpcCall("0101"))).orElse(Lists.newArrayList()));
        Thread.sleep(4000);
        System.out.println("load from callableCache two : " + callableCache.get("0101", () -> Optional.ofNullable(rpcCall("0101"))).orElse(Lists.newArrayList()));
        Thread.sleep(2000);
        System.out.println("load from callableCache three : " + callableCache.get("0101", () -> Optional.ofNullable(rpcCall("0101"))).orElse(Lists.newArrayList()));
        Thread.sleep(2000);
        System.out.println("load not exist key from callableCache : " + callableCache.get("0103", () -> Optional.ofNullable(rpcCall("0103"))).orElse(Lists.newArrayList()));
    } catch (ExecutionException | InterruptedException e) {
        //记录日志
    }
}

执行结果:
在这里插入图片描述

后续待补充

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1638097.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

帕金森患者应该怎么注意生活方式?

在面对帕金森病的挑战时&#xff0c;科学合理地改善日常生活方式&#xff0c;不仅能帮助患者更好地管理病情&#xff0c;还能提升生活质量。今天&#xff0c;让我们一起探索如何通过简单的日常调整&#xff0c;为患有帕金森病的朋友们带来积极的变化。 饮食调整&#xff1a;营养…

MATLAB 函数

MATLAB 函数 函数是一起执行任务的一组语句。在MATLAB中&#xff0c;函数是在单独的文件中定义的。文件名和函数名应该相同。 函数在其自己的工作空间&#xff08;也称为本地工作空间&#xff09;中对变量进行操作&#xff0c;与在MATLAB命令提示符下访问的工作空间&#xff0…

优化|贝叶斯优化系列(一):基础算法原理

贝叶斯优化是一种处理黑盒函数优化问题的重要方法。它通过构建一个目标函数的代理模型&#xff0c;并且利用贝叶斯机器学习方法如高斯过程回归来评估代理模型的不确定性。基于代理模型&#xff0c;通过一个采样函数来决定在哪里进行采样。本推文简单描述了贝叶斯优化方法的框架…

【1小时掌握速通深度学习面试1】卷积神经网络-上

目录 1.简述卷积的基本操作&#xff0c;并分析其与全连接层的区别 2.在卷积神经网络中&#xff0c;如何计算各层的感受野大小?卷积层的输出尺寸、参数量和计算量。 3.简述分组卷积及其应用场景 4.简述空洞卷积的设计思路 5.简述转置卷积的主要思想以及应用场景 1.简述卷积…

8. Django 表单与模型

8. 表单与模型 表单是搜集用户数据信息的各种表单元素的集合, 其作用是实现网页上的数据交互, 比如用户在网站输入数据信息, 然后提交到网站服务器端进行处理(如数据录入和用户登录注册等).网页表单是Web开发的一项基本功能, Django的表单功能由Form类实现, 主要分为两种: dj…

vue3项目引入VueQuill富文本编辑器(成功)及 quill-image-uploader 图像模块(未成功)

tip&#xff1a;重点解释都写在代码注释里了&#xff0c;方便理解&#xff0c;所以看起来比较密集 富文本基本使用 项目文件夹路径安装依赖 npm install vueup/vue-quilllatest --save 全局注册&#xff1a;main.js // main.js// 自己项目的一些配置&#xff08;只放了主要…

IoTDB 入门教程 问题篇①——内存不足导致datanode服务无法启动

文章目录 一、前文二、发现问题三、分析问题四、继续分析五、解决问题 一、前文 IoTDB入门教程——导读 二、发现问题 执行启动命令&#xff0c;但是datanode服务却无法启动&#xff0c;查询不到6667端口 bash sbin/start-standalone.sh 进而导致数据库连接也同样失败 [rooti…

开箱子咸鱼之王H5游戏源码_内购修复优化_附带APK完美运营无bug最终版__GM总运营后台_附带安卓版本

内容目录 一、详细介绍二、效果展示2.效果图展示 三、学习资料下载 一、详细介绍 1.包括原生打包APK&#xff0c;资源全部APK本地化&#xff0c;基本上不跑服务器宽带 2.优化后端&#xff0c;基本上不再一直跑内存&#xff0c;不炸服响应快&#xff01; 3.优化前端&#xff0c…

Linux开发板 FTP 服务器移植与搭建

VSFTPD&#xff08;Very Secure FTP Daemon&#xff09;是一个安全、稳定且快速的FTP服务器软件&#xff0c;广泛用于Unix和Linux操作系统。它以其轻量级、高效和易于配置而受到赞誉。VSFTPD不仅支持标准的FTP命令和操作&#xff0c;还提供了额外的安全特性&#xff0c;如匿名F…

会声会影2024中文旗舰版最新网盘安装包下载

会声会影2024是一款功能强大的视频编辑软件&#xff0c;它凭借直观易用的界面、全面的编辑工具以及丰富的特效库&#xff0c;吸引了广泛的用户群体。无论是视频编辑初学者还是专业人士&#xff0c;都能在这款软件中找到满足自己创作需求的功能。 一、软件概述 会声会影2024继承…

【c++】模板编程解密:C++中的特化、实例化和分离编译

&#x1f525;个人主页&#xff1a;Quitecoder &#x1f525;专栏&#xff1a;c笔记仓 朋友们大家好&#xff0c;本篇文章我们来学习模版的进阶部分 目录 1.非类型模版参数按需实例化 2.模版的特化函数模版特化函数模版的特化类模版全特化偏特化 3.分离编译模版分离编译 1.非类…

Android(Java)项目支持Kotlin语言开发

Android&#xff08;Java&#xff09;项目通过相关Kotlin设置后&#xff0c;允许同时使用Java语言和Kotlin语言进行开发代码的。 示例环境&#xff1a; Android Studio Giraffe | 2022.3.1 Patch 3 Java 8 Kotlin 1.9.20 设置Kotlin选项&#xff1a; 第一步&#xff1a;在项…

ASP.NET淘宝店主交易管理系统的设计与实现

摘 要 淘宝店主交易管理系统主要采用了ASPACCESS的B/S设计模式&#xff0c;通过网络之间的数据交换来实现客户、商品、交易的管理和对客户、商品、交易统计工作&#xff0c;从而提高淘宝店主在管理网店过程中的工作效率和质量。 系统分为基本资料模块&#xff0c;统计资料模…

基于ssm+vue+Mysql的药源购物网站

开发语言&#xff1a;Java框架&#xff1a;ssmJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;Maven3.…

知识图谱与知识表示:人工智能的基石

知识图谱与知识表示&#xff1a;人工智能的基石 一、知识图谱&#xff1a;连接数据的桥梁1.1 知识图谱的构成1.2 知识图谱的应用 二、知识表示&#xff1a;AI的推理基础2.1 知识表示的定义2.2 知识表示的形式 三、从符号表示到向量表示3.1 符号表示与向量表示3.2 向量表示的优势…

virtualbox kafka nat + host-only集群 + windows 外网 多网卡

virtualbox kafka nat + host-only集群 + windows 映射访问 kafka集群搭建背景kafka集群搭建 背景 使用virtualbox搭建kafka集群,涉及到不同网络策略的取舍 首先 桥接 网络虽说 啥都可以,但是涉及到过多ip的时候,而且还不能保证使用的ip不被占用,所以个人选择kafka虚拟机…

带宽的理解-笔记

带宽的理解 带宽(频带宽度)&#xff1a;是指电磁波最高频率和最低频率的差值&#xff0c;这一段频率被称为带宽。 举例说明 人耳能听到的频率范围是20赫兹到2万赫兹。换句话说&#xff0c;人而只对20赫兹至2万赫兹的声音频率有反应&#xff0c;超出或低于这一频率范围的声音我…

目标检测发展概述

前言 本篇文章只是简单介绍一下目标检测这一计算机视觉方向的发展历史&#xff0c;因此重点在于介绍而不是完整阐述各个时期的代表算法&#xff0c;只要能够简单了解到目标检测的发展历史那么本文的目的就达到了。 目标检测的任务 从上图不难看出&#xff0c;目标检测是计算机…

快速了解Django:核心概念解析与实践指南

title: 快速了解Django&#xff1a;核心概念解析与实践指南 date: 2024/5/1 20:31:41 updated: 2024/5/1 20:31:41 categories: 后端开发 tags: Django核心路由系统视图系统ORM管理中间件Web框架登录装饰器 第一章&#xff1a;Django简介 背景和发展历程&#xff1a; Djan…

pyinstaller打包pytorch和transformers程序

记录使用pyinstaller打包含有pytorch和transformers库的程序时遇到的问题和解决方法。 环境和版本信息 操作系统&#xff1a;Windows 11 Python&#xff1a;3.10.12 pyinstaller&#xff1a;5.13.0 torch&#xff1a;2.2.2 transformers&#xff1a;4.40.1 打包过程和问…