Redis】spring-data-redis与JedisPool的区别、使用ShardedJedisPool与spring集成的实现及一致性哈希分析

一、Redis与spring的整合一般分为spring-data-redis整合和JedisPool整合,先看看两者的区别

1)、引用的依赖不同:

spring-data-redis使用的依赖如下:

  1. <dependency>
  2. <groupId>org.springframework.data </groupId>
  3. <artifactId>spring-data-redis </artifactId>
  4. <version>1.0.2.RELEASE </version>
  5. </dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

JedisPool使用的依赖如下:

  1. <dependency>
  2. <groupId>redis.clients </groupId>
  3. <artifactId>jedis </artifactId>
  4. <version>2.7.2 </version>
  5. <type>jar </type>
  6. <scope>compile </scope>
  7. </dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

2)、管理Jedis实例方式、操作redis服务的不同:

spring-data-redis:

通过org.springframework.data.redis.connection.jedis.JedisConnectionFactory来管理,即通过工厂类管理,然后通过配置的模版bean,操作redis服务,代码段中充斥大量与业务无关的模版片段代码,代码冗余,不易维护,比如像下面的代码:

  1. @Autowired
  2. protected RedisTemplate<Serializable, Serializable> redisTemplate;
  3. public void saveUser ( final User user) {
  4. redisTemplate.execute( new RedisCallback<Object>() {
  5. @Override
  6. public Object doInRedis (RedisConnection connection) throws DataAccessException {
  7. connection.set(redisTemplate.getStringSerializer().serialize( "user.uid." + user.getId()),
  8. redisTemplate.getStringSerializer().serialize(user.getName()));
  9. return null;
  10. }
  11. });
  12. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  1. @Override
  2. public User getUser ( final long id) {
  3. return redisTemplate.execute( new RedisCallback<User>() {
  4. @Override
  5. public User doInRedis (RedisConnection connection) throws DataAccessException {
  6. byte[] key = redisTemplate.getStringSerializer().serialize( "user.uid." + id);
  7. if (connection.exists(key)) {
  8. byte[] value = connection.get(key);
  9. String name = redisTemplate.getStringSerializer().deserialize(value);
  10. User user = new User();
  11. user.setName(name);
  12. user.setId(id);
  13. return user;
  14. }
  15. return null;
  16. }
  17. });
  18. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

JedisPool方式:

通过redis.clients.jedis.JedisPool来管理,即通过池来管理,通过池对象获取jedis实例,然后通过jedis实例直接操作redis服务,剔除了与业务无关的冗余代码,如下面的代码片段:

  1. @Autowired
  2. private JedisPool jedisPool;
  3. @Override
  4. public String save (String key,String val) {
  5. Jedis jedis = jedisPool.getResource();
  6. return jedis.set(key, val);
  7. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

从工厂类到池的方式变化,就相当于mybatis连接MySQL方变化是一样的,代码变得更简洁,维护也更容易了。

spring-data-redis的集成方式可以查看 java之redis篇(spring-data-redis整合) 这边博文。

但是本文与spring集成并未直接采用JedisPool,而是采用了 ShardedJedisPool ,为什么呢?

因为ShardedJedisPool可以通过一致性哈希实现分布式存储

shared一致性哈希采用以下方案:

1、Redis服务器节点划分:将每台服务器节点采用hash算法划分为160个虚拟节点(可以配置划分权重)

2、将划分虚拟节点采用TreeMap存储

3、对每个Redis服务器的物理连接采用LinkedHashMap存储

4、对Key or KeyTag 采用同样的hash算法,然后从TreeMap获取大于等于键hash值得节点,取最邻近节点存储;当key的hash值大于虚拟节点hash值得最大值时,存入第一个虚拟节点sharded采用的hash算法:MD5 和 MurmurHash两种;默认采用64位的MurmurHash算法;

更为深入解释可以查看 Jedis分片连接池(分布式) 、 jedis源码中ShardedJedis实现sharding文章。

使用非分片的JedisPool和使用分片的ShardedJedisPool示例可以查看 Java内存数据库实践之深入浅出Redis - Jedis分布式(Sharding/Sharded) 这篇文章。

二、使用ShardedJedisPool与spring集成

集成参照:https://my.oschina.net/u/866380/blog/521658

相关依赖jar包

  1. <properties>
  2. <project.build.sourceEncoding>UTF-8 </project.build.sourceEncoding>
  3. <spring.version>4.2.6.RELEASE </spring.version>
  4. </properties>
  5. <dependencies>
  6. <!-- spring begin -->
  7. <dependency>
  8. <groupId>org.springframework </groupId>
  9. <artifactId>spring-context </artifactId>
  10. <version>${spring.version} </version>
  11. </dependency>
  12. <dependency>
  13. <groupId>org.springframework </groupId>
  14. <artifactId>spring-context-support </artifactId>
  15. <version>${spring.version} </version>
  16. </dependency>
  17. <dependency>
  18. <groupId>org.springframework </groupId>
  19. <artifactId>spring-test </artifactId>
  20. <version>${spring.version} </version>
  21. </dependency>
  22. <dependency>
  23. <groupId>redis.clients </groupId>
  24. <artifactId>jedis </artifactId>
  25. <version>2.7.2 </version>
  26. <type>jar </type>
  27. </dependency>
  28. <dependency>
  29. <groupId>junit </groupId>
  30. <artifactId>junit </artifactId>
  31. <version>4.11 </version>
  32. <scope>test </scope>
  33. </dependency>
  34. </dependencies>
  • 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
  • 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
  • 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

Spring 配置文件spring-redis.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context = "http://www.springframework.org/schema/context"
  5. xsi:schemaLocation = "
  6. http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
  7. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd" >
  8. <!-- 开启注解驱动 -->
  9. <context:annotation-config> </context:annotation-config>
  10. <!-- 引入属性文件 -->
  11. <context:property-placeholder location="classpath:spring-redis.properties" ignore-unresolvable="true" />
  12. <!-- 配置redis数据库连接池 -->
  13. <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
  14. <property name="maxTotal" value="${redis.pool.maxActive}" />
  15. <property name="maxIdle" value="${redis.pool.maxIdle}" />
  16. <property name="minIdle" value="${redis.pool.minIdle}" />
  17. <property name="maxWaitMillis" value="${redis.pool.maxWait}" />
  18. <property name="lifo" value="${redis.pool.lifo}" />
  19. <property name="testOnBorrow" value="${redis.pool.testOnBorrow}" />
  20. </bean>
  21. <!-- 配置redis共享连接池,业务层主要通过该bean访问redis服务器 -->
  22. <bean id="shardedJedisPool" class="redis.clients.jedis.ShardedJedisPool">
  23. <constructor-arg index="0" ref="jedisPoolConfig" />
  24. <constructor-arg index="1">
  25. <list>
  26. <bean class="redis.clients.jedis.JedisShardInfo">
  27. <constructor-arg index="0" value="${redis.uri.0}" />
  28. </bean>
  29. </list>
  30. </constructor-arg>
  31. </bean>
  32. </beans>
  • 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
  • 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
  • 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

几个注意的点:

(1)如果你有多个数据源需要通过<context:property-placeholder>管理,且不愿意放在一个配置文件里,那么一定要加上ignore-unresolvable=“true”

(2)注意新版的(具体从哪个版本开始不清楚,有兴趣可以查一下)JedisPoolConfig的property name,不是maxActive而是maxTotal,而且没有maxWait属性,建议看一下Jedis源码。

(3)ShardedJedisPool有多种构造函数,选择你需要的(具体看源码),示例中只初始化了一个分片,并使用了通过指定host的构造器(具体格式见下文),如果有集群,在下增加新的即可。

(4)当然,你的spring核心配置文件中得有扫描组件。

(5)客户端分片使用ShardedJedisPool,设置DB和超时时间

redis连接池配置文件spring-redis.properties

  1. #最大分配的对象数
  2. redis .pool .maxActive= 10
  3. #最大能够保持idel状态的对象数
  4. redis .pool .maxIdle= 10
  5. #最小空闲的对象数。2.5.1以上版本有效
  6. redis .pool .minIdle= 8
  7. #当池内没有返回对象时,最大等待时间
  8. redis .pool .maxWait= 1000
  9. #是否启用Lifo。如果不设置,默认为true。2.5.1以上版本有效
  10. redis .pool .lifo= false
  11. #当调用borrow Object方法时,是否进行有效性检查
  12. redis .pool .testOnBorrow= false
  13. ## REDIS URI
  14. ## 使用DB0库
  15. ##redis://用户名:密码@host:port/库,其中用户名随意填写的
  16. redis .uri .0=redis: //testRedis:foobared @119 .254 .166 .136 : 6379 / 0
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

注意:redis uir的格式为 redis://用户名:密码@host:port/库,其中用户名随意填写的,如果没有用户名和密码,格式为redis://:@host:port/库,使用这种方式,配置内容少,还能自定义db index,非常适合开发、测试和线上环境的切换

代码实现

(1)推荐大家使用统一的类来管理Jedis实例的生成和回收,参考代码如下:JedisDataSourceImpl

  1. @Repository( "jedisDS")
  2. public class JedisDataSourceImpl implements JedisDataSource {
  3. private static final Logger LOG = LoggerFactory.getLogger(JedisDataSourceImpl.class);
  4. @Autowired
  5. private ShardedJedisPool shardedJedisPool;
  6. @Override
  7. public ShardedJedis getRedisClient () {
  8. ShardedJedis shardJedis = null;
  9. try {
  10. shardJedis = shardedJedisPool.getResource();
  11. return shardJedis;
  12. } catch (Exception e) {
  13. LOG.error( "[JedisDS] getRedisClent error:" + e.getMessage());
  14. if ( null != shardJedis)
  15. shardJedis.close();
  16. }
  17. return null;
  18. }
  19. @Override
  20. public void returnResource (ShardedJedis shardedJedis) {
  21. shardedJedis.close();
  22. }
  23. @Override
  24. public void returnResource (ShardedJedis shardedJedis, boolean broken) {
  25. shardedJedis.close();
  26. }
  27. }
  • 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
  • 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
  • 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

这里要注意的是Jedis实例的回收,从jedis2.6开始,原returnResource方式已经提示在后续版本中不再支持,所以不建议大家再用ShardedJedisPool里的returnResource和retureBrokenResource方法,虽然在2.7中还支持(毕竟是因为这两个方法存在漏洞)。

(2)编写具体的Jedis操作类(片断):RedisClientTemplate

  1. @Repository( "redisClientTemplate")
  2. public class RedisClientTemplate {
  3. private static final Logger log = LoggerFactory.getLogger(RedisClientTemplate.class);
  4. @Autowired
  5. private JedisDataSource redisDataSource;
  6. public void disconnect () {
  7. ShardedJedis shardedJedis = redisDataSource.getRedisClient();
  8. shardedJedis.disconnect();
  9. }
  10. /**
  11. * 设置单个值
  12. *
  13. * @param key
  14. * @param value
  15. * @return
  16. */
  17. public String set (String key, String value) {
  18. String result = null;
  19. ShardedJedis shardedJedis = redisDataSource.getRedisClient();
  20. if (shardedJedis == null) {
  21. return result;
  22. }
  23. boolean broken = false;
  24. try {
  25. result = shardedJedis.set(key, value);
  26. } catch (Exception e) {
  27. log.error(e.getMessage(), e);
  28. broken = true;
  29. } finally {
  30. redisDataSource.returnResource(shardedJedis, broken);
  31. }
  32. return result;
  33. }
  34. /**
  35. * 获取单个值
  36. *
  37. * @param key
  38. * @return
  39. */
  40. public String get (String key) {
  41. String result = null;
  42. ShardedJedis shardedJedis = redisDataSource.getRedisClient();
  43. if (shardedJedis == null) {
  44. return result;
  45. }
  46. boolean broken = false;
  47. try {
  48. result = shardedJedis.get(key);
  49. } catch (Exception e) {
  50. log.error(e.getMessage(), e);
  51. broken = true;
  52. } finally {
  53. redisDataSource.returnResource(shardedJedis, broken);
  54. }
  55. return result;
  56. }
  57. public Boolean exists (String key) {
  58. Boolean result = false;
  59. ShardedJedis shardedJedis = redisDataSource.getRedisClient();
  60. if (shardedJedis == null) {
  61. return result;
  62. }
  63. boolean broken = false;
  64. try {
  65. result = shardedJedis.exists(key);
  66. } catch (Exception e) {
  67. log.error(e.getMessage(), e);
  68. broken = true;
  69. } finally {
  70. redisDataSource.returnResource(shardedJedis, broken);
  71. }
  72. return result;
  73. }
  74. public String type (String key) {
  75. String result = null;
  76. ShardedJedis shardedJedis = redisDataSource.getRedisClient();
  77. if (shardedJedis == null) {
  78. return result;
  79. }
  80. boolean broken = false;
  81. try {
  82. result = shardedJedis.type(key);
  83. } catch (Exception e) {
  84. log.error(e.getMessage(), e);
  85. broken = true;
  86. } finally {
  87. redisDataSource.returnResource(shardedJedis, broken);
  88. }
  89. return result;
  90. }
  91. /**
  92. * 在某段时间后失效
  93. *
  94. * @param key
  95. * @param seconds
  96. * @return
  97. */
  98. public Long expire (String key, int seconds) {
  99. Long result = null;
  100. ShardedJedis shardedJedis = redisDataSource.getRedisClient();
  101. if (shardedJedis == null) {
  102. return result;
  103. }
  104. boolean broken = false;
  105. try {
  106. result = shardedJedis.expire(key, seconds);
  107. } catch (Exception e) {
  108. log.error(e.getMessage(), e);
  109. broken = true;
  110. } finally {
  111. redisDataSource.returnResource(shardedJedis, broken);
  112. }
  113. return result;
  114. }
  115. /**
  116. * 在某个时间点失效
  117. *
  118. * @param key
  119. * @param unixTime
  120. * @return
  121. */
  122. public Long expireAt (String key, long unixTime) {
  123. Long result = null;
  124. ShardedJedis shardedJedis = redisDataSource.getRedisClient();
  125. if (shardedJedis == null) {
  126. return result;
  127. }
  128. boolean broken = false;
  129. try {
  130. result = shardedJedis.expireAt(key, unixTime);
  131. } catch (Exception e) {
  132. log.error(e.getMessage(), e);
  133. broken = true;
  134. } finally {
  135. redisDataSource.returnResource(shardedJedis, broken);
  136. }
  137. return result;
  138. }
  139. public Long ttl (String key) {
  140. Long result = null;
  141. ShardedJedis shardedJedis = redisDataSource.getRedisClient();
  142. if (shardedJedis == null) {
  143. return result;
  144. }
  145. boolean broken = false;
  146. try {
  147. result = shardedJedis.ttl(key);
  148. } catch (Exception e) {
  149. log.error(e.getMessage(), e);
  150. broken = true;
  151. } finally {
  152. redisDataSource.returnResource(shardedJedis, broken);
  153. }
  154. return result;
  155. }
  156. public boolean setbit (String key, long offset, boolean value) {
  157. ShardedJedis shardedJedis = redisDataSource.getRedisClient();
  158. boolean result = false;
  159. if (shardedJedis == null) {
  160. return result;
  161. }
  162. boolean broken = false;
  163. try {
  164. result = shardedJedis.setbit(key, offset, value);
  165. } catch (Exception e) {
  166. log.error(e.getMessage(), e);
  167. broken = true;
  168. } finally {
  169. redisDataSource.returnResource(shardedJedis, broken);
  170. }
  171. return result;
  172. }
  173. public boolean getbit (String key, long offset) {
  174. ShardedJedis shardedJedis = redisDataSource.getRedisClient();
  175. boolean result = false;
  176. if (shardedJedis == null) {
  177. return result;
  178. }
  179. boolean broken = false;
  180. try {
  181. result = shardedJedis.getbit(key, offset);
  182. } catch (Exception e) {
  183. log.error(e.getMessage(), e);
  184. broken = true;
  185. } finally {
  186. redisDataSource.returnResource(shardedJedis, broken);
  187. }
  188. return result;
  189. }
  190. public long setRange (String key, long offset, String value) {
  191. ShardedJedis shardedJedis = redisDataSource.getRedisClient();
  192. long result = 0;
  193. if (shardedJedis == null) {
  194. return result;
  195. }
  196. boolean broken = false;
  197. try {
  198. result = shardedJedis.setrange(key, offset, value);
  199. } catch (Exception e) {
  200. log.error(e.getMessage(), e);
  201. broken = true;
  202. } finally {
  203. redisDataSource.returnResource(shardedJedis, broken);
  204. }
  205. return result;
  206. }
  207. public String getRange (String key, long startOffset, long endOffset) {
  208. ShardedJedis shardedJedis = redisDataSource.getRedisClient();
  209. String result = null;
  210. if (shardedJedis == null) {
  211. return result;
  212. }
  213. boolean broken = false;
  214. try {
  215. result = shardedJedis.getrange(key, startOffset, endOffset);
  216. } catch (Exception e) {
  217. log.error(e.getMessage(), e);
  218. broken = true;
  219. } finally {
  220. redisDataSource.returnResource(shardedJedis, broken);
  221. }
  222. return result;
  223. }
  224. }
  • 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
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 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
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 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
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247

(3)好了,接下来在你的业务代码里加载RedisClientTemplate.class就可以了。

  1. @RunWith(SpringJUnit4ClassRunner.class)
  2. @ContextConfiguration( "classpath:spring-redis.xml")
  3. public class RedisTest{
  4. @Autowired
  5. private RedisClientTemplate redisClientTemplate ;
  6. @Test
  7. public void testSave (){
  8. String key = "10086";
  9. String val = "中国移动";
  10. String r = redisClientTemplate .save(key,val);
  11. System.out.println(r);
  12. }
  13. @Test
  14. public void testFind (){
  15. String key = "10086";
  16. String result = redisClientTemplate .find(key);
  17. System.out.println(result);
  18. }
  19. @Test public void testDel (){
  20. String key = "10086";
  21. long l = redisClientTemplate .delete(key);
  22. System.out.println(l);
  23. }
  24. }
  • 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
  • 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
  • 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

补充:


1、shardedjedispool分片实现集群与jediscluster实现集群区别以及jediscluster实现集群可以查看 分布式缓存技术redis学习系列(七)——spring整合jediscluster 

2、shardedjedispool分片集群与jediscluster集群同样不具有高可用特性,但基于shardedjedispool的ShardedJedisSentinelPool可以实现集群高可用,redis服务一台master挂机,sentinel哨兵进行主从切换之后,客户端程序自动完成同步的主从切换。 
具体的实现方式就是通过sentinel的sentinelGetMasterAddrByName(masterName);(实际执行sentinel的get-master-addr-by-name命令)获取哨兵监控的所有master节点;然后用一个MasterListener启用一个线程,利用redis的订阅与发布机制,订阅+switch-master频道,时时获取redis服务端主从切换的信息。 
实现原理和源码分析可以查看 基于Redis Sentinel的Redis集群(主从&Sharding)高可用方案 相关源码地址位于 sharded-jedis-sentinel-pool 

猜你喜欢

转载自blog.csdn.net/architect_csdn/article/details/80897601
今日推荐