redis 集群使用

如果使用的是redis2.x,在项目中使用客户端分片(Shard)机制,已经很久之前的版本,该换新了(此处略过),

本文讲解基于redis3.x中的集群,通过两部分来阐述spring boot整合redis,在项目中使用jedisCluster机制。

第一部分:spring boot自带整合的redis,比较简单,看下来

1>不用多说,pom.xml文件增加redis与spring boot的依赖

[html]  view plain  copy
  1.   
  2.         <dependency>  
  3.             <groupId>org.springframework.bootgroupId>  
  4.             <artifactId>spring-boot-starter-redisartifactId>  
  5.             <version>1.4.7.RELEASEversion>  
  6.         dependency>  

2>application.properties增加redis节点配置

[html]  view plain  copy
  1. #redis单服务器配置  
  2. spring.redis.database=0  
  3. spring.redis.host=127.0.0.1  
  4. spring.redis.port=6379  
  5. spring.redis.password=  
  6. spring.redis.pool.max-active=8  
  7. spring.redis.pool.max-wait=-1  
  8. spring.redis.pool.max-idle=8  
  9. spring.redis.pool.min-idle=0  
  10. spring.redis.timeout=0  

3>在需要使用的地方增加RedisTemplate依赖,我只在controller试了下.代码如下:

[html]  view plain  copy
  1. package com.xyy.controller;  
  2.   
  3. import java.util.HashMap;  
  4. import java.util.Map;  
  5.   
  6. import org.slf4j.Logger;  
  7. import org.slf4j.LoggerFactory;  
  8. import org.springframework.beans.factory.annotation.Autowired;  
  9. import org.springframework.data.redis.core.RedisTemplate;  
  10. import org.springframework.data.redis.core.ValueOperations;  
  11. import org.springframework.ui.ModelMap;  
  12. import org.springframework.web.bind.annotation.PathVariable;  
  13. import org.springframework.web.bind.annotation.RequestMapping;  
  14. import org.springframework.web.bind.annotation.RestController;  
  15. import org.springframework.web.servlet.ModelAndView;  
  16.   
  17. import com.danga.MemCached.MemCachedClient;  
  18. import com.xyy.model.Favorite;  
  19. import com.xyy.service.FavoriteService;  
  20.   
  21. /**  
  22.  * Favorite控制层  
  23.  * @ClassName: FavoriteController   
  24.  * @author wujing  
  25.  * @date 2017-07-13 15:09:50  
  26.  */  
  27. @RestController  
  28. @RequestMapping("/favorite")  
  29. public class FavoriteController{  
  30.     private static final Logger LOGGER = LoggerFactory.getLogger(FavoriteController.class);  
  31.       
  32.     @Autowired  
  33.     private FavoriteService favoriteService;  
  34.     @Autowired  
  35.     private MemCachedClient  memCachedClient ;  
  36.     @Autowired  
  37.     private RedisTemplate redisTemplate;  
  38.   
  39.       
  40.     /**  
  41.      * Favorite编辑  
  42.      * @Title: update  
  43.      * @param favorite 修改对象  
  44.      * @return Object  
  45.      * @author wujing   
  46.      * @date 2017-07-13 15:09:50  
  47.      */  
  48.     //@RequestMapping("/detail2/{id}")  
  49.     public Object detail2(@PathVariable Long id,ModelMap modelMap) {  
  50.         Map<String,Object> resultMap = new HashMap<String,Object>();  
  51.         try {  
  52.             Favorite tempFavorite = favoriteService.selectByPrimaryKey(id);  
  53.             resultMap.put("status", "success");  
  54.             resultMap.put("data", tempFavorite);  
  55.         } catch (Exception e) {  
  56.             resultMap.put("status", "error");  
  57.             resultMap.put("errorMsg", "系统异常");  
  58.             LOGGER.error("Favorite添加异常", e);  
  59.         }  
  60.         return resultMap;  
  61.     }  
  62.       
  63.     @RequestMapping("/detail/{id}")  
  64.     public Object detail(@PathVariable Long id,ModelMap modelMap) {  
  65.         try {  
  66.             /*Favorite tempFavorite = (Favorite) memCachedClient.get("favorite:"+id);  
  67.             if(tempFavorite == null) {  
  68.                 tempFavorite = favoriteService.selectByPrimaryKey(id);  
  69.                 memCachedClient.set("favorite:"+id, tempFavorite);  
  70.             }*/  
  71.             ValueOperations<String, Favorite> operations = redisTemplate.opsForValue();  
  72.             Favorite tempFavorite = operations.get("favorite:"+id);  
  73.             if(tempFavorite == null) {  
  74.                 tempFavorite = favoriteService.selectByPrimaryKey(id);  
  75.                 operations.set("favorite:"+id, tempFavorite);  
  76.             }  
  77.             modelMap.put("tempFavorite", tempFavorite);  
  78.               
  79.         } catch (Exception e) {  
  80.             LOGGER.error("Favorite查询异常", e);  
  81.         }  
  82.         return new ModelAndView("favorite/detail");  
  83.     }  
  84. }  

就是这么简单,不得不说spring boot做了很多事,极大的简化了开发的难度 ..让我等屌丝完全沉沦于码农了

随着项目的扩大,数据的增加,项目面临的考验也越来越明显,性能,扩展,容灾..等都是很重要的,这时候分布式或集群就显得尤为重要了

第二部分:spring boot整合集群版的redis

redis 3.X,在项目中使用jedisCluster机制。

1>pom.xml增加jedisCluster依赖

[html]  view plain  copy
  1. dependency>  
  2.                         <groupId>org.springframework.bootgroupId>  
  3.             <artifactId>spring-boot-starter-redisartifactId>  
  4.             <version>1.4.7.RELEASEversion>  
  5.         dependency>  
2>添加redis集群节点配置文件,此处有两种方法

        1:直接在application.properties添加,此处就不详细介绍了

        2:采用javaben的方式配置(此处需要注意spring boot 1.5以后的版本@ConfigurationProperties取消了locations属性),可以通过@PropertySource("classpath:redis.properties")引入配置文件,当然如果写在application.properties下,不需要引用该注解,如下

[html]  view plain  copy
  1. package com.xyy.util.cached.redis;  
  2.   
  3. import org.springframework.boot.context.properties.ConfigurationProperties;  
  4. import org.springframework.context.annotation.PropertySource;  
  5. import org.springframework.stereotype.Component;  
  6.   
  7. /**  
  8.  * redis集群配置文件  
  9.  * @ClassName: RedisProperties   
  10.  * @author wangqinghua  
  11.  * @date 2017年7月24日 下午5:29:19  
  12.  */  
  13. @Component  
  14. @ConfigurationProperties(prefix = "xyy.redis.pool")  
  15. @PropertySource("classpath:redis.properties")  
  16. public class RedisProperties {  
  17.       
  18.     /** redis集群节点 */  
  19.     private String nodes;  
  20.     /** 连接超时时间 */  
  21.     private int timeout;  
  22.     /** 重连次数 */  
  23.     private int maxAttempts;  
  24.     public String getNodes() {  
  25.         return nodes;  
  26.     }  
  27.     public void setNodes(String nodes) {  
  28.         this.nodes = nodes;  
  29.     }  
  30.     public int getTimeout() {  
  31.         return timeout;  
  32.     }  
  33.     public void setTimeout(int timeout) {  
  34.         this.timeout = timeout;  
  35.     }  
  36.     public int getMaxAttempts() {  
  37.         return maxAttempts;  
  38.     }  
  39.     public void setMaxAttempts(int maxAttempts) {  
  40.         this.maxAttempts = maxAttempts;  
  41.     }  
  42.       
  43. }  

redis.properties配置文件如下:

[html]  view plain  copy
  1. #redis集群配置  
  2. xyy.redis.pool.nodes=127.0.0.1:6379,<span style="line-height: 1.5;">span>127.0.0.1:6380,127.0.0.1:6381  
  3. xyy.redis.pool.timeout=3000  
  4. xyy.redis.pool.maxAttempts=5  

3>创建JedisCluster对象

[html]  view plain  copy
  1. package com.xyy.util.cached.redis;  
  2.   
  3. import java.util.HashSet;  
  4. import java.util.Set;  
  5.   
  6. import org.springframework.beans.factory.annotation.Autowired;  
  7. import org.springframework.context.annotation.Bean;  
  8. import org.springframework.context.annotation.Configuration;  
  9.   
  10. import redis.clients.jedis.HostAndPort;  
  11. import redis.clients.jedis.JedisCluster;  
  12.   
  13. /**  
  14.  * 生成JedisCluster对象  
  15.  * @ClassName: JedisClusterConfig   
  16.  * @author wangqinghua  
  17.  * @date 2017年7月24日 下午7:08:03  
  18.  */  
  19. @Configuration  
  20. public class JedisClusterConfig {  
  21.   
  22.     @Autowired  
  23.     private RedisProperties redisProperties;  
  24.   
  25.     /**  
  26.      * 注意:  
  27.      * 这里返回的JedisCluster是单例的,并且可以直接注入到其他类中去使用  
  28.      * @return  
  29.      */  
  30.     @Bean  
  31.     public JedisCluster getJedisCluster() {  
  32.         String[] serverArray = redisProperties.getNodes().split(",");//获取服务器数组(这里要相信自己的输入,所以没有考虑空指针问题)  
  33.         Set<HostAndPort> nodes = new HashSet<>();  
  34.   
  35.         for (String ipPort : serverArray) {  
  36.             String[] ipPortPair = ipPort.split(":");  
  37.             nodes.add(new HostAndPort(ipPortPair[0].trim(), Integer.valueOf(ipPortPair[1].trim())));  
  38.         }  
  39.   
  40.         return new JedisCluster(nodes, redisProperties.getTimeout(),redisProperties.getMaxAttempts());  
  41.     }  
  42.   
  43. }  

4>自定义RedisTemplate

[html]  view plain  copy
  1. package com.xyy.util.cached.redis;  
  2.   
  3. import org.slf4j.Logger;  
  4. import org.slf4j.LoggerFactory;  
  5. import org.springframework.beans.factory.annotation.Autowired;  
  6. import org.springframework.stereotype.Component;  
  7.   
  8. import redis.clients.jedis.JedisCluster;  
  9.   
  10. /**  
  11.  * 自定义redisTemplate  
  12.  * @ClassName: XyyRedisTemplate   
  13.  * @author wangqinghua  
  14.  * @date 2017年7月24日 下午7:09:49  
  15.  */  
  16. @Component  
  17. public class XyyRedisTemplate {  
  18.     private static final Logger LOGGER    = LoggerFactory.getLogger(XyyRedisTemplate.class);  
  19.   
  20.     @Autowired  
  21.     private JedisCluster        jedisCluster;  
  22.   
  23.     @Autowired  
  24.     private RedisProperties     redisProperties;  
  25.   
  26.     private static final String KEY_SPLIT = ":"; //用于隔开缓存前缀与缓存键值   
  27.   
  28.     /**  
  29.      * 设置缓存   
  30.      * @param prefix 缓存前缀(用于区分缓存,防止缓存键值重复)  
  31.      * @param key    缓存key  
  32.      * @param value  缓存value  
  33.      */  
  34.     public void set(String prefix, String key, String value) {  
  35.         jedisCluster.set(prefix + KEY_SPLIT + key, value);  
  36.         LOGGER.debug("RedisUtil:set cache key={},value={}", prefix + KEY_SPLIT + key, value);  
  37.     }  
  38.   
  39.     /**  
  40.      * 设置缓存,并且自己指定过期时间  
  41.      * @param prefix  
  42.      * @param key  
  43.      * @param value  
  44.      * @param expireTime 过期时间  
  45.      */  
  46.     public void setWithExpireTime(String prefix, String key, String value, int expireTime) {  
  47.         jedisCluster.setex(prefix + KEY_SPLIT + key, expireTime, value);  
  48.         LOGGER.debug("RedisUtil:setWithExpireTime cache key={},value={},expireTime={}", prefix + KEY_SPLIT + key, value,  
  49.             expireTime);  
  50.     }  
  51.   
  52.     /**  
  53.      * 设置缓存,并且由配置文件指定过期时间  
  54.      * @param prefix  
  55.      * @param key  
  56.      * @param value  
  57.      */  
  58.     public void setWithExpireTime(String prefix, String key, String value) {  
  59.         int EXPIRE_SECONDS = redisProperties.getTimeout();  
  60.         jedisCluster.setex(prefix + KEY_SPLIT + key, EXPIRE_SECONDS, value);  
  61.         LOGGER.debug("RedisUtil:setWithExpireTime cache key={},value={},expireTime={}", prefix + KEY_SPLIT + key, value,  
  62.             EXPIRE_SECONDS);  
  63.     }  
  64.   
  65.     /**  
  66.      * 获取指定key的缓存  
  67.      * @param prefix  
  68.      * @param key  
  69.      */  
  70.     public String get(String prefix, String key) {  
  71.         String value = jedisCluster.get(prefix + KEY_SPLIT + key);  
  72.         LOGGER.debug("RedisUtil:get cache key={},value={}", prefix + KEY_SPLIT + key, value);  
  73.         return value;  
  74.     }  
  75.   
  76.     /**  
  77.      * 删除指定key的缓存  
  78.      * @param prefix  
  79.      * @param key  
  80.      */  
  81.     public void deleteWithPrefix(String prefix, String key) {  
  82.         jedisCluster.del(prefix + KEY_SPLIT + key);  
  83.         LOGGER.debug("RedisUtil:delete cache key={}", prefix + KEY_SPLIT + key);  
  84.     }  
  85.       
  86.     public void delete(String key) {  
  87.         jedisCluster.del(key);  
  88.         LOGGER.debug("RedisUtil:delete cache key={}", key);  
  89.     }  
  90.   
  91. }  

5>如何使用,和spring boot自带的就很类似了

[html]  view plain  copy
  1. package com.xyy.controller;  
  2.   
  3. import java.util.HashMap;  
  4. import java.util.Map;  
  5.   
  6. import org.slf4j.Logger;  
  7. import org.slf4j.LoggerFactory;  
  8. import org.springframework.beans.factory.annotation.Autowired;  
  9. import org.springframework.data.redis.core.RedisTemplate;  
  10. import org.springframework.ui.ModelMap;  
  11. import org.springframework.util.StringUtils;  
  12. import org.springframework.web.bind.annotation.PathVariable;  
  13. import org.springframework.web.bind.annotation.RequestMapping;  
  14. import org.springframework.web.bind.annotation.RestController;  
  15. import org.springframework.web.servlet.ModelAndView;  
  16.   
  17. import com.danga.MemCached.MemCachedClient;  
  18. import com.xyy.model.Favorite;  
  19. import com.xyy.service.FavoriteService;  
  20. import com.xyy.util.JsonUtil;  
  21. import com.xyy.util.cached.redis.XyyRedisTemplate;  
  22.   
  23. /**  
  24.  * Favorite控制层  
  25.  * @ClassName: FavoriteController   
  26.  * @author wujing  
  27.  * @date 2017-07-13 15:09:50  
  28.  */  
  29. @RestController  
  30. @RequestMapping("/favorite")  
  31. public class FavoriteController{  
  32.     private static final Logger LOGGER = LoggerFactory.getLogger(FavoriteController.class);  
  33.       
  34.     @Autowired  
  35.     private FavoriteService favoriteService;  
  36.     @Autowired  
  37.     private MemCachedClient  memCachedClient ;  
  38.     @Autowired  
  39.     private RedisTemplate redisTemplate;  
  40.     @Autowired  
  41.     private XyyRedisTemplate xyyRedisTemplate;  
  42.       
  43.     /**  
  44.      * Favorite编辑  
  45.      * @Title: update  
  46.      * @param favorite 修改对象  
  47.      * @return Object  
  48.      * @author wujing   
  49.      * @date 2017-07-13 15:09:50  
  50.      */  
  51.     //@RequestMapping("/detail2/{id}")  
  52.     public Object detail2(@PathVariable Long id,ModelMap modelMap) {  
  53.         Map<String,Object> resultMap = new HashMap<String,Object>();  
  54.         try {  
  55.             Favorite tempFavorite = favoriteService.selectByPrimaryKey(id);  
  56.             resultMap.put("status", "success");  
  57.             resultMap.put("data", tempFavorite);  
  58.         } catch (Exception e) {  
  59.             resultMap.put("status", "error");  
  60.             resultMap.put("errorMsg", "系统异常");  
  61.             LOGGER.error("Favorite添加异常", e);  
  62.         }  
  63.         return resultMap;  
  64.     }  
  65.       
  66.     @RequestMapping("/detail/{id}")  
  67.     public Object detail(@PathVariable Long id,ModelMap modelMap) {  
  68.         try {  
  69.             /*Favorite tempFavorite = (Favorite) memCachedClient.get("favorite:"+id);  
  70.             if(tempFavorite == null) {  
  71.                 tempFavorite = favoriteService.selectByPrimaryKey(id);  
  72.                 memCachedClient.set("favorite:"+id, tempFavorite);  
  73.             }*/  
  74.             /*ValueOperations<String, Favorite> operations = redisTemplate.opsForValue();  
  75.             Favorite tempFavorite = operations.get("favorite:"+id);  
  76.             if(tempFavorite == null) {  
  77.                 tempFavorite = favoriteService.selectByPrimaryKey(id);  
  78.                 operations.set("favorite:"+id, tempFavorite);  
  79.             }*/  
  80.             Favorite tempFavorite = null;  
  81.             String value = xyyRedisTemplate.get("favorite",String.valueOf(id));  
  82.             if(StringUtils.isEmpty(value)) {  
  83.                 tempFavorite = favoriteService.selectByPrimaryKey(id);  
  84.                 xyyRedisTemplate.set("favorite",String.valueOf(id), JsonUtil.objToString(tempFavorite));  
  85.             }else {  
  86.                 tempFavorite = JsonUtil.stringToObj(value, Favorite.class);  
  87.             }  
  88.             modelMap.put("tempFavorite", tempFavorite);  
  89.               
  90.         } catch (Exception e) {  
  91.             LOGGER.error("Favorite查询异常", e);  
  92.         }  
  93.         return new ModelAndView("favorite/detail");  
  94.     }  
  95. }  

你可能感兴趣的:(实用案例,问题总结)