spring-boot集成redis实现缓存功能

简介: 一、本次案例 我们假设用户信息(user)和产品信息(product)需要缓存,缓存数据都加上user和product作为key前缀,采用用户的id和产品的id作为key的后缀。用户缓存时间为30分钟,产品信息缓存时间为10分钟。

一、本次案例

我们假设用户信息(user)和产品信息(product)需要缓存,缓存数据都加上user和product作为key前缀,采用用户的id和产品的id作为key的后缀。用户缓存时间为30分钟,产品信息缓存时间为10分钟。

二、redis客户端配置

无论使用spring-boot的哪个版本,我们都需要先配置redis连接,两个版本的redis客户端连接池使用有所不同。

spring-boot版本 默认客户端类型
1.5.x jedis
2.x lettuce

在1.5.x中,我们配置jedis连接池只需要配置 spring.redis.pool.* 开始的配置即可,如下配置

spring.redis.pool.max-active=8
spring.redis.pool.max-wait=-1
spring.redis.pool.min-idle=0
spring.redis.pool.max-idle=8

但在2.x版本中由于引入了不同的客户端,需要指定配置哪种连接池,如下配置

#jedis客户端
spring.redis.jedis.pool.max-active=8
spring.redis.jedis.pool.max-wait=-1ms
spring.redis.jedis.pool.min-idle=0
spring.redis.jedis.pool.max-idle=8
#lettuce客户端
spring.redis.lettuce.pool.min-idle=0
spring.redis.lettuce.pool.max-idle=8
spring.redis.lettuce.pool.max-wait=-1ms
spring.redis.lettuce.pool.max-active=8
spring.redis.lettuce.shutdown-timeout=100ms

除此之外还可以看到时间配置上还需要带上对应的单位。

三、直接配置cache参数

在1.5.x版本下提供的针对cache的配置非常少,我们能够使用到的自动装配redis缓存的配置如下

#缓存的名称集合,多个采用逗号分割
spring.cache.cache-names=
#缓存的类型,官方提供了很多,这里我们填写redis
spring.cache.type=

在2.x版本时,官方增加了更多的配置

#缓存的名称集合,多个采用逗号分割
spring.cache.cache-names=
#缓存的类型,官方提供了很多,这里我们填写redis
spring.cache.type=
#是否缓存null数据,默认是false
spring.cache.redis.cache-null-values=
#redis中缓存超时的时间,默认60000ms
spring.cache.redis.time-to-live=
#缓存数据key是否使用前缀,默认是true
spring.cache.redis.use-key-prefix=
#缓存数据key的前缀,在上面的配置为true时有效,
spring.cache.redis.key-prefix=

四、JavaConfig方式配置

通用配置方式只能满足整个程序所有缓存都采用相同公共配置的方式,如果需要特殊处理,如我们的案列,则需要自己采用代码的方式来配置。
采用代码的方式,只要需要配置的是CacheMananger,采用Redis时具体实现我们需要使用其子类RedisCacheMananger来做配置

4.1、spring-boot 1.5.x版本

CacheManager配置

@Bean
public CacheManager cacheManager(RedisTemplate redisTemplate) {
    RedisCacheManager redisCacheManager = new RedisCacheManager(redisTemplate);
    //默认超时时间,单位秒
    redisCacheManager.setDefaultExpiration(60);
    //缓存超时时间Map,key为cacheName,value为超时,单位是秒
    Map<String, Long> expiresMap = new HashMap<>();
    //缓存用户信息的cacheName和超时时间
    expiresMap.put("user", 1800L);
    //缓存产品信息的cacheName和超时时间
    expiresMap.put("product", 600L);
    redisCacheManager.setExpires(expiresMap);
    return redisCacheManager;
}

cache调用代码

@Cacheable(value = "user", key = "'user:'+#id", unless = "#result==null")
public String getUser(int id) {
    //逻辑操作
}
@Cacheable(value = "product", key = "'product:'+#id", unless = "#result==null")
public String getProduct(int id) {
    //逻辑操作
}

4.2、spring-boot 2.x版本

CacheManager配置

2.x版本开始,代码方式配置变化比较大,同时增加了更多配置参数

@Bean
CacheManager cacheManager(RedisConnectionFactory connectionFactory) {
    //user信息缓存配置
    RedisCacheConfiguration userCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(30)).disableCachingNullValues().prefixKeysWith("user");
    //product信息缓存配置
    RedisCacheConfiguration productCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(10)).disableCachingNullValues().prefixKeysWith("product");
    Map<String, RedisCacheConfiguration> redisCacheConfigurationMap = new HashMap<>();
    redisCacheConfigurationMap.put("user", userCacheConfiguration);
    redisCacheConfigurationMap.put("product", productCacheConfiguration);
    //初始化一个RedisCacheWriter
    RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory);
    
    
    //设置CacheManager的值序列化方式为JdkSerializationRedisSerializer,但其实RedisCacheConfiguration默认就是使用StringRedisSerializer序列化key,JdkSerializationRedisSerializer序列化value,所以以下注释代码为默认实现
    //ClassLoader loader = this.getClass().getClassLoader();
    //JdkSerializationRedisSerializer jdkSerializer = new JdkSerializationRedisSerializer(loader);
    //RedisSerializationContext.SerializationPair<Object> pair = RedisSerializationContext.SerializationPair.fromSerializer(jdkSerializer);
    //RedisCacheConfiguration defaultCacheConfig=RedisCacheConfiguration.defaultCacheConfig().serializeValuesWith(pair);
    
    
    RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig();
    //设置默认超过期时间是30秒
    defaultCacheConfig.entryTtl(Duration.ofSeconds(30));
    //初始化RedisCacheManager
    RedisCacheManager cacheManager = new RedisCacheManager(redisCacheWriter, defaultCacheConfig, redisCacheConfigurationMap);
    return cacheManager;
}

以上代码中RedisCacheConfiguration类为2.x新增的配置类,增加了几个配置项。这里比较奇怪的是调用它的配置方法每一次都会重新生成一个配置对象,而不是在原对象上直接修改参数值,这一点本人没搞懂作者为何要选择这种方式。

cache调用代码

@Cacheable(value = "user", key = "#id", unless = "#result==null")
public String getUser(int id) {
    //逻辑操作
}
@Cacheable(value = "product", key = "#id", unless = "#result==null")
public String getProduct(int id) {
    //逻辑操作
}

这里两点需要注意的地方

  • 1、在Cacheable的key属性中不在需要自己配置前缀,可以在RedisCacheConfiguration中配置。
  • 2、如果Cacheable中不配置 unless = "#result==null" 属性,而RedisCacheConfiguration中调用disableCachingNullValues()配置了不缓存null结果在出现null结果时会报异常,这一点与我一开始的理解也不太一样,二者并非都生效的。个人理解unless配置#result==null可以决定null的值是否往cacheManager丢,而RedisCacheConfiguration的disableCachingNullValues()只在存储前起到了校验作用,而不会因为设置了这个值而直接跳过null的保存。如果真是设计如此,感觉有点鸡肋,不知道算不算一个bug。

小结

spring-boot刚刚发布了2.0.0的正式版,除了比较大的webflux之外,许多组件可能都有细节变化,在做升级的时候需要注意更改,建议先验证常用的功能用法后,再做升级的计划安排。

相关文章
|
9月前
|
XML 测试技术 API
利用C#开发ONVIF客户端和集成RTSP播放功能
利用C#开发ONVIF客户端和集成RTSP播放功能
4648 123
|
8月前
|
缓存 负载均衡 监控
135_负载均衡:Redis缓存 - 提高缓存命中率的配置与最佳实践
在现代大型语言模型(LLM)部署架构中,缓存系统扮演着至关重要的角色。随着LLM应用规模的不断扩大和用户需求的持续增长,如何构建高效、可靠的缓存架构成为系统性能优化的核心挑战。Redis作为业界领先的内存数据库,因其高性能、丰富的数据结构和灵活的配置选项,已成为LLM部署中首选的缓存解决方案。
812 25
|
9月前
|
存储 缓存 NoSQL
Redis专题-实战篇二-商户查询缓存
本文介绍了缓存的基本概念、应用场景及实现方式,涵盖Redis缓存设计、缓存更新策略、缓存穿透问题及其解决方案。重点讲解了缓存空对象与布隆过滤器的使用,并通过代码示例演示了商铺查询的缓存优化实践。
365 1
Redis专题-实战篇二-商户查询缓存
|
8月前
|
缓存 运维 监控
Redis 7.0 高性能缓存架构设计与优化
🌟蒋星熠Jaxonic,技术宇宙中的星际旅人。深耕Redis 7.0高性能缓存架构,探索函数化编程、多层缓存、集群优化与分片消息系统,用代码在二进制星河中谱写极客诗篇。
1515 3
|
9月前
|
SQL 运维 关系型数据库
【产品升级】Dataphin V5.0版本发布:助力出海业务、增全量一体集成、异步调用API等更多功能等你发现
Dataphin是瓴羊推出的智能数据建设与治理平台,基于阿里巴巴内部实践,提供一站式数据建设与治理能力。V5.0版本研发新增支持Databricks作为离线计算引擎、支持MySQL数据库一键增全量同步、支持管理Hudi、Delta Lake表等;资产运营与消费持续提效,支持批量编辑目录名称及描述、Quick BI仪表板的上架管理等功能,增加资产可用性与盘点效率。
418 8
|
9月前
|
缓存 NoSQL 关系型数据库
Redis缓存和分布式锁
Redis 是一种高性能的键值存储系统,广泛用于缓存、消息队列和内存数据库。其典型应用包括缓解关系型数据库压力,通过缓存热点数据提高查询效率,支持高并发访问。此外,Redis 还可用于实现分布式锁,解决分布式系统中的资源竞争问题。文章还探讨了缓存的更新策略、缓存穿透与雪崩的解决方案,以及 Redlock 算法等关键技术。
|
10月前
|
存储 JSON 前端开发
Django集成图片验证码功能:基于django-simple-captcha实现
在Web应用开发中,验证码是防止恶意攻击、自动化脚本滥用的重要手段。本文将介绍如何使用django-simple-captcha库在Django项目中快速集成图片验证码功能,包括安装配置、核心实现代码及使用方法。
259 0
|
12月前
|
监控 安全 Java
Java 开发中基于 Spring Boot 3.2 框架集成 MQTT 5.0 协议实现消息推送与订阅功能的技术方案解析
本文介绍基于Spring Boot 3.2集成MQTT 5.0的消息推送与订阅技术方案,涵盖核心技术栈选型(Spring Boot、Eclipse Paho、HiveMQ)、项目搭建与配置、消息发布与订阅服务实现,以及在智能家居控制系统中的应用实例。同时,详细探讨了安全增强(TLS/SSL)、性能优化(异步处理与背压控制)、测试监控及生产环境部署方案,为构建高可用、高性能的消息通信系统提供全面指导。附资源下载链接:[https://pan.quark.cn/s/14fcf913bae6](https://pan.quark.cn/s/14fcf913bae6)。
2444 0
|
NoSQL API Redis
redis的其他功能
瑞士军刀Redis image.png 慢查询 image.png image.png image.png image.
1191 0
|
缓存 NoSQL 关系型数据库
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?