Redis应用 02、Springboot整合redis

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: Redis应用 02、Springboot整合redis

一、认识@EnableCaching与@Cacheable


1.1、理论介绍


spring为了方便缓存的使用,提供了一层缓存抽象,而譬如ehcache、redis等第三方缓存框架,spring则为它们提供了实现。


spring的缓存抽象主要依靠org.springframework.cache.Cache接口和org.springframework.cache.CacheManager接口。对于不同的缓存框架,对应不同的CacheManager实现。


针对于Spring自己本身实现了ConcurrentMapCacheManager,对于缓存一般都是key,map形式,该CacheManager实现是将缓存数据存储在JDKConcurrentMap中。


在Spring-context模块中就提供了cache相关实现。




1.2、最佳实践(Spring的Cache管理器结合Redis进行方法级别存储)


准备


框架版本:springboot 2.5.2


在springboot中自动就会给我们引入spring、springmvc一些主流的第三方框架,并且能够帮助我们进行自动配置!使用起来也十分方便。


step1:在启动类上添加注解


@EnableCaching  //表示开启缓存


step2:在指定的方法上添加@Cacheable,对方法的返回值进行缓存


//cacheNames:表示对应指定map的名称(说明我们要将本次缓存的内容放置到user对应的map集合里)
//key表示值为user对应map中entry的key值,方法的返回值则是该entry的value
@Cacheable(cacheNames = {"user"},key="targetClass.getName()+'.'+methodName+'.'+#id")
@Override
public User queryById(Integer id) {
    return userMapper.selectById(id);
}


此时我们就已经完成了配置,为了方便测试,通过自动注入来看一下默认Spring使用的是哪一个CacheManager实现类:




测试


测试请求:http://localhost:9999/user/2



此时我们就能够确定默认使用的是Spring自带的ConcurrentMapCacheManager



测试效果:


第一次请求访问时,会正常进入service方法中,并对数据库进行查询。

第二次请求访问,不会进入到servcie方法,而是直接从对应的缓存(ConcurrentMapCacheManager)中读取直接返回给controller。



说明:通过该种方式我们能够将方法级别的返回值来优雅快速的存储到我们的redis中,简直是秒啊。



二、Springboot2整合redis使用lettuce连接池


说明:引入依赖之后默认使用jdk来进行序列化(JdkSerializationRedisSerializer),其底层就是使用的ObjectOutputstream来进行序列化。


默认会序列化转为byte[]数组来进行存储。

如下我们存储存储的是set("key1","changlu")此时就会出现乱码问题!




2.1、前提准备


实操


配置依赖:


<!--redis配置-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--若是springboot2.5.4,就需要引入下面的jar-->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
    <version>2.4.2</version>
</dependency>



分析


在该启动器依赖中使用了lettuce-core来替代之前使用jedis来进行连接redis。


在SpringBoot2.x之后,原本使用的jedis被替换为了lettuce。


jedis:采用直连,多个线程操作的话是不安全的,如果要避免不安全的情况,要使用JedisPool连接池,像BIO,又有其他问题。
lettuce:底层采用netty,实例可以在多个线程中进行共享,不存在线程不安全的情况,可以减少线程的数量,更像NIO模式



2.2、编写redis配置类(RedisConfig)


RedisTemplate:由于redistemplate默认序列化采用的是JDK序列化的方式,会转成byte[]数组来进行存储,就会出现乱码问题,所以我们这里对字符串的key、value以及hash的key、value分别做string字符串序列化与json序列化方式。根据实际需求来进行配置。


额外可配置(之后补充):LettuceConnectionFactory、CacheManager


可参考:springboot2整合redis使用lettuce连接池(解决lettuce连接池无效问题)
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
 * Redis的核心配置类
 * @author changlu
 * @date 2021/08/20 16:59
 **/
@Configuration
public class RedisConfig {
    //对RedisTemplate来进行配置
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        //1.初始化一个redisTemplate
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        //2.序列话(一般用于key值)
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        //3.引入json串的转化类(一般用于value的处理)
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        //3.1、设置ObjectMapper的访问权限
        ObjectMapper objectMapper=new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        //3.2指定序列化输入类型,就是将数据库里的数据按照一定类型存储到redis缓存中。
        //objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);//最近升级SpringBoot,发现enableDefaultTyping方法过期过期了。可以使用下面的方法代替
        objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,
                ObjectMapper.DefaultTyping.NON_FINAL,
                JsonTypeInfo.As.WRAPPER_ARRAY);
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
        //4、创建连接
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        //4.1、redis的key值序列化
        redisTemplate.setKeySerializer(stringRedisSerializer);
        //4.2、redis的value值序列化
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        //4.3、对于hash 的key进行序列化
        redisTemplate.setHashKeySerializer(stringRedisSerializer);
        //4.4、对于hash 的value进行序列化
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
        return redisTemplate;
    }
}



2.3、实操测试


这里我们方便测试直接来存储string的key与value:


@SpringBootTest
class TestApplicationTests {
    @Autowired
    private RedisTemplate redisTemplate;
    @Test
    public void test() {
        RedisConnection connection = (RedisConnection) redisTemplate.getConnectionFactory().getConnection();
        System.out.println(connection.ping());
        connection.flushDb();
        //字符串操作
        redisTemplate.opsForValue().set("key1",new User(18L,"changlu",18,"liner",15));
        System.out.println(redisTemplate.opsForValue().get("key1"));
    }
}





三、redisTemplate


redisTemplate常用方法


redisTemplate.opsForValue();  //操作字符串
redisTemplate.opsForHash();   //操作hash
redisTemplate.opsForList();   //操作list
redisTemplate.opsForSet();    //操作set
redisTemplate.opsForZSet();   //操作有序set


其他方法:


expire(key,time,unit)  //对指定key设置失效时间

getExpire(key):获取指定的key的失效时间

相关文章
|
19天前
|
消息中间件 缓存 NoSQL
Redis各类数据结构详细介绍及其在Go语言Gin框架下实践应用
这只是利用Go语言和Gin框架与Redis交互最基础部分展示;根据具体业务需求可能需要更复杂查询、事务处理或订阅发布功能实现更多高级特性应用场景。
149 86
|
6月前
|
canal NoSQL 关系型数据库
Redis应用—7.大Value处理方案
本文介绍了一种用于监控Redis大key的方案设计及其实现步骤。主要内容包括:方案设计、安装与配置环境、binlog数据消费者。
267 29
Redis应用—7.大Value处理方案
|
18天前
|
NoSQL Java 调度
分布式锁与分布式锁使用 Redis 和 Spring Boot 进行调度锁(不带 ShedLock)
分布式锁是分布式系统中用于同步多节点访问共享资源的机制,防止并发操作带来的冲突。本文介绍了基于Spring Boot和Redis实现分布式锁的技术方案,涵盖锁的获取与释放、Redis配置、服务调度及多实例运行等内容,通过Docker Compose搭建环境,验证了锁的有效性与互斥特性。
分布式锁与分布式锁使用 Redis 和 Spring Boot 进行调度锁(不带 ShedLock)
|
28天前
|
存储 缓存 监控
Redis分区的核心原理与应用实践
Redis分区通过将数据分散存储于多个节点,提升系统处理高并发与大规模数据的能力。本文详解分区原理、策略及应用实践,涵盖哈希、范围、一致性哈希等分片方式,分析其适用场景与性能优势,并探讨电商秒杀、物联网等典型用例,为构建高性能、可扩展的Redis集群提供参考。
63 0
|
6月前
|
NoSQL Java 关系型数据库
微服务——SpringBoot使用归纳——Spring Boot 中集成Redis——Redis 介绍
本文介绍在 Spring Boot 中集成 Redis 的方法。Redis 是一种支持多种数据结构的非关系型数据库(NoSQL),具备高并发、高性能和灵活扩展的特点,适用于缓存、实时数据分析等场景。其数据以键值对形式存储,支持字符串、哈希、列表、集合等类型。通过将 Redis 与 Mysql 集群结合使用,可实现数据同步,提升系统稳定性。例如,在网站架构中优先从 Redis 获取数据,故障时回退至 Mysql,确保服务不中断。
272 0
微服务——SpringBoot使用归纳——Spring Boot 中集成Redis——Redis 介绍
|
2月前
|
NoSQL Java Redis
Redis基本数据类型及Spring Data Redis应用
Redis 是开源高性能键值对数据库,支持 String、Hash、List、Set、Sorted Set 等数据结构,适用于缓存、消息队列、排行榜等场景。具备高性能、原子操作及丰富功能,是分布式系统核心组件。
381 2
|
3月前
|
NoSQL 网络协议 Java
【Azure Redis】Redis服务端的故障转移(Failover)导致客户端应用出现15分钟超时问题的模拟及解决
在使用 Azure Cache for Redis 服务时,因服务端维护可能触发故障转移。Linux 环境下使用 Lettuce SDK 会遇到超时 15 分钟的已知问题。本文介绍如何通过重启 Primary 节点主动复现故障转移,并提供多种解决方案,包括调整 TCP 设置、升级 Lettuce 版本、配置 TCP_USER_TIMEOUT 及使用其他 SDK(如 Jedis)来规避此问题。
144 1
|
6月前
|
缓存 NoSQL Java
基于SpringBoot的Redis开发实战教程
Redis在Spring Boot中的应用非常广泛,其高性能和灵活性使其成为构建高效分布式系统的理想选择。通过深入理解本文的内容,您可以更好地利用Redis的特性,为应用程序提供高效的缓存和消息处理能力。
522 79
|
6月前
|
缓存 NoSQL Java
Redis应用—6.热key探测设计与实践
热key问题在高并发系统中可能导致数据层和服务层的严重瓶颈,如Redis集群瘫痪和用户体验下降。为解决此问题,京东开发了JdHotkey热key探测框架,具备实时性、准确性、集群一致性和高性能等特点。该框架由etcd集群、Client端jar包、Worker端集群和Dashboard控制台组成,通过分布式计算快速识别热key并推送至应用内存,有效减轻数据层负载,提升服务性能。JdHotkey适用于多种场景,安装部署简便,支持毫秒级热key探测和集群一致性维护。
323 61
Redis应用—6.热key探测设计与实践
|
3月前
|
SQL Java 数据库
解决Java Spring Boot应用中MyBatis-Plus查询问题的策略。
保持技能更新是侦探的重要素质。定期回顾最佳实践和新技术。比如,定期查看MyBatis-Plus的更新和社区的最佳做法,这样才能不断提升查询效率和性能。
164 1