广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Guava Cache的使用简介
  • 636
分享到

Guava Cache的使用简介

2024-04-02 19:04:59 636人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

目录1 引入 2 Guava Cache介绍 3 缓存的过期时间设置 4 缓存加载机制 5 缓存清理 1 引入 说到缓存,可能大家最先想到的还是Redis。作为基于键值对的非关系型

1 引入

说到缓存,可能大家最先想到的还是Redis。作为基于键值对的非关系型数据库,Redis具有高性能、丰富的数据结构、持久化、高可用分布式等特性,使其在业内得到了广泛的认可和使用。但是,使用Redis必然涉及到网络连接,当网络连接不稳定或网络耗时严重时,必然会影响到我们的业务使用。如果我们想提高我们的业务性能,又减少对其他机器的依赖,那么,使用本地缓存会是一个不错的选择。

使用本地缓存时,大多时候我们会采用ConcurrentHashMap来实现。对于本地缓存的使用,现在有一些较为成熟的本地缓存工具,如ehcache、guava cache,以及Caffeine。当需要对缓存进行持久化操作时,可以考虑使用ehcache。如果没有持久化操作,可以考虑使用guava cache或caffeine,caffeine是基于guava cache进行的二次优化,可根据自身业务需要选择使用哪一种本地缓存工具,本文将针对在DRS系统中使用到的Guava Cache进行讲解。

在本次项目中,选择的guava cache版本信息如下:


<dependency>
  <groupId>com.Google.guava</groupId>
  <artifactId>guava</artifactId>
  <version>30.1-jre</version>
</dependency>

2 Guava Cache介绍

Guava cache和ConcurrentHashMap很相似,都是采用的key-value键值对的方式进行数据的存储,都采用了分段加的方式来提高多线程下的并发操作。不同的是,使用ConcurrentHashMap进行缓存存储时,会一直保留缓存数据,直到系统重启或显示删除缓存,而guava cache支持缓存过期时间的设置,可以进行缓存清理操作。同时,guava cache还可以自动加载缓存,当我们需要从数据库中加载数据到缓存时,不需要每次在获取缓存时判断缓存是否存在,guava cache会按照我们设置的加载方式进行数据的加载。除此之外,guava cache还可以进行一些统计操作,如统计缓存的命中率、加载新值的平均时间等。正是由于Guava cache的这些特性,我们才选择它应用于DRS系统中。下面,来看看我们是如何使用Guava Cache进行缓存管理操作的吧。

3 缓存的过期时间设置

Guava Cache支持三种过期设置,分别是基于容量的回收、定时回收,以及基于引用的回收。显然,基于容量的回收和基于引用的回收跟缓存时间没关系。当我们需要设置缓存的缓存的过期时间时,使用的必然是定时回收的回收策略,那么,在guava cache中,支持两种定时回收策略,分别是基于读写访问的回收与基于写访问的回收,也就是缓存在设置的时间内没有被读写访问或写访问,缓存将会被回收,这种特性是可以满足我们过期时间设置要求的。这两种方法分别是: expireAfterAccess(long, TimeUnit):基于读写访问的回收,缓存项在给定时间内没有被读/写访问,则回收 expireAfterWrite(long, TimeUnit):基于写访问的回收,即缓存项在给定时间内没有被写访问,则回收 如下,给出了基于写访问的回收策略,过期时间设置的是3秒:


Cache<String, String> cache = CacheBuilder.newBuilder()
  .expireAfterWrite(3, TimeUnit.SECONDS)
  .build();

但是,在我们的项目中,需要针对不同的key设置不同的过期时间。而上面的示例中,只能满足一种过期时间的设置,所有key的过期时间都是一样的。为了满足不同过期时间的需求,这里我们采用了一个两级结构的guava cache来实现,如下所示:


private Cache<String, Cache<String, String>> cacheCache = CacheBuilder.newBuilder().build();
   
public void init() {
  Cache<String, String> cache1 = CacheBuilder.newBuilder()
    .expireAfterWrite(3, TimeUnit.SECONDS)
    .build();
  cache1.put("appName", "drs-server");
  Cache<String, String> cache2 = CacheBuilder.newBuilder()
    .expireAfterWrite(2, TimeUnit.SECONDS)
    .build();
  cache2.put("appName", "drs-ops");
  cacheCache.put("key1", cache1);
  cacheCache.put("key2", cache2);
}

在上面的示例中,还可以使用Map+guava cache的方式,也就是一个map里面套一个guava cache,定义如下:


Map<String, Cache<String, String>> cacheMap = new HashMap<String, Cache<String, String>>();

那为什么我们要使用一个两级的cache结构而不是Map+cache的方式呢?原因在于,当读取的数据在缓存中没有时,我们是希望能够自动去从数据库加载的,所以使用两级的cache结构更合适。说到这里,就不得不提到guava cache的加载机制了。

4 缓存加载机制

guava cache有两种方式加载,一种是在构建缓存对象的时候,在build方法中设置缓存的加载方式(仅LocalCache对象可用);另一种是在获取缓存对象的时候,通过实现Callable接口方法的方式设置加载方式。 采用如下的方式构建缓存对象:


LoadinGCache<String, String> cache = CacheBuilder.newBuilder()
  .build(new CacheLoader<String, String>() {
    @Override
    public String load(String s) throws Exception {
      return "load: " + UUID.randomUUID().toString().substring(1, 6);
    }
  });

通过上述方式构建完LocalCache的缓存对象,当调用get(K key)方法获取缓存时,如果指定的key对应的缓存值不存在,则会从load的方法中加载对象。但是,如果使用的是getIfPresent方法,则不会从执行load方法中加载缓存值,而是返回null值。当时用get(K key, Callable call) 获取缓存时,如果对应的缓存值不存在,则会从实现的Callable接口方法中来加载缓存。完整的示例代码如下所示:


public static void main(String[] args) throws Exception{
  LoadingCache<String, String> cache = CacheBuilder.newBuilder()
    .build(new CacheLoader<String, String>() {
      @Override
      public String load(String s) throws Exception {
        return "load: " + UUID.randomUUID().toString().substring(1, 6);
      }
    });
   
  System.out.println(cache.getIfPresent("appName1"));
  System.out.println(cache.get("appName2"));
 
  String loadValue = cache.get("appName3", new Callable<String>() {
    @Override
    public String call() throws Exception {
      return "call: " + UUID.randomUUID().toString().substring(1, 6);
    }
  });
  System.out.println(loadValue);
}

测试结果如下:

5 缓存清理

既然我们给缓存设置了过期时间,那么,缓存过期时间到了后,又是怎么来清理的呢?实际上,过期后的缓存并不会“自动”进行清理,而是在下一次进行读访问或是写访问的时候,通过判断当前时间与缓存加载进来时的时间进行比较,如果时间差大于给定的过期时间,则会清理缓存。如果设置了缓存的加载方式,则会重新加载缓存值,缓存的加载时间也会更新。通过代码调试可以发现,缓存清理是在get方法里实现的,用到的以下几个方法:


get(Object key, int hash); // 获取缓存值
getLiveEntry(Object key, int hash, long now); // 获取存活的对象
isExpired(ReferenceEntry<K, V> entry, long now); // 判断是否过期
expireEntries(long now); // 清理缓存

其中,判断是否过期的逻辑如下:

如果缓存已过期,则返回true,然后执行缓存清理删除操作,如下所示:

除此之外,guava cache还支持缓存的一些统计工作,如统计缓存命中率、加载新值的平均时间、缓存项被回收的总数等,还有缓存中断操作和刷新操作,由于本次项目中没有使用到这些特性,没有进行深入的了解,感兴趣的同学如有使用到,可以去官方网站进行深入了解,详见ifeve.com/google-guav…

以上就是Guava Cache的使用简介的详细内容,更多关于Guava Cache的使用的资料请关注编程网其它相关文章!

--结束END--

本文标题: Guava Cache的使用简介

本文链接: https://www.lsjlt.com/news/122579.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Guava Cache的使用简介
    目录1 引入 2 Guava Cache介绍 3 缓存的过期时间设置 4 缓存加载机制 5 缓存清理 1 引入 说到缓存,可能大家最先想到的还是Redis。作为基于键值对的非关系型...
    99+
    2022-11-12
  • Java开发利器之Guava Cache的使用教程
    目录前言缓存的意义Guava Cache特色API介绍Builder配置简单示例本地缓存前言 缓存技术被认为是减轻服务器负载、降低网络拥塞、增强Web可扩展性的有效途径之一,其基本思...
    99+
    2022-11-13
  • java guava主要功能介绍及使用心得总结
    目录1. 前言2. Guava主要功能介绍2.1 集合操作2.2 缓存2.3 字符串处理2.4 函数式编程2.5 其他实用工具3. 结论1. 前言 Guava是一个由Google开发...
    99+
    2023-05-16
    java guava使用 java guava
  • 详解Guava中EventBus的使用
    目录Guava EventBus使用场景示例核心总结Guava EventBus EventBus是Guava的事件处理机制,是设计模式中观察者模式(生产/消费者编程模型)的优雅实现...
    99+
    2022-12-23
    Guava EventBus使用 Guava EventBus
  • pipenv 使用简介
    之前在开发时一直使用 conda 使用作为虚拟环境管理工具,但有时候会经常会临时性的需要一个虚拟环境,如果使用 conda create 创建一个新环境,耗时不说,有时候还忘了删除,最后系统里一堆的虚拟环境。偶然发现 pipenv 后试用...
    99+
    2023-01-31
    简介 pipenv
  • dgraph 使用简介
    dgraph 简介 dgraph 使用示例(基于 golang) golang client 安装 创建 schema 数据的 CURD 事务 总结 dgraph 简介 dgraph 是基于 golang 开发的开源的分...
    99+
    2015-11-24
    dgraph 使用简介
  • OSWatcher使用简介
       OSWatcher Black Box, 简称OSW,是oracle提供的一个小但是非常有用的工具,它通过调用OS自己提供的命令来记录OS运行时的一些性能参数,比如CPU/Memo...
    99+
    2022-10-18
  • DBM_SQLTUNE使用简介
    DBMS_SQLTUNE的使用方法所需权限grant advisor to user;grant select_catalog_role to user;  --通过OEM管理必不可少g...
    99+
    2022-10-18
  • innotop使用简介
        innotop是一个mysql数据库实时监控工具,其功能强大,信息种类繁多,很能体现数据库的状态.    它实际上是一...
    99+
    2022-10-18
  • Pytest 使用简介
    前言   最近在听极客时间的课程,里面的讲师极力推崇 pytest 框架,鄙视 unittest 框架,哈哈!然后查了些资料,发现了一条 python 鄙视链:pytest 鄙视 &...
    99+
    2022-11-12
  • Postman使用简介
    文章目录 Postman简介Postman主界面菜单栏工具栏请求管理区环境管理区请求设计区 发送请求发送GET请求Postman发送GET请求发送表单格式POST请求发送JSON格式PO...
    99+
    2023-09-02
    Java Postman
  • SpringCloud Zuul的使用简介
    目录简介 使用 简介 Zuul是Spring Cloud全家桶中的微服务API网关。 所有从设备或网站来的请求都会经过Zuul到达后端的Netflix应用程序 Z...
    99+
    2022-11-12
  • SpringCloud Feign的使用简介
    目录简介使用总结简介 feign是声明式的web service客户端,它让微服务之间的调用变得更简单了,类似controller调用service。Spring Cloud集成了...
    99+
    2022-11-12
  • Python中itertools简介使用介绍
    目录Python中itertools模块一、 简介二、 使用介绍1、 常用迭代器1.1 chain1.2 groupby2、 无穷迭代器2.1 count2.2 cycle2.3 r...
    99+
    2022-12-28
    Python中itertools Python itertools详解 Python itertools
  • SpiderMonkey 简介和使用
    SpiderMonkey 是 Mozilla 基金会开发的一款开源的 JavaScript 引擎。它是 Firefox 浏览器的内置...
    99+
    2023-09-14
    SpiderMonkey
  • Android OKHttp使用简介
    目录配置 创建OkHttpClient 同步get请求异步get请求 同步post请求异步post请求上传文件表单提交下面是官网给出的OKHTTP的特点: 支持HTTP/2...
    99+
    2022-11-12
  • Vue3 Composition API的使用简介
    目录概述 示例为什么需要 setup ref、reactive computed与watch生命周期 vue3.0在7月发布了rc版本,vue-cli4.5后也支持选择vue3作为备...
    99+
    2022-11-11
  • python Polars库的使用简介
    目录文件地址:大家好,我是小F~ 很多人在学习数据分析的时候,肯定都会用到Pandas这个库,非常的实用! 从创建数据到读取各种格式的文件(text、csv、json),或者对数据进...
    99+
    2022-11-12
  • C# 枚举的使用简介
    目录为什么使用枚举?枚举有哪些用法?1、简单枚举2、标志枚举3、枚举使用的一些建议枚举这个名词大家都听过,很多小伙伴也使用过, 那么枚举在开发中能做什么,使用它后能给程序代码带来什么...
    99+
    2022-11-11
  • Java Guava的使用技巧有哪些
    本文小编为大家详细介绍“Java Guava的使用技巧有哪些”,内容详细,步骤清晰,细节处理妥当,希望这篇“Java Guava的使用技巧有哪些”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。G...
    99+
    2023-07-05
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作