[Springboot]SpringCache + Redis实现数据缓存

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 本文实现了SpringCache + Redis的集中式缓存,方便大家对学习了解缓存的使用。本文实现:SpringCache + Redis的组合通过配置文件实现了自定义key过期时间;key命名方式;value序列化方式实现本文代码的前提:已有一个可以运行的Springboot项目,实现了简单的CRUD功能


前言



本文实现了SpringCache + Redis的集中式缓存,方便大家对学习了解缓存的使用。

本文实现:

  • SpringCache + Redis的组合
  • 通过配置文件实现了自定义key过期时间;key命名方式;value序列化方式

实现本文代码的前提:

  • 已有一个可以运行的Springboot项目,实现了简单的CRUD功能


步骤


在Spring Boot中通过@EnableCaching注解自动化配置合适的缓存管理器(CacheManager),Spring Boot根据下面的顺序去侦测缓存提供者:

Generic
JCache (JSR-107)
EhCache 2.x
Hazelcast
Infinispan
Redis
Guava
Simple
复制代码

我们所需要做的就是实现一个将缓存数据放在Redis的缓存机制。

  • 添加pom.xml依赖
<!-- 缓存: spring cache -->
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
  </dependency>
  <!-- 缓存: redis -->
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
  </dependency>
复制代码

注意:- spring-boot-starter-data-redis和spring-boot-starter-redis的区别:blog.csdn.net/weixin_3852…

可以看出两个包并没有区别,但是当springBoot的版本为1.4.7 以上的时候,spring-boot-starter-redis 就空了。要想引入redis就只能选择有data的。

  • application.properties中加入redis连接设置(其它详细设置请查看参考网页)
# Redis
spring.redis.host=localhost
spring.redis.port=6379
spring.redis.pool.max-idle=8
spring.redis.pool.min-idle=0
spring.redis.pool.max-active=8
spring.redis.pool.max-wait=-1
spring.redis.database=0
spring.redis.password=xxx
复制代码
  • 新增KeyGeneratorCacheConfig.java(或者名为CacheConfig)文件

该文件完成三项设置:key过期时间;key命名方式;value序列化方式:JSON便于查看

package com.pricemonitor.pm_backend;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.lang.reflect.Method;
@Configuration
public class KeyGeneratorCacheConfig extends CachingConfigurerSupport {
    private final RedisTemplate redisTemplate;
    @Autowired
    public KeyGeneratorCacheConfig(RedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }
    @Override
    public CacheManager cacheManager() {
        // 设置key的序列化方式为String
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        // 设置value的序列化方式为JSON
        GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
        redisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer);
        RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
        // 设置默认过期时间为600秒
        cacheManager.setDefaultExpiration(600);
        return cacheManager;
    }
    /**
     * key值为className+methodName+参数值列表
     * @return
     */
    @Override
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object o, Method method, Object... args) {
                StringBuilder sb = new StringBuilder();
                sb.append(o.getClass().getName()).append("#");
                sb.append(method.getName()).append("(");
                for (Object obj : args) {
                    if(obj != null) { // 在可选参数未给出时时,会出现null,此时需要跳过
                        sb.append(obj.toString()).append(",");
                    }
                }
                sb.append(")");
                return sb.toString();
            }
        };
    }
}
复制代码
  • 在serviceImpl中加入@CacheConfig并且给给每个方法加入缓存(详细注解使用请查看参考网页)
@Service
@CacheConfig(cacheNames = "constant")
public class ConstantServiceImpl implements ConstantService {
    @Autowired
    private ConstantMapper constantMapper;
    @Cacheable
    @Override
    public List<Constant> alertMessage() {
        ConstantExample constantExample = new ConstantExample();
        ConstantExample.Criteria criteria = constantExample.createCriteria();
        criteria.andTypeEqualTo("alert");
        return constantMapper.selectByExample(constantExample);
    }
    @Cacheable
    @Override
    public List<Constant> noteMessage() {
        ConstantExample constantExample = new ConstantExample();
        ConstantExample.Criteria criteria = constantExample.createCriteria();
        criteria.andTypeEqualTo("note");
        return constantMapper.selectByExample(constantExample);
    }
    @Cacheable
    @Override
    public List<Constant> banner() {
        ConstantExample constantExample = new ConstantExample();
        ConstantExample.Criteria criteria = constantExample.createCriteria();
        criteria.andTypeEqualTo("banner");
        return constantMapper.selectByExample(constantExample);
    }
}
复制代码


效果图



注意事项


  • 若直接修改数据库的表,并没有提供接口修改的字段,缓存就没法更新。所以这种字段加缓存需要尤其注意缓存的有效性,最好让其及时过期。或者给其实现增删改接口。
  • 大坑:在可选参数未给出时时,会出现null,此时在生成Key名的时候需要跳过。已在代码中修改
for (Object obj : args) {
    if(obj != null) { // 在可选参数未给出时时,会出现null,此时需要跳过
        sb.append(obj.toString()).append(",");
    }
}


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
1月前
|
NoSQL Java 关系型数据库
微服务——SpringBoot使用归纳——Spring Boot 中集成Redis——Redis 介绍
本文介绍在 Spring Boot 中集成 Redis 的方法。Redis 是一种支持多种数据结构的非关系型数据库(NoSQL),具备高并发、高性能和灵活扩展的特点,适用于缓存、实时数据分析等场景。其数据以键值对形式存储,支持字符串、哈希、列表、集合等类型。通过将 Redis 与 Mysql 集群结合使用,可实现数据同步,提升系统稳定性。例如,在网站架构中优先从 Redis 获取数据,故障时回退至 Mysql,确保服务不中断。
110 0
微服务——SpringBoot使用归纳——Spring Boot 中集成Redis——Redis 介绍
|
1月前
|
缓存 NoSQL Java
基于SpringBoot的Redis开发实战教程
Redis在Spring Boot中的应用非常广泛,其高性能和灵活性使其成为构建高效分布式系统的理想选择。通过深入理解本文的内容,您可以更好地利用Redis的特性,为应用程序提供高效的缓存和消息处理能力。
167 79
|
1月前
|
缓存 监控 NoSQL
Redis--缓存击穿、缓存穿透、缓存雪崩
缓存击穿、缓存穿透和缓存雪崩是Redis使用过程中可能遇到的常见问题。理解这些问题的成因并采取相应的解决措施,可以有效提升系统的稳定性和性能。在实际应用中,应根据具体场景,选择合适的解决方案,并持续监控和优化缓存策略,以应对不断变化的业务需求。
110 29
|
27天前
|
人工智能 缓存 NoSQL
Redis 与 AI:从缓存到智能搜索的融合之路
Redis 已从传统缓存系统发展为强大的 AI 支持平台,其向量数据库功能和 RedisAI 模块为核心,支持高维向量存储、相似性搜索及模型服务。文章探讨了 Redis 在实时数据缓存、语义搜索与会话持久化中的应用场景,并通过代码案例展示了与 Spring Boot 的集成方式。总结来看,Redis 结合 AI 技术,为现代应用提供高效、灵活的解决方案。
|
1月前
|
机器学习/深度学习 人工智能 缓存
MHA2MLA:0.3%数据微调!复旦团队开源推理加速神器,KV缓存狂降96.87%
MHA2MLA是复旦大学、华东师范大学、上海AI Lab等机构联合推出的数据高效微调方法,通过引入多头潜在注意力机制(MLA),显著优化基于Transformer的LLM推理效率,降低推理成本。
90 1
MHA2MLA:0.3%数据微调!复旦团队开源推理加速神器,KV缓存狂降96.87%
|
1月前
|
存储 人工智能 NoSQL
SpringBoot整合Redis、ApacheSolr和SpringSession
本文介绍了如何使用SpringBoot整合Redis、ApacheSolr和SpringSession。SpringBoot以其便捷的配置方式受到开发者青睐,通过引入对应的starter依赖,可轻松实现功能整合。对于Redis,可通过配置RedisSentinel实现高可用;SpringSession则提供集群Session管理,支持多种存储方式如Redis;整合ApacheSolr时,借助Zookeeper搭建SolrCloud提高可用性。文中详细说明了各组件的配置步骤与代码示例,方便开发者快速上手。
58 11
|
1月前
|
存储 NoSQL 算法
Redis分片集群中数据是怎么存储和读取的 ?
Redis集群采用的算法是哈希槽分区算法。Redis集群中有16384个哈希槽(槽的范围是 0 -16383,哈希槽),将不同的哈希槽分布在不同的Redis节点上面进行管理,也就是说每个Redis节点只负责一部分的哈希槽。在对数据进行操作的时候,集群会对使用CRC16算法对key进行计算并对16384取模(slot = CRC16(key)%16383),得到的结果就是 Key-Value 所放入的槽,通过这个值,去找到对应的槽所对应的Redis节点,然后直接到这个对应的节点上进行存取操作
|
1月前
|
缓存 NoSQL 关系型数据库
Redis和Mysql如何保证数据⼀致?
1. 先更新Mysql,再更新Redis,如果更新Redis失败,可能仍然不⼀致 2. 先删除Redis缓存数据,再更新Mysql,再次查询的时候在将数据添加到缓存中 这种⽅案能解决1 ⽅案的问题,但是在⾼并发下性能较低,⽽且仍然会出现数据不⼀致的问题,⽐如线程1删除了 Redis缓存数据,正在更新Mysql,此时另外⼀个查询再查询,那么就会把Mysql中⽼数据⼜查到 Redis中 1. 使用MQ异步同步, 保证数据的最终一致性 我们项目中会根据业务情况 , 使用不同的方案来解决Redis和Mysql的一致性问题 : 1. 对于一些一致性要求不高的场景 , 不做处理例如 : 用户行为数据 ,
|
1月前
|
NoSQL Redis
Redis的数据淘汰策略有哪些 ?
Redis 提供 8 种数据淘汰策略: 淘汰易失数据(具有过期时间的数据) 1. volatile-lru(least recently used):从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰 2. volatile-lfu(least frequently used):从已设置过期时间的数据集(server.db[i].expires)中挑选最不经常使用的数据淘汰 3. volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰 4. volatile-random:从已设置过期
|
1月前
|
NoSQL Redis
Redis的数据持久化策略有哪些 ?
Redis 提供了两种方式,实现数据的持久化到硬盘。 1. RDB 持久化(全量),是指在指定的时间间隔内将内存中的数据集快照写入磁盘。 2. AOF持久化(增量),以日志的形式记录服务器所处理的每一个写、删除操作 RDB和AOF一起使用, 在Redis4.0版本支持混合持久化方式 ( 设置 aof-use-rdb-preamble yes )

热门文章

最新文章

下一篇
oss创建bucket