快速掌握缓存技术:学习多个缓存供应商(ehcache,redis,memcached,jetcache,j2cache)

embedded/2024/10/18 8:24:16/

缓存技术

缓存

缓存是一种介于数据永久存储介质与数据应用之间的数据临时存储介质

使用缓存可以有效的减少低速数据读取过程的次数(例如磁盘IO),提高系统性能

缓存不仅可以用于提高永久性存储介质的数据读取效率,还可以提供临时的数据存储空间

模拟缓存

手动写一个模拟缓存的demo,这里我们在server层中模拟一个缓存

@Server
public class Bookserverimpl implements Bookserver{
@Autowired
private BookDao bookdao;
private HashMap<Integer,Book> cache=new HashMap<Integer,Book>();
public Book getById(Integer id){
Book book=cache.get(id);
if(book=null){
Book qubook=BookDao.selectById(id);
cache.put(id,qubook);
return qubook;
}
}
return cache.get(id);
}

这里面的HashMap对象充当一个缓存器,对数据库中的数据进行查询,先对缓存中进行查询,当缓存中有这个数据的时候就查询缓存中的数据,当缓存中没有的时候再在数据库中进行查询并添加到缓存器中

Spring缓存技术

SpringBoot提供了缓存技术,方便缓存使用
首先导入缓存的依赖:

        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId></dependency>

在启动类中加入注解 @EnableCaching表示启动缓存

@SpringBootApplication
@EnableCaching
public class SpringbootApplication{
}

在服务层使用缓存技术:

@Cacheable(value="cacheSpace",key="#id")
public Book getByid(Integer id){
}

但是这里有一个问题,在这个注解中也有向外读取的操作,我们应该将注解换成 @CachePut
value属性指创建一个存储空间,其中放入key的值,#id表示可以读取名为id 的值

上述操作就是spring官方默认的缓存技术,除此之外,spring还可以整合第三方的缓存技术,统一接口,实现高效开发

第三方缓存技术

第三方<a class=缓存技术" />

Ehcache缓存供应

导入ehcache的依赖:

        <dependency><groupId>ehcache</groupId><artifactId>ehcache</artifactId><version>1.2</version></dependency>

在配置文件中设置cache的类型启用ehcache

spring:cache:type: ehcacheehcache:config: ehcache.xml

使用ehcache需要有一个其独立的配置文件,用来配置其中的设置
在这里插入图片描述
在配置文件当中缓存还可以多次进行配置,我再写一个defaultCache用name区分

<defaultCachename="cacac"..../>
  • 注意

当我们改换第三方技术的时候,原有的默认注解并没有进行改变,依然可以正常使用

Redis缓存

首先先导入依赖

        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>

在配置文件中选择cache的类型为redis

  redis:host: localhostport: 6379

redis的相关配置也在配置文件中进行配置

spring:cache:type: redisredis:use-key-prefix: true   #是否使用前缀cache-null-values: false  #是否缓存空值key-prefix:  aa  #指定前缀time-to-live: 10s #最大活动周期

注意属性的层次尤其是redis
在这里插入图片描述

memcached缓存(国内)

下载memcached
地址:https://www.runoob.com/memcached/window-install-memcached.html
下载之后解压目录:
在管理员权限下运行cmd,进入到当前目录中输入命令安装并启动服务
在这里插入图片描述
当需要服务停止的时候输入memcached.exe -d stop

  • memcached客户端选择
  1. Memcached Client for java:最早期客户端,稳定可靠,用户群广
  2. SpyMemcached: 效率更高
  3. Xmemcached: 并发处理好

我们这里采用技术更加先进的Xmemcached技术,但是SpringBoot未提供对xmemcached的整合,需要使用硬编码方式实现客户端初始化管理

首先导入依赖:

        <dependency><groupId>com.googlecode.xmemcached</groupId><artifactId>xmemcached</artifactId><version>2.4.7</version></dependency>

写一个控制类


@Configuration
public class XmemcachedConfig {@Beanpublic MemcachedClient getmemcacheclient() throws IOException {MemcachedClientBuilder memcachedClientBuilder=new XMemcachedClientBuilder("localhost:11211");MemcachedClient memcachedClient=memcachedClientBuilder.build();return memcachedClient;}
}

像控制类中的配置信息还可以通过配置文件进行自定义配置:

memcached:servers: localhost:11211poolSize: 10               #连接池的最大连接数opTimeout: 3000

自定义文件之后配置一个对应的属性类进行配置

@Component
@ConfigurationProperties(prefix="memcached")
@Data
public class Xmemcachedproperties{private String servers;private int poolSize;private long opTimeout;
}

这个时候在配置类中就可以进行使用

@Configuration
public class XmemcachedConfig {@Beanpublic MemcachedClient getmemcacheclient() throws IOException {MemcachedClientBuilder memcachedClientBuilder=new XMemcachedClientBuilder(memcachedproperties.getServers());memcachedClientBuilder.setconnectionPoolSize(memcachedProperties.getPoolSzie());   //设置最大连接数memcachedClientBuilder.setOptimeout(memcachedProperties.getOpTimeout());MemcachedClient memcachedClient=memcachedClientBuilder.build();return memcachedClient;}
}

在服务类中注入使用

@Autowired
private MemcachedClient memcachedClient;
public String sendCodeTosms(String tele){
memcachedclient.set(tele,0,code); //第一个参数是key,第二个参数是过期时间,第三个参数是值,这句话需要try-catch抛出
}

jetcache缓存供应商

jetCache对SpringCache进行了封装,在原有功能基础上实现了多级缓存缓存统计,自动刷新,异步调用,数据报表等功能
jetCache设定了本地缓存与远程缓存的多级缓存解决方案
本地缓存:(local)

  1. LinkedHashMap
  2. Caffeine
    远程缓存:(remote)
  3. Redis
  4. Tair

jetcache的基本使用

设置外部服务

首先先导入依赖:

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

在配置文件中配置jetcache:
jetcache与spring是同一级别的配置

jetcache:remote:          #配置远程管理default:        #管理模式,相当于之前配置文件中的ehcache配置文件中的name可以有多个type: redishost: localhostport: 6379poolConfig:  #对应的配置maxTotal: 50    #设置最大连接数,必须写poolConfiig,其中最少也要写maxTotal的配置否则会报错keyConvertor: fastjson    #默认在缓存中将java对象数据转换为json字符串,也可以将json字符串转换为java	calueEncoder: javacalueEncoder: java    #规定缓存中值进行转换时,转换成什么类型的数据sms:            #第二个管理模式

在开启类中jetcache启用缓存开关

@springbootApplication
@EnableCreateCacheAnnotation
public class SpringbootApplication{
}

自定义缓存空间

//注解第一个属性相当于值前的前缀,expire设置过期时间,3600默认单位秒,可以通过第三个参数设置单位
@CreateCache(name="jetcache",expire=3600,timeUnit=TimeUnit.SECONDS)
//自定义缓存空间,泛型中对应的是key和value的值
private Cache<String,String> jetcache;

存入缓存

jetcache.put("tele",code);

读取缓存

jetcache.get();
  • 切换管理模式

在配置中配置第二个管理模式sms如上所讲,那要如何进行切换

@CreateCache(area="sms",name="",expire=)

通过注解进行管理模式的切换,这样命名空间就会用对应的管理模式进行创建空间

设置本地服务

同样在配置文件中进行配置:

jetcache:local:default:type: linkedhashmapkeyConvertor: fastjsonlimit: #缓存的数据量

通过注解实现本地远程进行切换:

@CreateCache(name="",expire=,cacheType=Cache.LOCAL)//有三个值可以进行切换
  • jetcache配置属性信息

配置属性信息

jetcache方法缓存

如果需要启动方法缓存需要在启动类上面加入方法缓存的注解

@springbootApplication
@EnableCreateCacheAnnotation
@EnableMethodCache(basepackages="包名")   //注解中的属性需要添加一个包名,所要添加注解的方法就在这个包下
public class SpringBootCacheApplicaton{
}

在方法上使用注解 @Cached进行缓存处理:

@Cached(name="jetcache_",key="#id",expire=3600)
public Book getbyId(Integer id){return bookDao.getByid(id);
}
  • @Cached@CreateCache的区别:
  1. 用途: @CreateCache 用于创建和直接操作缓存实例;@Cached 用于自动处理方法返回值的缓存
  2. 操作: 使用 @CreateCache 时,开发者需要手动从缓存中获取和存储数据;而 @Cached 则自动化这个过程,使得方法执行与缓存透明化。
  3. 灵活性: @CreateCache 提供更多的控制权和灵活性,因为您可以直接操作缓存;@Cached 更简单易用,适合那些希望自动缓存方法返回结果的场景。

注意前面提到的jecache配置文件中的配置:keyConvertor:fastjson
我们提到它可以将java对象数据转换为json格式的字符串存储在缓存当中,而jetcache缓存底层通过序列化与反序列化的机制进行转换,这时我们首先应该将实体类对象序列化,这样才能够将序列化后的java对象数据进行转换:

@Data
public class Book implements Serializable{private Integer id;private String name;
}

接着进行操作:如果此时我们进行更新操作,此时缓存中的对应数据需要同步进行更新,那么此时,我们在进行更新操作的时候可以通过注解 @Cacheupdate同步进行更新操作:

@Cacheupdate(name="book_",key="#book.id",value="#book")
public boolean update(Book book){
return bookDao.updayeById(book)>0;
}

同时在进行删除操作的时候也应该通过注解 @CacheInvalidate缓存中进行同步操作:

@CacheInvalidate(name="book_",key="#id")
public boolean delete(Integer id){
return bookDao.delete(id)>0;
}

通过以上三个操作就会显示出来一个问题,当多个用户同时操作一个数据的时候,可能会出现B用户操作后缓存同步完毕,A用户操作之后缓存没有进行同步看到的还是之前存在的数据这时就会出错:
我们可以通过注解 @CacheRefresh进行定时刷新,刷新缓存数据

@Cached(...)
@CacheRefresh(refresh=10)

jetcache对应的操作信息可以通过配置进行查看:

jetcache:statIntervalMinutes: 1 #等待一分钟将一分钟内对缓存的操作进行分析统计并输出在控制台上

j2cache

j2cache 是一个缓存整合框架,可以提供缓存的整合方案,使各种缓存搭配使用,自身不提供缓存功能

这里我们基于 encache + redis 进行整合讲解j2cache

第一步导入依赖:

<!--在j2cache-spring-boot2-starter中就包含了redis的依赖文件--><dependency><groupId>net.oschina.j2cache</groupId><artifactId>j2cache-spring-boot2-starter</artifactId><version>2.8.0-release</version></dependency><dependency><groupId>net.oschina.j2cache</groupId><artifactId>j2cache-core</artifactId><version>2.8.4-release</version></dependency><dependency><groupId>ehcache</groupId><artifactId>ehcache</artifactId><version>1.2</version></dependency>

然后在配置文件中进行配置:

server:port: 80
j2cache:config-location: j2cache.properties

j2cache的配置文件是properties类型,在配置文件当中配置多级缓存

# 一级缓存
j2cache.L1.provider_class =ehcache
ehcache.configXml =ehcache.xml
#设置是否启用二级缓存
j2cache.l2-cache-open=false
# 二级缓存
j2cache.L2.provider_class=net.oschina.j2cache.cache.support.redis.SpringRedisProvider
j2cache.L2.config_section=redis
redis.hosts=localhost:6379 
#一级缓存中的数据如何到达二级缓存
j2cache.broadcast=net.oschina.j2cache.cache.support.redis.SpringRedisPubSubPolicy

二级缓存的供应商应该配置j2cache中redis的SpringRedisProvider类
如何使用j2cache:

//定义一个缓存对象
@Autowired
private CacheChannel cacheChannel;
//在方法中使用该对象进行缓存的处理
cacheChannel.set("sms",tele,code);
String code=cacheChannel.get("sms",smsCode.getTele()).asString();//将我们的值变化为String类型的值 

http://www.ppmy.cn/embedded/4024.html

相关文章

MATLAB实现禁忌搜索算法优化柔性车间调度fjsp

禁忌搜索算法的流程可以归纳为以下几个步骤&#xff1a; 初始化&#xff1a; 利用贪婪算法或其他局部搜索算法生成一个初始解。清空禁忌表。设置禁忌长度&#xff08;即禁忌表中禁止操作的期限&#xff09;。邻域搜索产生候选解&#xff1a; 通过特定的搜索算子&#xff08;如…

Sonatype Nexus 服务器迁移

因为服务器的升级和调整&#xff0c;有时候会对安装 Sonatype Nexus 的服务器进行迁移到新服务器上。 从技术架构上来说&#xff0c;Sonatype Nexus 我们使用的是 AWS 的存储&#xff0c;所以我们并不需要拷贝大量的数据。 文件夹结构 在备份和恢复之前&#xff0c;我们需要…

分类网络总结

欢迎大家订阅我的专栏一起学习共同进步&#xff0c;主要针对25届应届毕业生 祝大家早日拿到offer&#xff01; lets go http://t.csdnimg.cn/dfcH3 目录 4. 经典分类网络与发展 4.1 AlexNet 4.2 VGGNet 4.3 GoogLeNet Inception 4.4 ResNet 4.5 DenseNet 4.6 MobileN…

.Net ajax 接收参数

后端部分代码 一般处理程序 public void ProcessRequest(HttpContext context){context.Response.ContentType "text/plain";string str_index context.Request.Form.AllKeys.Contains("index") ? context.Request.Form["index"].ToString(…

JavaScript 高性能编程 —— Data Access 数据访问

经典计算机科学的一个问题是确定数据应当存放在什么地方,以实现最佳的读写效率。数据存储在哪里, 关系到代码运行期间数据被检索到的速度。在 JavaScript 中,此问题相对简单,因为数据存储只有少量方 式可供选择。正如其他语言那样,数据存储位置关系到访问速度。 在 JavaS…

华为配置静态ARP示例

华为配置静态ARP示例 组网图形 图1 配置静态ARP组网图 静态ARP简介配置注意事项组网需求配置思路操作步骤配置文件相关信息 静态ARP简介 静态ARP表项是指网络管理员手工建立IP地址和MAC地址之间固定的映射关系。 正常情况下网络中设备可以通过ARP协议进行ARP表项的动态学习&…

RabbitMQ - Spring boot 整合 RabbitMQ

一、RabbitMQ 1、RabbitMQ 使用场景 1.1、服务解耦 假设有这样一个场景, 服务A产生数据, 而服务B,C,D需要这些数据, 那么我们可以在A服务中直接调用B,C,D服务,把数据传递到下游服务即可 但是,随着我们的应用规模不断扩大,会有更多的服务需要A的数据,如果有几十甚至几百个下…

Webrtc 信令服务器实现

webrtc建联流程图 由上图可知&#xff0c;所谓的信令服务器其实就是将peer的offer/candidate/answer传给对端而已。这样的话实现方式就有很多种了&#xff0c;目前普遍的方式HTTP/HTTPS&#xff0c;WS/WSS。像webrtc-demo-peerconnection就是实现HTTP这种方式。本文使用WS&…