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的更多相关文章

  1. 使用Spring Data Redis操作Redis(集群版)

    说明:请注意Spring Data Redis的版本以及Spring的版本!最新版本的Spring Data Redis已经去除Jedis的依赖包,需要自行引入,这个是个坑点.并且会与一些低版本的Sp ...

  2. spring data jpa 操作pipelinedb 的continuous view 与stream

    一. 由于pipelinedb是postgreSQL的扩展,因此相关依赖于配置都合集成postgreSQL是一样的. springboot + spring data jpa + postgreSQL ...

  3. Spring Boot使用Spring Data Redis操作Redis(单机/集群)

    说明:Spring Boot简化了Spring Data Redis的引入,只要引入spring-boot-starter-data-redis之后会自动下载相应的Spring Data Redis和 ...

  4. 使用Spring Data Redis操作Redis(单机版)

    说明:请注意Spring Data Redis的版本以及Spring的版本!最新版本的Spring Data Redis已经去除Jedis的依赖包,需要自行引入,这个是个坑点.并且会与一些低版本的Sp ...

  5. Spring 使用RedisTemplate操作Redis

    首先添加依赖: <!-- https://mvnrepository.com/artifact/redis.clients/jedis --> <dependency> < ...

  6. Spring Data Solr操作solr的简单案例

    Spring Data Solr简介 虽然支持任何编程语言的能力具有很大的市场价值,你可能感兴趣的问题是:我如何将Solr的应用集成到Spring中?可以,Spring Data Solr就是为了方便 ...

  7. 通过Spring Data Neo4J操作您的图形数据库

    在前面的一篇文章<图形数据库Neo4J简介>中,我们已经对其内部所使用的各种机制进行了简单地介绍.而在我们尝试对Neo4J进行大版本升级时,我发现网络上并没有任何成型的样例代码以及简介,而 ...

  8. Spring Boot (五)Spring Data JPA 操作 MySQL 8

    一.Spring Data JPA 介绍 JPA(Java Persistence API)Java持久化API,是 Java 持久化的标准规范,Hibernate是持久化规范的技术实现,而Sprin ...

  9. [Reprinted] 使用Spring Data Redis操作Redis(一) 很全面

    Original Address: http://blog.csdn.net/albertfly/article/details/51494080

  10. 使用WeihanLi.Redis操作Redis

    WeihanLi.Redis Intro StackExchange.Redis 扩展,更简单的泛型操作,并提供一些的适用于业务场景中的扩展 基于 Redis 的五种数据类型扩展出了一些应用: Str ...

随机推荐

  1. cogs_396_魔术球问题_(最小路径覆盖+二分图匹配,网络流24题#4)

    描述 http://cojs.tk/cogs/problem/problem.php?pid=396 连续从1开始编号的球,按照顺寻一个个放在n个柱子上,\(i\)放在\(j\)上面的必要条件是\(i ...

  2. BZOJ_1618_ [Usaco2008_Nov]_Buying_Hay_购买干草(动态规划,完全背包)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1618 有n种物品,每种物品有价值和重量,可以无限拿.现在要满足价值之和大于等于h,问最小重量. ...

  3. [swustoj 191] 迷宫逃离

    迷宫逃离(0191) 描述 江鸟突然想到了一个迷宫逃离的游戏,话说有三个人被困于一个n*m的迷宫里,他们三人都可以向上.向下.向左.向右四个方向进行走动,当然他们所在的初始位置没有障碍物,同时只能走到 ...

  4. Mac 上Dock中添加“最近打开过的项目”(Recent Applications)

    有一个特别有用的Stack,“最近打开过的项目”,建立方法如下: 1. 打开Terminal,输入以下命令 defaults write com.apple.dock persistent-other ...

  5. iphone4s丢失如何找回

    iphone4s丢失如何找回 iphone4s手机丢了怎么办,其实苹果手机自带找回功能,但是前提你得打开了icloud这款软件. 方法/步骤 1 在手机的设置里找到icloud设置,如图. 2 点击进 ...

  6. POJ1680 Currency Exchange SPFA判正环

    转载来源:優YoU  http://user.qzone.qq.com/289065406/blog/1299337940 提示:关键在于反向利用Bellman-Ford算法 题目大意 有多种汇币,汇 ...

  7. mac os develop

    . 安装PCRE Download latest PCRE. After download go to download directory from terminal. $ cd ~/Downloa ...

  8. nyoj 96 一个水题目

    虽然很简单,发现自己用内存太高了了,算了,我就是这水平了. 描述 已知w是一个大于10但不大于1000000的无符号整数,若w是n(n≥2)位的整数,则求出w的后n-1位的数. 输入 第一行为M,表示 ...

  9. vijosP1137 组合数

    vijosP1137 组合数 链接:https://vijos.org/p/1137 [思路] 唯一分解定理. 简化式子为 : C = (n*…*m) / (n-m)!. 题目要求C质因子的数目,在质 ...

  10. 枚举在c与c++中定义的不同

    众所周知的,枚举是在运行期才决定枚举变量的值的,而不是像宏一样在预编译的时候就进行值得替换. 而且c标准规定: size(int) <= size(enum)<=系统所能表示的最大范围的值 ...