首先不得不服Spring这个宇宙无敌的开源框架,几乎整合了所有流行的其它框架,http://projects.spring.io/spring-data/ 从这上面看,当下流行的redis、solr、hadoop、mongoDB、couchBase... 全都收入囊中。对于redis整合而言,主要用到的是spring-data-redis
使用步骤:
一、pom添加依赖项
<dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>1.4.1.RELEASE</version> </dependency>
其它Spring必备组件,比如Core,Beans之类,大家自行添加吧
观察一下:
jedis、jredis等常用java的redis client已经支持了,不知道以后会不会集成Redisson,spring-data-redis提供了一个非常有用的类:StringRedisTemplate
对于大多数缓存应用场景而言,字符串是最常用的缓存项,用StringRedisTemplate可以轻松应付。
二、spring配置
1 <bean id="redisSentinelConfiguration" 2 class="org.springframework.data.redis.connection.RedisSentinelConfiguration"> 3 <property name="master"> 4 <bean class="org.springframework.data.redis.connection.RedisNode"> 5 <property name="name" value="mymaster"></property> 6 </bean> 7 </property> 8 <property name="sentinels"> 9 <set> 10 <bean class="org.springframework.data.redis.connection.RedisNode"> 11 <constructor-arg index="0" value="10.6.1**.**5" /> 12 <constructor-arg index="1" value="7031" /> 13 </bean> 14 <bean class="org.springframework.data.redis.connection.RedisNode"> 15 <constructor-arg index="0" value="10.6.1**.**6" /> 16 <constructor-arg index="1" value="7031" /> 17 </bean> 18 <bean class="org.springframework.data.redis.connection.RedisNode"> 19 <constructor-arg index="0" value="10.6.1**.**1" /> 20 <constructor-arg index="1" value="7031" /> 21 </bean> 22 </set> 23 </property> 24 </bean> 25 26 <bean id="jedisConnFactory" 27 class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"> 28 <constructor-arg ref="redisSentinelConfiguration" /> 29 </bean> 30 31 <bean id="stringRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate"> 32 <property name="connectionFactory" ref="jedisConnFactory" /> 33 </bean>
提示:上面配置中的端口为sentinel的端口,而非redis-server的端口。
这里我们使用Sentinel模式来配置redis连接,从上篇学习知道,sentinel是一种高可用架构,个人推荐在生产环境中使用sentinel模式。
注:26-28行,经试验,如果修改了默认端口,这里必须明细指定hostName及port,否则运行后,无法正确读写缓存,参考下面的配置:
(2016-4-2更新:最新1.6.4版的spring-data-redis 已经修正了这个问题,无需再指定端口和hostname)
<bean id="jedisConnFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"> <property name="hostName" value="10.6.53.xxx"/> <property name="port" value="8830"/> <property name="usePool" value="false"/> <constructor-arg ref="redisSentinelConfiguration"/> </bean>
其中hostName为当前master的IP,port为redis-server的运行端口(非sentinel端口),此外还要设置 usePool为false,由于sentinel可能会自行切换master节点,如果不清楚当前的master节点是哪台机器,可以用前面提到的命令./redis-cli -p <sentinal端口号> sentinel masters查看,或者用java代码输出,参考下面的代码:
1 ApplicationContext ctx = new FileSystemXmlApplicationContext("/opt/app/spring-redis.xml"); 2 StringRedisTemplate template = ctx.getBean(StringRedisTemplate.class); 3 for (RedisServer m : template.getConnectionFactory().getSentinelConnection().masters()) { 4 logger.debug(m); 5 }
另外<property name="usePool" value="false"/> 这里的value值如果改成true,经实际测试,发现偶尔会报如下错误(如果报错,换成false通常就可以了):
redis.clients.jedis.exceptions.JedisDataException: ERR unknown command 'SET'
其它注意事项:
配置文件中的sentinels属性的Set 中的节点,并非一定要在同一个master下,也可以是归属于多个master,即:如果这里配置了10个node信息,其中1-3归属于master1,剩下的4-10属于master2,这也是允许的。
这样调用时,通过StringRedisTemplate.getConnectionFactory().getSentinelConnection().masters()可以返回一个master的列表,然后代码中根据需要,向某一个需要的master写入缓存.
三、单元测试
1 @Test 2 public void testSpringRedis() { 3 ConfigurableApplicationContext ctx = null; 4 try { 5 ctx = new ClassPathXmlApplicationContext("spring.xml"); 6 7 StringRedisTemplate stringRedisTemplate = ctx.getBean("stringRedisTemplate", StringRedisTemplate.class); 8 9 // String读写 10 stringRedisTemplate.delete("myStr"); 11 stringRedisTemplate.opsForValue().set("myStr", "http://yjmyzz.cnblogs.com/"); 12 System.out.println(stringRedisTemplate.opsForValue().get("myStr")); 13 System.out.println("---------------"); 14 15 // List读写 16 stringRedisTemplate.delete("myList"); 17 stringRedisTemplate.opsForList().rightPush("myList", "A"); 18 stringRedisTemplate.opsForList().rightPush("myList", "B"); 19 stringRedisTemplate.opsForList().leftPush("myList", "0"); 20 List<String> listCache = stringRedisTemplate.opsForList().range( 21 "myList", 0, -1); 22 for (String s : listCache) { 23 System.out.println(s); 24 } 25 System.out.println("---------------"); 26 27 // Set读写 28 stringRedisTemplate.delete("mySet"); 29 stringRedisTemplate.opsForSet().add("mySet", "A"); 30 stringRedisTemplate.opsForSet().add("mySet", "B"); 31 stringRedisTemplate.opsForSet().add("mySet", "C"); 32 Set<String> setCache = stringRedisTemplate.opsForSet().members( 33 "mySet"); 34 for (String s : setCache) { 35 System.out.println(s); 36 } 37 System.out.println("---------------"); 38 39 // Hash读写 40 stringRedisTemplate.delete("myHash"); 41 stringRedisTemplate.opsForHash().put("myHash", "PEK", "北京"); 42 stringRedisTemplate.opsForHash().put("myHash", "SHA", "上海虹桥"); 43 stringRedisTemplate.opsForHash().put("myHash", "PVG", "浦东"); 44 Map<Object, Object> hashCache = stringRedisTemplate.opsForHash() 45 .entries("myHash"); 46 for (Map.Entry<Object, Object> entry : hashCache.entrySet()) { 47 System.out.println(entry.getKey() + " - " + entry.getValue()); 48 } 49 50 System.out.println("---------------"); 51 52 } finally { 53 if (ctx != null && ctx.isActive()) { 54 ctx.close(); 55 } 56 } 57 58 }
运行一下,行云流水般的输出:
...
信息: Created JedisPool to master at 10.6.144.***:7030
http://yjmyzz.cnblogs.com/
---------------
0
A
B
---------------
C
B
A
---------------
SHA - 上海虹桥
PVG - 浦东
PEK - 北京
---------------
...
注意红色标出部分,从eclipse控制台的输出,还能看出当前的master是哪台服务器
这里再补充一点小技巧:如果想遍历所有master及slave可以参考以下代码
1 @Test 2 public void testGetAllMasterAndSlaves() { 3 ApplicationContext ctx = new FileSystemXmlApplicationContext("D:/spring-redis.xml"); 4 StringRedisTemplate template = ctx.getBean(StringRedisTemplate.class); 5 RedisSentinelConnection conn = template.getConnectionFactory().getSentinelConnection(); 6 for (RedisServer m : conn.masters()) { 7 System.out.println("master => " + m);//打印master信息 8 Collection<RedisServer> slaves = conn.slaves(m); 9 //打印该master下的所有slave信息 10 for (RedisServer s : slaves) { 11 System.out.println("slaves of " + m + " => " + s); 12 } 13 System.out.println("--------------"); 14 } 15 ((FileSystemXmlApplicationContext) ctx).close(); 16 }
输出类似下面的结果:
master => 172.20.16.191:6379
slaves of 172.20.16.191:6379 => 172.20.16.192:6379
注:这里输出的slaves列表,经实际测试,发现只是根据redis server端的配置呆板的返回slave node列表,不管这些node是死是活,换句话说,就算某个slave已经down掉,这里依然会返回。
三、POJO对象的缓存
Spring提供的StringRedisTemplate只能对String操作,大多数情况下已经够用,但如果真需要向redis中存放POJO对象也不难,我们可以参考StringRedisTemplate的源码,扩展出ObjectRedisTemplate
然后就可以这样用了:
其中SampleBean的定义如下:
注:由于不是标准的String类型,所以在redis控制台,用./redis-cli get myBean是看不到缓存内容的,只能得到nil的输出,不要误以为set没成功!通过代码是可以正常get到缓存值的。
另外关于POJO对象的缓存,还有二个注意事项:
a) POJO类必须要有默认的无参构造函数,否则反序列化时会报错
b) ObjectRedisTemplate<T>中 的T不能是接口,比如 DomainModelA继承自接口 IModelA,使用ObjectRedisTemplate时,要写成 ObjectRedisTemplate<DomainModelA>而不是 ObjectRedisTemplate<IModelA>,否则反序列化时也会出错
http://www.cnblogs.com/yjmyzz/p/4113019.html
相关推荐
1. **高可用性**:Redis支持主从复制和哨兵(Sentinel)集群,确保会话数据的可靠性。 2. **高性能**:Redis的数据操作在内存中完成,提供极快的读写速度。 3. **可扩展性**:通过Redis集群,可以轻松扩展以应对高并发...
Sentinel是Redis的高可用性解决方案,它监控Redis主从集群,当主节点故障时,Sentinel会自动将从节点提升为新的主节点,并更新所有客户端的连接指向新的主节点,从而实现系统的无缝切换和高可用性。在Java应用中,...
10. **Sentinel和Cluster支持**:如果Redis部署在高可用环境中,如Sentinel集群或Cluster模式,Spring Data Redis也能很好地支持,通过配置相应的连接工厂即可。 综上所述,"spring-data-redis-1.6.0.RELEASE.jar +...
同时,你还需要了解Redis的持久化、主从复制、Sentinel哨兵系统以及Cluster集群等高级特性,以应对不同的应用场景和需求。 总的来说,"redis-2.6.jar"是Java开发者在Windows环境中与Redis交互的重要工具,它允许...
例如,spring.redis.sentinel.master可以设置主节点名称,spring.redis.sentinel.nodes可以设置哨兵节点的列表。 在实际应用中,开发者可以结合Spring Boot的自动配置功能,通过简单的配置就能完成对Redis连接器的...
在IT行业中,Redis是一个广泛...通过`spring-redis`压缩包文件,开发者可以获得示例代码和配置,进一步学习和实践Spring与Redis的集成。在实践中不断调整优化,才能更好地利用Redis的特性,为应用程序带来最大的价值。
在Java开发中,Redis Sentinel是实现高可用Redis集群的关键组件,它主要负责监控主从节点的状态,当主节点出现故障时,Sentinel会自动进行故障转移,将从节点提升为主节点,确保服务的连续性。这里我们将深入探讨...
11. **Spring Data Redis**: 如果你的项目使用了Spring框架,Spring Data Redis模块可以简化与Redis的集成,提供了一套基于注解的编程模型。 12. **性能调优**: 使用Redis时,需要关注数据结构的选择、过期策略、...
《Spring MVC、Shiro与Redis集群的整合应用详解》 在现代Web开发中,安全管理和数据缓存是两个至关重要的环节。Apache Shiro是一个强大且易用的Java安全框架,负责处理认证、授权、会话管理和加密等任务。Redis则是...
- **Sentinel监控和故障转移**:通过Redis Sentinel可以监控集群状态并自动处理主从切换。 - **Cluster Slot分配**:了解Redis集群的槽分配机制,确保数据分布均匀。 - **连接池管理**:合理设置连接池大小,避免...
Spring框架作为Java企业级应用的主流选择,提供了与各种数据存储系统的整合方案,包括Redis。本教程将深入探讨如何在Spring环境中整合Redis,包括使用Spring Redis模板、连接池、哨兵系统以及JSON序列化,并进一步...
6. 监控与维护:使用 `redis-cli` 的 `cluster info` 和 `cluster nodes` 命令检查集群状态。 三、Spring 集群配置 在 Spring 应用中,可以使用 Spring Data Redis 模块来管理 Redis 集群。以下是一个基本的 `...
项目中的 `redis-jedis` 可能是包含 Jedis 客户端使用示例的目录,`redis-lock` 可能是关于分布式锁实现的代码,而 `redis-boot-sentinel-cluster` 可能是配置和使用 Redis Sentinel 进行高可用集群的示例。...
- **1.7 版本新特性**:包括但不限于对 Redis Sentinel 的支持、新的连接工厂实现(Lettuce)以及对集群模式的支持增强。 - **1.6 版本新特性**:可能涉及更高效的数据序列化机制、扩展的键空间操作等。 - **1.5 ...
首先,你需要在项目的`pom.xml`或`build.gradle`文件中添加Spring和Redis的相关依赖,如Spring Data Redis、Spring Session以及Redis的客户端库(例如Jedis或Lettuce)。 3. **配置Redis连接**: 创建一个`spring...
**Spring Data Redis** 是 **Spring Data** 家族中的一个模块,它为 **Redis** 提供了一套方便的操作接口,使得开发人员可以更加高效地利用 **Redis** 进行数据存储与检索。本章节将对 Spring Data Redis 的主要功能...
本文将详细介绍如何在SpringBoot项目中整合单机版Redis、redis-cluster集群以及redis-sentinel哨兵模式。 首先,让我们从最基础的单机版Redis整合开始。要在SpringBoot中配置单机版Redis,你需要在`pom.xml`文件中...
在Java开发领域,Spring框架与Redis的集成是常见的数据存储和缓存解决方案。Spring提供了对多种数据源的支持,包括关系型数据库、NoSQL数据库以及缓存系统如Redis。本篇文章将详细阐述Spring与Redis集成的相关知识点...
SSM(Spring、SpringMVC、MyBatis)框架与Redis的集成是现代Java Web开发中的常见实践,尤其是在处理高并发、数据缓存等场景下。本教程将详细讲解如何利用SSM搭建一个支持Redis的开发环境,并探讨如何在集群模式下...