JetCache @Cached 缓存框架学习实践总结

2023-11-05 01:52

本文主要是介绍JetCache @Cached 缓存框架学习实践总结,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、 来源以及基本介绍

Alibaba 开源框架,基于 Spring 和 Redis 的分布式缓存框架

二、特点

  1. 基于注解使用,简单便捷支持Spring 注入,自定义配置,API 统一且简单
  2. 不仅支持一般场景的使用,在分布式场景高性能场景 中也同样可以支持缓存的数据一致性和更新,同时自身实现了缓存防击穿多级缓存
  3. 可以将数据缓存在本地内存RedisTairMemcached 等多种缓存存储中,提高缓存的命中率和查询效率,也因此支持多种缓存协议。
  4. 针对高并发,高性能场景做了数据结构优化以及算法优化,同样适用

三、注解以及基本使用

缓存管理:JetCache 提供了 CacheBuilder 类来创建缓存,以及 Cache 对象来操作缓存,例如 get、put、remove 等。在调用 Cache 对象的 put 方法时,可以使用注解 @Cache 来设置缓存时间和名称等配置。

注解支持:JetCache 提供了多种注解来实现缓存操作,例如 @Cached,@CacheUpdate, @CacheInvalidate 等,通过使用注解的方式,可以更加方便地进行缓存操作,例如缓存预热、删除、更新等。

四、普通spring ,非springboot 集成和基本使用方式

  1. 依赖:
    <!--jetcache--><dependency><groupId>com.alicp.jetcache</groupId><artifactId>jetcache-anno</artifactId><version>2.7.3</version></dependency><dependency><groupId>com.alicp.jetcache</groupId><artifactId>jetcache-core</artifactId><version>2.7.3</version></dependency>
  1. 创建基本配置类,即将缓存注入spring
    基本配置类可以如下:
import com.alicp.jetcache.anno.CacheConsts;
import com.alicp.jetcache.anno.SerialPolicy;
import com.alicp.jetcache.anno.config.EnableMethodCache;
import com.alicp.jetcache.anno.support.GlobalCacheConfig;
import com.alicp.jetcache.anno.support.JetCacheBaseBeans;
import com.alicp.jetcache.embedded.CaffeineCacheBuilder;
import com.alicp.jetcache.support.DecoderMap;
import com.alicp.jetcache.support.Fastjson2KeyConvertor;
import com.alicp.jetcache.support.Fastjson2ValueDecoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;import java.util.HashMap;
import java.util.Map;@Configuration
// 要扫描的类的基本路径  即支持的路径
@EnableMethodCache(basePackages = {"com.xxx.xxx.xxx.xx"})
@Import(JetCacheBaseBeans.class)
public class MyJetCacheConfig {@Beanpublic GlobalCacheConfig config() {DecoderMap.defaultInstance().initDefaultDecoder();DecoderMap.defaultInstance().register(SerialPolicy.IDENTITY_NUMBER_FASTJSON2, Fastjson2ValueDecoder.INSTANCE);Map localBuilders = new HashMap();CaffeineCacheBuilder localBuilder =CaffeineCacheBuilder.createCaffeineCacheBuilder().keyConvertor(Fastjson2KeyConvertor.INSTANCE).limit(100);// 设置默认缓存时间 单位毫秒localBuilder.setExpireAfterWriteInMillis(60 * 60 * 1000);localBuilders.put(CacheConsts.DEFAULT_AREA, localBuilder);Map remoteBuilders = new HashMap();GlobalCacheConfig globalCacheConfig = new GlobalCacheConfig();globalCacheConfig.setLocalCacheBuilders(localBuilders);globalCacheConfig.setRemoteCacheBuilders(remoteBuilders);globalCacheConfig.setStatIntervalMinutes(15);globalCacheConfig.setPenetrationProtect(true);return globalCacheConfig;}
}
  1. 基本使用
@Service
public class UserServiceImpl implements IUserService {@Cache(name = "自定义的当前缓存名", key = "#userId", expire = 300, cacheType = CacheType.LOCAL)@Overridepublic User getUserById(Long userId) {// 具体内部自己的业务实现.......}@CacheUpdate(name = "自定义的当前缓存名2", key = "#user.id") // user.id 会自动获取当前方法入参的对象的id 属性 作为缓存的key 类似于Map@Overridepublic void updateUser(User user) {// 具体内部自己的业务实现......}
}

五、注解说明

@Cache 属性说明

属性说明
area如果在配置中配置了多个缓存area,在这里指定使用哪个area
name指定缓存的唯一名称,不是必须的,如果没有指定,会使用类名+方法名。name会被用于远程缓存的key前缀。另外在统计中,一个简短有意义的名字会提高可读性。
key使用 spring EL 表达式 指定key,如果没有指定会根据所有参数自动生成。
expire超时时间。如果注解上没有定义,会使用全局配置,如果此时全局配置也没有定义,则为无穷大
timeUnit指定expire的单位,默认为 TimeUnit.SECONDS 秒
cacheTypeCacheType.REMOTE 缓存的类型,包括CacheType.REMOTE、CacheType.LOCAL、CacheType.BOTH。如果定义为BOTH,会使用LOCAL和REMOTE组合成两级缓存
localLimit如果cacheType为LOCAL或BOTH,这个参数指定本地缓存的最大元素数量,以控制内存占用。如果注解上没有定义,会使用全局配置,如果此时全局配置也没有定义,则为100,参数 localLimit 表示本地缓存的最大条目限制。当使用 JetCache 的本地缓存功能时,localLimit 参数可以控制本地缓存中最多缓存的条目数量,如果超过了这个数量,将会按照 LRU(Least Recently Used)算法删除最近最少使用的缓存条目,以保持缓存的大小在限制范围内。localLimit 默认值为 100条,可以通过设置该值来优化缓存性能和内存使用。备注:当type为LOCAL时,配置localLimit,当key值超出限制条件,会删除最少使用的条目,重新请求缓存过的,会走到db再缓存一次。当type为BOTH时,虽然配置了localLimit 当key值超出限制条件,本地会删除使用最少得条目,但是远程还有缓存,查询缓存时是优先查询本地,没有再去远程,都没有再走db,将查询结果进行一次缓存。如果配置BOTH时,可以配置该项减少本地内存使用,但是不影响缓存整体使用因为有远程兜底。
localExpire仅当cacheType为BOTH时适用,为内存中的Cache指定一个不一样的超时时间,通常应该小于expire
serialPolicy指定远程缓存的序列化方式。可选值为SerialPolicy.JAVA和SerialPolicy.KRYO。如果注解上没有定义,会使用全局配置,如果此时全局配置也没有定义,则为SerialPolicy.JAVA
keyConvertor指定KEY的转换方式,用于将复杂的KEY类型转换为缓存实现可以接受的类型,当前支持KeyConvertor.FASTJSON和KeyConvertor.NONE。NONE表示不转换,FASTJSON可以将复杂对象KEY转换成String。如果注解上没有定义,会使用全局配置。
enabled默认true 是否激活缓存。例如某个dao方法上加缓存注解,由于某些调用场景下不能有缓存,所以可以设置enabled为false,正常调用不会使用缓存,在需要的地方可使用CacheContext.enableCache在回调中激活缓存,缓存激活的标记在ThreadLocal上,该标记被设置后,所有enable=false的缓存都被激活
cacheNullValue默认 false 当方法返回值为null的时候是否要缓存
condition使用SpEL指定条件(spring EL 表达式),如果表达式返回true的时候才去缓存中查询
postCondition使用SpEL指定条件(spring EL 表达式),如果表达式返回true的时候才更新缓存,该评估在方法执行后进行,因此可以访问到 #result

@CacheRefresh 属性说明

属性说明
refresh刷新间隔
timeUnit默认 TimeUnit.SECONDS 秒 时间单位
stopRefreshAfterLastAccess指定该key多长时间没有访问就停止刷新,如果不指定会一直刷新
refreshLockTimeout默认 60秒 类型为BOTH/REMOTE的缓存刷新时,同时只会有一台服务器在刷新,这台服务器会在远程缓存放置一个分布式锁,此配置指定该锁的超时时间

@CacheInvalidate 属性说明

属性说明
area如果在配置中配置了多个缓存area,在这里指定使用哪个area,指向对应的@Cached定义。
name指定缓存的唯一名称,指向对应的@Cached定义。
key使用SpEL指定key
condition使用SpEL指定条件,如果表达式返回true才执行删除,可访问方法结果#result

@CacheUpdate 属性说明

属性说明
area如果在配置中配置了多个缓存area,在这里指定使用哪个area,指向对应的@Cached定义。
name指定缓存的唯一名称,指向对应的@Cached定义。
key使用SpEL指定key
value使用SpEL指定value
condition使用SpEL指定条件,如果表达式返回true才执行删除,可访问方法结果#result

@CachePenetrationProtect 注解
当缓存访问未命中的情况下对并发进行的加载行为进行保护。
当前版本实现的是单JVM内的保护,即同一个JVM中同一个key只有一个线程去加载,其它线程等待结果。

对于以上未定义默认值的参数,如果没有指定,将使用yml中指定的全局配置

六、spring boot 类型项目依赖以及配置

依赖
后缀为 redis 即支持redis 远程缓存

<dependency><groupId>com.alicp.jetcache</groupId><artifactId>jetcache-starter-redis</artifactId><version>3.0.1</version>
</dependency>

yml 配置文件

jetcache:# 统计间隔,默认0:表示不统计statIntervalMinutes: 1# areaName是否作为缓存key前缀,默认TrueareaInCacheName: falselocal:default:# 已支持可选:linkedhashmap、caffeinetype: linkedhashmap# key转换器的全局配置,当前只有:fastjson, @see com.alicp.jetcache.support.FastjsonKeyConvertorkeyConvertor: fastjson# 每个缓存实例的最大元素的全局配置,仅local类型的缓存需要指定limit: 100# jetcache2.2以上,以毫秒为单位,指定多长时间没有访问,就让缓存失效,当前只有本地缓存支持。0表示不使用这个功能expireAfterAccessInMillis: 60000remote:default:# 已支持可选:redis、tairtype: redis.lettuce# 连接格式@see:https://github.com/lettuce-io/lettuce-core/wiki/Redis-URI-and-connection-detailsuri: redis://localhost:6379/1?timeout=5skeyConvertor: fastjson# 序列化器的全局配置。仅remote类型的缓存需要指定,可选java和kryovalueEncoder: javavalueDecoder: java# 以毫秒为单位指定超时时间的全局配置expireAfterWriteInMillis: 5000

全局开关运行类

@SpringBootApplication
@EnableMethodCache(basePackages = "com.xxx.xxxx.xxxx")
@EnableCreateCacheAnnotation
public class MySpringBootApp {public static void main(String[] args) {SpringApplication.run(MySpringBootApp.class);}
}

本地缓存

LinkedHashMapCache是JetCache中实现的一个最简单的Cache,使用LinkedHashMap做LRU方式淘汰。

Cache<String, Xxxx> cache = LinkedHashMapCacheBuilder.createLinkedHashMapCacheBuilder().limit(100).expireAfterWrite(200, TimeUnit.SECONDS).buildCache();

内部为key 和 value 的返回值

本地缓存-caffeine
caffeine cache 是guava cache的后续作品

Cache<String, Xxxx> cache = CaffeineCacheBuilder.createCaffeineCacheBuilder().limit(100).expireAfterWrite(200, TimeUnit.SECONDS).buildCache();

内部为key 和 value 的返回值

统计信息
当yml中的 jetcache.statIntervalMinutes 大于0时,通过 @CreateCache 和 @Cached 配置出来的 Cache 自带监控。JetCache会按指定的时间定期通过logger输出统计信息。

开启配置

@Bean
public Consumer<StatInfo> statCallback() {// ... 或实现自己的Consumer<StatInfo>return new StatInfoLogger(false);
}

这篇关于JetCache @Cached 缓存框架学习实践总结的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/346618

相关文章

Spring Boot 配置文件之类型、加载顺序与最佳实践记录

《SpringBoot配置文件之类型、加载顺序与最佳实践记录》SpringBoot的配置文件是灵活且强大的工具,通过合理的配置管理,可以让应用开发和部署更加高效,无论是简单的属性配置,还是复杂... 目录Spring Boot 配置文件详解一、Spring Boot 配置文件类型1.1 applicatio

tomcat多实例部署的项目实践

《tomcat多实例部署的项目实践》Tomcat多实例是指在一台设备上运行多个Tomcat服务,这些Tomcat相互独立,本文主要介绍了tomcat多实例部署的项目实践,具有一定的参考价值,感兴趣的可... 目录1.创建项目目录,测试文China编程件2js.创建实例的安装目录3.准备实例的配置文件4.编辑实例的

Python 中的异步与同步深度解析(实践记录)

《Python中的异步与同步深度解析(实践记录)》在Python编程世界里,异步和同步的概念是理解程序执行流程和性能优化的关键,这篇文章将带你深入了解它们的差异,以及阻塞和非阻塞的特性,同时通过实际... 目录python中的异步与同步:深度解析与实践异步与同步的定义异步同步阻塞与非阻塞的概念阻塞非阻塞同步

Python Dash框架在数据可视化仪表板中的应用与实践记录

《PythonDash框架在数据可视化仪表板中的应用与实践记录》Python的PlotlyDash库提供了一种简便且强大的方式来构建和展示互动式数据仪表板,本篇文章将深入探讨如何使用Dash设计一... 目录python Dash框架在数据可视化仪表板中的应用与实践1. 什么是Plotly Dash?1.1

基于Flask框架添加多个AI模型的API并进行交互

《基于Flask框架添加多个AI模型的API并进行交互》:本文主要介绍如何基于Flask框架开发AI模型API管理系统,允许用户添加、删除不同AI模型的API密钥,感兴趣的可以了解下... 目录1. 概述2. 后端代码说明2.1 依赖库导入2.2 应用初始化2.3 API 存储字典2.4 路由函数2.5 应

Python GUI框架中的PyQt详解

《PythonGUI框架中的PyQt详解》PyQt是Python语言中最强大且广泛应用的GUI框架之一,基于Qt库的Python绑定实现,本文将深入解析PyQt的核心模块,并通过代码示例展示其应用场... 目录一、PyQt核心模块概览二、核心模块详解与示例1. QtCore - 核心基础模块2. QtWid

springboot集成Deepseek4j的项目实践

《springboot集成Deepseek4j的项目实践》本文主要介绍了springboot集成Deepseek4j的项目实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价... 目录Deepseek4j快速开始Maven 依js赖基础配置基础使用示例1. 流式返回示例2. 进阶

java常见报错及解决方案总结

《java常见报错及解决方案总结》:本文主要介绍Java编程中常见错误类型及示例,包括语法错误、空指针异常、数组下标越界、类型转换异常、文件未找到异常、除以零异常、非法线程操作异常、方法未定义异常... 目录1. 语法错误 (Syntax Errors)示例 1:解决方案:2. 空指针异常 (NullPoi

Linux修改pip和conda缓存路径的几种方法

《Linux修改pip和conda缓存路径的几种方法》在Python生态中,pip和conda是两种常见的软件包管理工具,它们在安装、更新和卸载软件包时都会使用缓存来提高效率,适当地修改它们的缓存路径... 目录一、pip 和 conda 的缓存机制1. pip 的缓存机制默认缓存路径2. conda 的缓

Redis解决缓存击穿问题的两种方法

《Redis解决缓存击穿问题的两种方法》缓存击穿问题也叫热点Key问题,就是⼀个被高并发访问并且缓存重建业务较复杂的key突然失效了,无数的请求访问会在瞬间给数据库带来巨大的冲击,本文给大家介绍了Re... 目录引言解决办法互斥锁(强一致,性能差)逻辑过期(高可用,性能优)设计逻辑过期时间引言缓存击穿:给