玩转Spring Cache --- 整合分布式缓存Redis Cache(使用Lettuce、使用Spring Data Redis)【享学Spring】(上)

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: 玩转Spring Cache --- 整合分布式缓存Redis Cache(使用Lettuce、使用Spring Data Redis)【享学Spring】(上)

前言


最近都在聊Spring的缓存抽象Spring Cache,上篇文章深入介绍了Spring Cache集成进程缓存的第三方组件如Caffeine、Ehcache,若对此篇文章感兴趣,可移步观看:【小家Spring】玩转Spring Cache — 整合进程缓存之王Caffeine Cache和Ehcache3.x


我们知道现在的应用大都以微服务的方式进行分布式部署,因此如果仅仅使用本地缓存是 满足不了/难以满足 我们需求的(Infinispan这种基于本地内存实现的分布式缓存不在本文讨论范围~)。针对分布式场景下的缓存应用,我们急需要一个高可用的、快速的、中心化的、分布式的缓存产品。然后在众多此场景的实现产品中,Redis以它众多优秀的特性脱颖而出。


so,本文就以大伙最关心、最熟悉的Redis这个缓存产品为例,让它和Spring Cache集成,达到分布式中心缓存的效果(支持缓存直接直接操作)。


Redis:一个基于键值对存储的NoSQL内存数据库,可存储复杂的数据结构,如List, Set, Hashes。

关于Redis的单线程、数据结构、序列化、网络IO、高吞吐等高级特性,不是本文讨论的范围。本文只讨论集成注解缓存的k-v结构


Spring Data Redis简介和使用示例


Spring构建了自己庞大的生态,它对很多优秀的、流行的产品提供了一整套的整合、解决方案。Redis在缓存界这么广受欢迎,Spring Data工程中自然少不了它,它就是Spring Data Redis。


Spring Data Redis对Redis底层开发包(Jedis、Lettuce、JRedis、RJC)进行了高度封装。RedisTemplate封装提供了redis各种操作、异常处理及序列化,完全屏蔽里底层实现(使用者面向Spring Data编程即可,可完全不用关心底层到底使用的是Jedis or Lettuce)。


Spring Data Redis这个Jar的依赖包如下:


image.png


另外有个使用的Tips需要注意:在Spring Data Redis的使用方面上,我们还需要重视版本的差异:


其实我一直在强调版本意识,不管是在Spring上、JDK上,还是MyBatis,版本意识对你做架构都非常的重要


Spring Data Redis1.x截图:


image.png


Spring Data Redis2.x截图:


image.png


版本的差异从包结构上就能一目了然。具体到源码处,从RedisConnectionFactory接口的继承图也能看出差异:


image.png


image.png

由图可知,从2.x版本开始,Spring就只为我们保留了jedis和lettuce。

lettuce是redis连接池未来的发展趋势,2.x开始已经推荐使用lettuce作为访问redis的client客户端。


不管用什么客户端,对使用者应该都是透明的,因为在开发过程中,没有极其特殊的情况,应该规定只允许使用RedisTemplate来操作Redis。


使用Jedis作为Client操作Redis示例


虽然说Jedis有多线程安全问题,并且它的性能也堪忧,大有被淘汰的趋势。但是,但是,但是毕竟它还仍旧还是当下的主流的Java访问Redis的客户端,所以本文也有必要把它的使用说一下,供以参考:


第一步:导包(本文以2.x为例)

<!-- 使用Spring Data Redis 操作Redis缓存 -->
<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-redis</artifactId>
    <version>2.1.9.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.10.2</version>
</dependency>


第二步:准备Config配置文件

//@EnableCaching // 因为此处我没准备CacheManager,暂时关闭缓存注解
@Configuration
public class CacheConfig extends CachingConfigurerSupport {
    @Bean
    public RedisConnectionFactory redisConnectionFactory() {
        RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration();
        // 2.0后的写法
        configuration.setHostName("10.102.132.150");
        //configuration.setPassword(RedisPassword.of("123456"));
        configuration.setPort(6379);
        configuration.setDatabase(0);
        JedisConnectionFactory factory = new JedisConnectionFactory(configuration);
        // Spring Data Redis1.x这么来设置  2.0后建议使用RedisStandaloneConfiguration来取代
        //factory.setHostName("10.102.132.150");
        //factory.setPassword("123456");
        //factory.setPort(6379);
        //factory.setDatabase(0);
        return factory;
    }
    @Bean
    public RedisTemplate<String, String> stringRedisTemplate() {
        RedisTemplate<String, String> redisTemplate = new StringRedisTemplate();
        redisTemplate.setConnectionFactory(redisConnectionFactory());
        return redisTemplate;
    }
}


运行单元测试:


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {RootConfig.class, CacheConfig.class})
public class TestSpringBean {
    @Autowired
    private RedisConnectionFactory redisConnectionFactory;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Test
    public void test1() {
        System.out.println(redisConnectionFactory);
        System.out.println(redisConnectionFactory.getConnection());
        //System.out.println(redisConnectionFactory.getClusterConnection()); //InvalidDataAccessApiUsageException: Cluster is not configured!
        //System.out.println(redisConnectionFactory.getSentinelConnection()); // InvalidDataAccessResourceUsageException: No Sentinels configured
        System.out.println(redisTemplate);
        redisTemplate.opsForValue().set("name", "fsx");
        System.out.println(redisTemplate.opsForValue().get("name"));
    }
}


打印输出:


org.springframework.data.redis.connection.jedis.JedisConnectionFactory@238b521e
org.springframework.data.redis.connection.jedis.JedisConnection@1cefc4b3
org.springframework.data.redis.core.StringRedisTemplate@2b27cc70
fsx


并且Redis Server端也能查看到key为“name”的值:


image.png


由此证明我们的缓存配置都能正常work了,能够使用RedisTempate操作Redis了。部分很简单有木有,只需要简单的两步即可达到目的~


关于Jedis或者说RedisTemplate的详细使用,显然也不是本文的重点,有兴趣的可自行研究,或者出门左拐~


使用Lettuce作为Client操作Redis示例

Lettuce作为新时代的Redis客户端,它势必成为将来的主流(其实现在也很主流了,比如SpringBoot2.0后默认就使用它作为Redis的Client访问)。


第一步:同样的导包(此处导入lettuce作为客户端)

<!-- 使用Spring Data Redis 操作Redis缓存 -->
<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-redis</artifactId>
    <version>2.1.9.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.lettuce/lettuce-core -->
<dependency>
    <groupId>io.lettuce</groupId>
    <artifactId>lettuce-core</artifactId>
    <version>5.1.7.RELEASE</version>
</dependency>


第二步:准备Config配置文件


//@EnableCaching
@Configuration
public class CacheConfig extends CachingConfigurerSupport {
    @Bean
    public RedisConnectionFactory redisConnectionFactory() {
        // RedisStandaloneConfiguration这个配置类是Spring Data Redis2.0后才有的~~~
        RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration();
        // 2.0后的写法
        configuration.setHostName("10.102.132.150");
        //configuration.setPassword(RedisPassword.of("123456"));
        configuration.setPort(6379);
        configuration.setDatabase(0);
        LettuceConnectionFactory factory = new LettuceConnectionFactory(configuration);
        // Spring Data Redis1.x这么来设置  2.0后建议使用RedisStandaloneConfiguration来取代
        //factory.setHostName("10.102.132.150");
        //factory.setPassword("123456");
        //factory.setPort(6379);
        //factory.setDatabase(0);
        return factory;
    }
    @Bean
    public RedisTemplate<String, String> stringRedisTemplate() {
        RedisTemplate<String, String> redisTemplate = new StringRedisTemplate();
        redisTemplate.setConnectionFactory(redisConnectionFactory());
        return redisTemplate;
    }
}


用上了Spring Data Redis2.0提供的RedisStandaloneConfiguration配置类后,配置步骤和Jedis的一毛一样


运行如上的单元测试,打印结果如下:


org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory@59942b48
14:35:00.798 [main] INFO  io.lettuce.core.EpollProvider - Starting without optional epoll library
14:35:00.800 [main] INFO  io.lettuce.core.KqueueProvider - Starting without optional kqueue library
org.springframework.data.redis.connection.lettuce.LettuceConnection@3cf7298d
org.springframework.data.redis.core.StringRedisTemplate@1ff55ff
fsx


从日志中会发现多输出了两句info日志,结果都是ok的,能正常work。




说明:SpringBoot1.x最终依赖的是Spring Data Redis 1.8.xx,默认导入使用的是Jedis客户端,版本号为2.9.x(非最新的3.x,不兼容,慎用)

SpringBoot2.0开始,依赖的是Spring Data Redis 2.x/x,并且默认导入使用的是Lettuce客户端,版本号是从5.x.x开始

当然,不管是Boot1.x或者2.x,都是允许你手动切换的(只是完全没有必要而已)。


相关实践学习
基于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 Redis
redis的基本命令,并用netty操作redis(不使用springboot或者spring框架)就单纯的用netty搞。
这篇文章介绍了Redis的基本命令,并展示了如何使用Netty框架直接与Redis服务器进行通信,包括设置Netty客户端、编写处理程序以及初始化Channel的完整示例代码。
38 1
redis的基本命令,并用netty操作redis(不使用springboot或者spring框架)就单纯的用netty搞。
|
19天前
|
缓存 NoSQL Java
Spring Boot与Redis:整合与实战
【10月更文挑战第15天】本文介绍了如何在Spring Boot项目中整合Redis,通过一个电商商品推荐系统的案例,详细展示了从添加依赖、配置连接信息到创建配置类的具体步骤。实战部分演示了如何利用Redis缓存提高系统响应速度,减少数据库访问压力,从而提升用户体验。
51 2
|
30天前
|
存储 Java API
如何使用 Java 记录简化 Spring Data 中的数据实体
如何使用 Java 记录简化 Spring Data 中的数据实体
34 9
|
5天前
|
JavaScript NoSQL Java
CC-ADMIN后台简介一个基于 Spring Boot 2.1.3 、SpringBootMybatis plus、JWT、Shiro、Redis、Vue quasar 的前后端分离的后台管理系统
CC-ADMIN后台简介一个基于 Spring Boot 2.1.3 、SpringBootMybatis plus、JWT、Shiro、Redis、Vue quasar 的前后端分离的后台管理系统
23 0
|
1月前
|
NoSQL Java Redis
在 Spring 中操作 Redis
本文详细介绍了在Spring框架中如何通过引入依赖、配置文件、使用StringRedisTemplate类以及执行原生命令等方式来操作Redis数据库,并提供了对String、List、Set、Hash和ZSet数据类型的操作示例。
54 0
在 Spring 中操作 Redis
|
2月前
|
NoSQL 网络协议 Java
[Redis] 渐进式遍历+使用jedis操作Redis+使用Spring操作Redis
[Redis] 渐进式遍历+使用jedis操作Redis+使用Spring操作Redis
40 7
|
2月前
|
消息中间件 Java 对象存储
数据一致性挑战:Spring Cloud与Netflix OSS下的分布式事务管理
数据一致性挑战:Spring Cloud与Netflix OSS下的分布式事务管理
49 2
|
1月前
|
存储 NoSQL Java
Spring Boot项目中使用Redis实现接口幂等性的方案
通过上述方法,可以有效地在Spring Boot项目中利用Redis实现接口幂等性,既保证了接口操作的安全性,又提高了系统的可靠性。
32 0
|
1月前
|
存储 缓存 NoSQL
数据的存储--Redis缓存存储(一)
数据的存储--Redis缓存存储(一)
|
30天前
|
消息中间件 缓存 NoSQL
Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。
【10月更文挑战第4天】Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。随着数据增长,有时需要将 Redis 数据导出以进行分析、备份或迁移。本文详细介绍几种导出方法:1)使用 Redis 命令与重定向;2)利用 Redis 的 RDB 和 AOF 持久化功能;3)借助第三方工具如 `redis-dump`。每种方法均附有示例代码,帮助你轻松完成数据导出任务。无论数据量大小,总有一款适合你。
67 6