好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

Spring-data-redis操作redis cluster的示例代码

redis 3.x版本引入了集群的新特性,为了保证所开发系统的高可用性项目组决定引用redis的集群特性。对于redis数据访问的支持,目前主要有二种方式:一、以直接调用jedis来实现;二、使用spring- data -redis,通过spring的封装来调用。下面分别对这二种方式如何操作redis进行说明。

一、利用jedis来实现

通过jedis操作redis cluster 的模型可以参考redis官网,具体如下:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

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

代码目录结构如下所示:

?

1

2

3

4

5

src

   com.example.bean

   com.example.repo

   com.example.repo.impl

   resources

a.在resources目录下增加spring-config.xml配置,配置如下:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

<!--通过构造方法注入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 -->

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

     <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文件

?

1

2

3

4

5

6

7

<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的操作。

?

1

2

3

classpathxmlapplicationcontext context = new classpathxmlapplicationcontext( new classpathresource( "resources/spring-config.xml" ).getpath());

 

repo repo =(repo)context.getbean( "personrepo" );

(2)采用redisclusterconfiguration(propertysource<?> propertysource)方式构造redisclusterconfiguration

  代码目录结构如下所示:

?

1

2

3

4

5

6

src

   com.redis.cluster.support.config

        monitorconfig

   resources

       spring-config.xml

        redis.properties

a.在resources目录下增加spring-config.xml配置,配置如下:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

<!--配置文件加载-->

 

  <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文件

?

1

2

3

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类

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

@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

?

1

2

3

4

5

6

7

@autowired

 

  jedisclusterconnection clusterconnection;

 

@autowired

 

redistemplate redistemplate;

三、简单集成spring

自己编写jediscluster的工厂类jedisclusterfactory,然后通过spring注入的方式获取jediscluster,实现客户端使用redis3.0版本的集群特性。

请参考: http://www.tuohang.net/article/140100.html

使用时,直接通过注解或者xml注入即可,如下所示:

?

1

2

@autowired

jediscluster jediscluster;

  或者

?

1

2

3

4

5

<bean id= "testredis" class = "com.test.testredis" >

 

   <property name= "jediscluster" ref= "jedisclusterfactory" />

 

</bean>

?

1

2

3

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.

?

1

2

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来规避此问题。

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

原文链接:https://www.cnblogs.com/moonandstar08/p/5149585.html

查看更多关于Spring-data-redis操作redis cluster的示例代码的详细内容...

  阅读:17次