Spring-data-redis操作redis cluster
Redis 3.X版本引入了集群的新特性,为了保证所开发系统的高可用性项目组决定引用Redis的集群特性。对于Redis数据访问的支持,目前主要有二种方式:一、以直接调用jedis来实现;二、使用spring-data-redis,通过spring的封装来调用。下面分别对这二种方式如何操作Redis进行说明。
一、利用Jedis来实现
通过Jedis操作Redis Cluster的模型可以参考Redis官网,具体如下:
Set<HostAndPort> jedisClusterNodes = new HashSet<HostAndPort>();
//Jedis Cluster will attempt to discover cluster nodes automatically
jedisClusterNodes.add(new HostAndPort("10.96.5.183",9001));
jedisClusterNodes.add(new HostAndPort("10.96.5.183",9002));
jedisClusterNodes.add(new HostAndPort("10.96.5.183",9003));
JedisCluster jc = new JedisCluster(jedisClusterNodes);
jc.set("foo","bar");
jc.get("foo";
二、利用spring-data-redis来实现
目前spring-data-redis已发布的主干版本都不能很好的支持Redis Cluster的新特性。为了解决此问题spring-data-redis开源项目组单独拉了一个315分支,但截止到目前尚未发布。下面在分析spring-data-redis源码的基础上配置spring实现操作Redis Cluster.下面分别针对XML和注入的方式进行说明。
315分支gitHub下载路径如下:https://github.com/spring-projects/spring-data-redis
315分支源码下载路径:http://maven.springframework.org/snapshot/org/springframework/data/spring-data-redis/1.7.0.DATAREDIS-315-SNAPSHOT/
(1)采用setClusterNodes属性方式构造RedisClusterConfiguration
代码目录结构如下所示:
src
com.example.bean
com.example.repo
com.example.repo.impl
resources
A.在resources目录下增加spring-config.xml配置,配置如下:
<!--通过构造方法注入RedisNode-->
<bean id="clusterRedisNodes1" class="org.springframework.data.redis.connection.RedisNode">
<constructor-arg value="10.96.5.183" />
<constructor-arg value="9002" type="int" />
</bean>
....
<!--setter方式注入-->
<bean id="redisClusterConfiguration" class="org.springframework.data.redis.connection.RedisClusterConfiguration">
<property name="clusterNodes">
<set>
<ref bean="clusterRedisNodes1"/>
<ref bean="clusterRedisNodes2"/>
<ref bean="clusterRedisNodes3"/>
</set>
</property>
<!--红色所示部分在从gitHub上获取的jar包中无对应setter方法,因此需要修改其对应的源码。
另外,如果不设置clusterTimeOut值,源码中默认为2S。当集群服务器与客户端不在同一服务器上时,容易报:Could not get a resource from the Cluster;
如果不设置maxRedirects值,源码中默认为5。一般当此值设置过大时,容易报:Too many Cluster redirections -->
<property name="clusterTimeOut" value="10000" />
<property name="maxRedirects" value="5" />
</bean>
<!--setter方式注入,对应的属性需存在setterXXX方法-->
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxToal" value="1000" />
<property name="maxIdle" value="1000" />
<property name="maxWaitMillis" value="1000" />
</bean>
<bean id="jedisConnFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" p:use-pool="true">
<constructor-arg ref="redisClusterConfiguration" />
<constructor-arg ref="jedisPoolConfig" />
</bean>
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" p:connection-factory-ref="jedisConnFactory" />
<!--setter方式注入PersonRepoImpl-->
<bean id="personRepo" class="com.example.repo.impl.PersonRepoImpl">
<property name="redisTemplate" ref="redisTemplate" />
</bean>
注:加载lua文件
<bean id ="XXX" class="org.springframework.data.redis.core.script.DefaultRedisScript">
<property name="location" value="./redis/XXX.lua" />
<property name="resultType" value="java.lang.Void" />
</bean>
在com.example.repo.impl下增加PersonRepoImpl,主要包括属性private RedisTemplate<String,Bean> redisTemplate(该属性存在setterXXX方法,对应property属性);
利用redisTemplate.opsForHash().put()即可完成对Redis Cluster的操作。
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new ClassPathResource("resources/spring-config.xml").getPath());
Repo repo =(Repo)context.getBean("personRepo");
(2)采用RedisClusterConfiguration(PropertySource<?> propertySource)方式构造RedisClusterConfiguration
代码目录结构如下所示:
src
com.redis.cluster.support.config
MonitorConfig
resources
spring-config.xml
redis.properties
A.在resources目录下增加spring-config.xml配置,配置如下:
<!--配置文件加载-->
<context:property-placeholder location="resources/redis.properties"/>
<context:property-placeholder location="resources/xxx.properties"/>
<bean class="com.redis.cluster.support.config.MonitorConfig" />
<!--对静态资源文件的访问-->
<mvc:default-servlet-handler/>
<mvc:annotation-driven />
<context:component-scan base-package="com.redis.cluster"/>
B.添加redis.properties文件
spring.redis.cluster.nodes=10.48.193.201:7389,10.48.193.201:7388
spring.redis.cluster.timeout=2000
spring.redis.cluster.max-redirects=8
C.编写初始化JedisConnectionFactory连接工厂的java类
@Configuration
public class MonitorConfig {
@Value("${spring.redis.cluster.nodes}")
private String clusterNodes;
@Value("${spring.redis.cluster.timeout}")
private Long timeout;
@Value("${spring.redis.cluster.max-redirects}")
private int redirects;
@Bean
public RedisClusterConfiguration getClusterConfiguration() {
Map<String, Object> source = new HashMap<String, Object>();
source.put("spring.redis.cluster.nodes", clusterNodes);
source.put("spring.redis.cluster.timeout", timeout);
source.put("spring.redis.cluster.max-redirects", redirects);
return new RedisClusterConfiguration(new MapPropertySource("RedisClusterConfiguration", source));
}
@Bean
public JedisConnectionFactory getConnectionFactory() {
return new JedisConnectionFactory(getClusterConfiguration());
}
@Bean
public JedisClusterConnection getJedisClusterConnection() {
return (JedisClusterConnection) getConnectionFactory().getConnection();
}
@Bean
public RedisTemplate getRedisTemplate() {
RedisTemplate clusterTemplate = new RedisTemplate();
clusterTemplate.setConnectionFactory(getConnectionFactory());
clusterTemplate.setKeySerializer(new DefaultKeySerializer());
clusterTemplate.setDefaultSerializer(new GenericJackson2JsonRedisSerializer());
return clusterTemplate;
}
}
D.通过注解方式使用JedisClusterConnection和RedisTemplate
@Autowired
JedisClusterConnection clusterConnection;
@Autowired
RedisTemplate redisTemplate;
三、简单集成Spring
自己编写jedisCluster的工厂类JedisClusterFactory,然后通过Spring注入的方式获取jedisCluster,实现客户端使用Redis3.0版本的集群特性。
请参考:http://my.oschina.net/FACEqiu/blog/512773?fromerr=I2SnVz8P
http://www.cnblogs.com/niceplay/p/4992614.html
使用时,直接通过注解或者XML注入即可,如下所示:
@Autowired
JedisCluster jedisCluster;
或者
<bean id="testRedis" class="com.test.TestRedis">
<property name="jedisCluster" ref="jedisClusterFactory" />
</bean>
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new ClassPathResource("resources/spring-config.xml").getPath());
TestRedis testRedis=(TestRedis)context.getBean("testRedis");
四、Redis Cluster调试中常见错误
(1)当客户端与集群服务器不在同一台服务器上时,有如下错误Could not get a resource from the Cluster
一般当客户端与集群服务器在同一台服务器上时,操作Redis Cluster正常; 当二者不在同一台服务器上时报如上错误,可能是clusterTimeOut时间设置过小;
(2)操作Redis时报Too many cluster redirections
初始化JedisCluster时,设定JedisCluster的maxRedirections.
JedisCluster(Set<HostAndPort> jedisClusterNode, int timeout, int maxRedirections) ;
JedisCluster jc = new JedisCluster(jedisClusterNodes,5000,1000);
请参考:https://gitHub.com/xetorthio/jedis/issues/659
(3)Redis Cluster数据写入慢
检查在通过./redis-trib命令建立集群时,如果是通过127.0.0.1的方式建立的集群,那么在往Redis Cluster中写入数据时写入速度比较慢。可以通过配置真实的IP来规避此问题。
Spring-data-redis操作redis cluster的更多相关文章
- 使用Spring Data Redis操作Redis(集群版)
说明:请注意Spring Data Redis的版本以及Spring的版本!最新版本的Spring Data Redis已经去除Jedis的依赖包,需要自行引入,这个是个坑点.并且会与一些低版本的Sp ...
- spring data jpa 操作pipelinedb 的continuous view 与stream
一. 由于pipelinedb是postgreSQL的扩展,因此相关依赖于配置都合集成postgreSQL是一样的. springboot + spring data jpa + postgreSQL ...
- Spring Boot使用Spring Data Redis操作Redis(单机/集群)
说明:Spring Boot简化了Spring Data Redis的引入,只要引入spring-boot-starter-data-redis之后会自动下载相应的Spring Data Redis和 ...
- 使用Spring Data Redis操作Redis(单机版)
说明:请注意Spring Data Redis的版本以及Spring的版本!最新版本的Spring Data Redis已经去除Jedis的依赖包,需要自行引入,这个是个坑点.并且会与一些低版本的Sp ...
- Spring 使用RedisTemplate操作Redis
首先添加依赖: <!-- https://mvnrepository.com/artifact/redis.clients/jedis --> <dependency> < ...
- Spring Data Solr操作solr的简单案例
Spring Data Solr简介 虽然支持任何编程语言的能力具有很大的市场价值,你可能感兴趣的问题是:我如何将Solr的应用集成到Spring中?可以,Spring Data Solr就是为了方便 ...
- 通过Spring Data Neo4J操作您的图形数据库
在前面的一篇文章<图形数据库Neo4J简介>中,我们已经对其内部所使用的各种机制进行了简单地介绍.而在我们尝试对Neo4J进行大版本升级时,我发现网络上并没有任何成型的样例代码以及简介,而 ...
- Spring Boot (五)Spring Data JPA 操作 MySQL 8
一.Spring Data JPA 介绍 JPA(Java Persistence API)Java持久化API,是 Java 持久化的标准规范,Hibernate是持久化规范的技术实现,而Sprin ...
- [Reprinted] 使用Spring Data Redis操作Redis(一) 很全面
Original Address: http://blog.csdn.net/albertfly/article/details/51494080
- 使用WeihanLi.Redis操作Redis
WeihanLi.Redis Intro StackExchange.Redis 扩展,更简单的泛型操作,并提供一些的适用于业务场景中的扩展 基于 Redis 的五种数据类型扩展出了一些应用: Str ...
随机推荐
- [转] 弱校ACM奋斗史
转载来自:http://blog.163.com/lx_zz0o0/blog/static/236205116201442604234538/ 弱校ACM奋斗史 2014-05-26 00:42:3 ...
- C#初始化数组的三种方式
C#声明数组并初始化,有三种方式. 对于一维数组: using System;using System.Data;using System.Configuration;using System.Web ...
- 知识面 z
http://blog.csdn.net/sxhelijian/article/details/23163683 有了较宽和知识面,面对复试中不知道的问题,回答可以是:“这个问题,直接回答我没有把握, ...
- How Many Tables
How Many Tables Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other) Tot ...
- bzoj 2754 [SCOI2012]喵星球上的点名(后缀数组)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2754 [题意] 每只喵有名姓,如果被老师点到名或姓的子串都要答道,但每只喵一次点名只答 ...
- Weka 入门2
现在我们介绍使用Weka来对数据进行分类.对数据进行分类,我们必须先指定那一列作为预测类别.因为数据文件格式的问题,类别一般都是最后一列属性.我们可以使用setClassIndex来设置类别.然后我们 ...
- SQLite 在Windows Server 2008 R2 部署问题FAQ汇总[轉]
轉自:http://www.steveluo.name/sqlite-windows-server-2008-r2-deploy-faq/ 今天花了一天的时间研究了一下SQLite,以取代一些轻量级项 ...
- PC-信使服务之不用聊天软件也能通信
net send 192.168.1.2 OK 二台电脑都要开启messenger服务.
- A Tour of Go Basic types
Go's basic types are bool string int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 uintptr ...
- S2SH商用后台权限系统第三讲
个位博友: 您好!今天我们做下登录页面,已经如何登录系统.我们的登录页面很简单,用户名.密码.验证码.下面首先描述下验证码的概念,验证码是为了防止机器人恶意登录.我们这里的验证码采用4位数字,当然你也 ...