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版本的集群特性。

请参考:https://www.jb51.net/article/128895.htm

使用时,直接通过注解或者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来规避此问题。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Redis Cluster添加、删除的完整操作步骤

    前言 最近学习了Redis,发现Redis还是挺好玩的,今天测试了集群的添加.删除节点.重分配slot等.更深入的理解redis的游戏规则.步骤繁多,但是详细,话不多说了,来一起看看详细的介绍吧. 环境解释: 我是在一台Centos 6.9上测试的,各个redis节点以端口号区分.文中针对各个redis,我只是以端口号代表. ~~~~Master Node~~~~~ 172.16.32.116:7000 172.16.32.116:7001 172.16.32.116:7002 ~~~~Slav

  • 使用Ruby脚本部署Redis Cluster集群步骤讲解

    安装Ruby和Gem 下载ruby wget https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.8.tar.gz 解压 tar xvf ruby-2.3.8.tar.gz 生成Makefile并且后面会被安装到/usr/local/ruby目录下 ./configure -prefix /usr/local/ruby 编译 make 安装 make install cd /usr/local/ruby cp bin/ruby /usr/local

  • Windows环境下Redis Cluster环境搭建(图文)

    搭建 Redis集群,三个主节点,三个从节点,多主节点为了分布集群,从节点是为了高可用性. 1. 下载redis 地址:https://github.com/MicrosoftArchive/redis/releases 此次案例中使用的版本为3.0.503 Source code可以一起下载,下文会用到. 2. 安装redis 解压Redis-x64-3.0.503.zip,并复制,如下图 3. 修改每台redis.windows.conf,修改里面的端口号,以及集群的配置 port 6380

  • spring集成redis cluster详解

    客户端采用最新的jedis 2.7 1.maven依赖: <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.7.3</version> </dependency> 2.增加spring 配置 <bean name="genericObjectPoolConfig"

  • php成功操作redis cluster集群的实例教程

    前言 java操作redis cluster集群可使用jredis php要操作redis cluster集群有两种方式: 1.使用phpredis扩展,这是个c扩展,性能更高,但是phpredis2.x扩展不行,需升级phpredis到3.0,但这个方案参考资料很少 2.使用predis,纯php开发,使用了命名空间,需要php5.3+,灵活性高 我用的是predis,下载地址:点击这里 步骤如下: 下载好后重命名为predis, server1:192.168.1.198 server2:1

  • Redis Cluster的图文讲解

    1.1 Redis-Cluster简介 1.1.1 什么是Redis-Cluster 为何要搭建Redis集群.Redis是在内存中保存数据的,而我们的电脑一般内存都不大,这也就意味着Redis不适合存储大数据,适合存储大数据的是Hadoop生态系统的Hbase或者是MogoDB.Redis更适合处理高并发,一台设备的存储能力是很有限的,但是多台设备协同合作,就可以让内存增大很多倍,这就需要用到集群. Redis集群搭建的方式有多种,例如使用客户端分片.Twemproxy.Codis等,但从re

  • 如何用docker部署redis cluster的方法

    前言 由于本人是个docker控,不喜欢安装各种环境,而且安装redis-trib也有点繁琐,索性用docker来做redis cluster. 本文用的是伪集群,真正的集群放到不同的机器即可.端口是7001-7006. 工作目录: /data/redis 创建文件夹 首先创建一堆对应端口的文件夹,下面是脚本 create.sh for i in `seq 7001 7006` do mkdir -p ${i}/data done 添加执行权限并执行 chmod 777 create.sh ./

  • Redis cluster集群的介绍

    1.前言 Redis集群模式主要有2种: 主从集群.分布式集群. 前者主要是为了高可用或是读写分离,后者为了更好的存储数据,负载均衡. redis集群提供了以下两个好处 1.将数据自动切分(split)到多个节点 2.当集群中的某一个节点故障时,redis还可以继续处理客户端的请求. 一个 redis 集群包含 16384 个哈希槽(hash slot),数据库中的每个数据都属于这16384个哈希槽中的一个.集群使用公式 CRC16(key) % 16384 来计算键 key 属于哪个槽.集群中

  • 基于Spring Data的AuditorAware审计功能的示例代码

    Spring Data提供支持审计功能:即由谁在什么时候创建或修改实体.Spring Data提供了在实体类的属性上增加@CreatedBy,@LastModifiedBy,@CreatedDate,@LastModifiedDate注解,并配置相应的配置项,即可实现审计功能,有系统自动记录 createdBy CreatedDate lastModifiedBy lastModifiedDate 四个属性的值,下面为具体的配置项. 示例 创建一个实体类 package com.hfcsbc.i

  • SpringBoot+Spring Data JPA整合H2数据库的示例代码

    目录 前言 Maven依赖 Conroller 实体类 Repository 数据库脚本文件 配置文件 启动项目 访问H2数据库 查看全部数据 H2数据库文件 运行方式 前言 H2数据库是一个开源的关系型数据库.H2采用java语言编写,不受平台的限制,同时支持网络版和嵌入式版本,有比较好的兼容性,支持相当标准的sql标准 提供JDBC.ODBC访问接口,提供了非常友好的基于web的数据库管理界面 官网:http://www.h2database.com/ Maven依赖 <!--jpa-->

  • 使用Spring Data JDBC实现DDD聚合的示例代码

    本文讨论了Spring Data JDBC如何实现DDD中聚合根存储的设计思路,其中主要讨论了是不是每个实体都需要一个对应数据表,这种问题需要根据具体情况而定. Spring Data JDBC比JPA更容易理解,比如对象引用特性会很有趣.作为第一个示例,请考虑以下领域模型: class PurchaseOrder { private @Id Long id; private String shippingAddress; private Set<OrderItem> items = new

  • spring使用RedisTemplate操作Redis数据库

    一.什么是Redis Redis是一个非关系型数据库,具有很高的存取性能,一般用作缓存数据库,减少正常存储数据库的压力. Redis可以存储键与5种不同数据结构类型之间的映射,这5种数据结构类型分别为String(字符串).List(列表).Set(集合).Hash(散列)和 Zset(有序集合). 下面来对这5种数据结构类型作简单的介绍: 二.RedisTemplate及其相关方法 1.RedisTemplate Spring封装了RedisTemplate对象来进行对Redis的各种操作,它

  • SpringBoot整合Redis实现访问量统计的示例代码

    目录 前言 Spring Boot 整合 Redis 引入依赖.增加配置 翠花!上代码 前言 之前开发系统的时候客户提到了一个需求:需要统计某些页面的访问量,记得当时还纠结了一阵子,不知道怎么去实现这个功能,后来还是在大佬的带领下借助 Redis 实现了这个功能.今天又回想起了这件事,正好和大家分享一下 Spring Boot 整合 Redis 实现访问量统计的全过程. 首先先解释一下为什么需要借助 Redis,其实原因也很简单,就是因为它非常快(每秒可执行大约110000次的 SET 操作,每

  • SpringBoot结合Redis实现接口幂等性的示例代码

    目录 介绍 实现过程 引入 maven 依赖 spring 配置文件写入 引入 Redis 自定义注解 token 的创建和实现 拦截器的配置 测试用例 介绍 幂等性的概念是,任意多次执行所产生的影响都与一次执行产生的影响相同,按照这个含义,最终的解释是对数据库的影响只能是一次性的,不能重复处理.手段如下 数据库建立唯一索引 token机制 悲观锁或者是乐观锁 先查询后判断 小小主要带你们介绍Redis实现自动幂等性.其原理如下图所示. 实现过程 引入 maven 依赖 <dependency>

  • Java利用Redis实现消息队列的示例代码

    本文介绍了Java利用Redis实现消息队列的示例代码,分享给大家,具体如下: 应用场景 为什么要用redis? 二进制存储.java序列化传输.IO连接数高.连接频繁 一.序列化 这里编写了一个java序列化的工具,主要是将对象转化为byte数组,和根据byte数组反序列化成java对象; 主要是用到了ByteArrayOutputStream和ByteArrayInputStream; 注意:每个需要序列化的对象都要实现Serializable接口; 其代码如下: package Utils

  • Docker 部署 SpringBoot 项目整合 Redis 镜像做访问计数示例代码

    最终效果如下 大概就几个步骤 1.安装 Docker CE 2.运行 Redis 镜像 3.Java 环境准备 4.项目准备 5.编写 Dockerfile 6.发布项目 7.测试服务 环境准备 系统:Ubuntu 17.04 x64 Docker 17.12.0-ce IP:45.32.31.101 一.安装 Docker CE 国内不建议使用:"脚本进行安装",会下载安装很慢,使用步骤 1 安装,看下面的链接:常规安装方式 1.常规安装方式 Ubuntu 17.04 x64 安装

  • MyBatis整合Redis实现二级缓存的示例代码

    MyBatis框架提供了二级缓存接口,我们只需要实现它再开启配置就可以使用了. 特别注意,我们要解决缓存穿透.缓存穿透和缓存雪崩的问题,同时也要保证缓存性能. 具体实现说明,直接看代码注释吧! 1.开启配置 SpringBoot配置 mybatis: configuration: cache-enabled: true 2.Redis配置以及服务接口 RedisConfig.java package com.leven.mybatis.api.config; import com.fasterx

  • SpringBoot集成redis实现分布式锁的示例代码

    1.准备 使用redis实现分布式锁,需要用的setnx(),所以需要集成Jedis 需要引入jar,jar最好和redis的jar版本对应上,不然会出现版本冲突,使用的时候会报异常redis.clients.jedis.Jedis.set(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)Ljava/lang/String; 我使用的redis版本是2.3.0,Jedis使用的是3.3.0 <de

随机推荐