redis-cluster做spring-boot的缓存

    网上有很多redis做spring-boot缓存的例子,贴两篇写的比较详细的。

    https://www.jianshu.com/p/5a70b13a4fa7

    https://blog.csdn.net/canot/article/details/52702029

    但关于redis-cluster做spring-boot缓存的例子真是少之又少,所以就写这篇文章记录下过程。如果有还没看过redis做缓存文章的同学请先阅读上两篇文章,再阅读本文。

一.连接Redis-cluster的方式

    有两种,一种是jedis连接,一种是Spring-data-redis,pom中的引用如下。

          
            org.springframework.data
	    spring-data-redis
       	 
       	
            redis.clients
            jedis
        

    jedis连接redis集群非常简单,也可直接操作jedisCluster来增删改查数据库。但有个问题是,要用redisCacheManager做为springboot的cachemanager,需要RedisTemplate参数,目前本人没找到怎么通过JedisCluster获取到redisTemplate,毕竟连包都不一样。

@Configuration
@EnableCaching
@ConfigurationProperties(prefix = "redis.cache")
public class RedisClusterConfig extends CachingConfigurerSupport {
   // getter,setter自动注入
   private List clusterNodes = new ArrayList<>(); // 接收prop2里面的属性值

   public List getClusterNodes() {
      return clusterNodes;
   }

   public void setClusterNodes(List clusterNodes) {
      this.clusterNodes = clusterNodes;
   }


   /*
   *  1.  jedis 连接redis-cluster
   *
    */


   /**
    * 这里返回的JedisCluster是单例,并且可以直接autowired调用
    * @return
    */
   @Bean
   public JedisCluster getJedisCluster() {
      // 创建set集合
      Set nodes = new HashSet();
      // 循环数组把集群节点添加到set集合中
      for (String node : clusterNodes) {
         String[] host = node.split(":");
         // 添加集群节点
         nodes.add(new HostAndPort(host[0], Integer.parseInt(host[1])));
      }
      JedisCluster jc = new JedisCluster(nodes);
      return jc;
   }

        另一种spring-data-redis,连接集群相对较复杂,要按照RedisClusterConfiguration -> JedisConnectionFactory -> RedisTemplate 的顺序来获得redisTemplate,但好处就是可以跟new RedisCacheManage(redisTemplate)联系上了。

        
/*
 *  2.Spring-data-redis  连接redis集群,并进行操作
 *  优势在于可以配置cacheManager,默认的cacheManagerConcurrentMapCacheManager
 *  RedisClusterConfiguration -> JedisConnectionFactory -> RedisTemplate -> CacheManager
 *
 */

@Bean
public RedisClusterConfiguration getRedisCluster() {

   Set jedisClusterNodes = new HashSet();


   clusterNodes.forEach(n ->{
      String[] arr = n.split(":");
      jedisClusterNodes.add(new RedisNode(arr[0], Integer.valueOf(arr[1])));
   });

   RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration();
   redisClusterConfiguration.setClusterNodes(jedisClusterNodes);
   return redisClusterConfiguration;
}


@Bean
public JedisConnectionFactory  getConnFactory(){
   JedisConnectionFactory     factory = new JedisConnectionFactory (getRedisCluster()) ;
   return factory;
}





/**
 * springboot有默认的redisTemplate,一般用RedisTemplate,Object>,也常用StringRedisTemplate
 * redisTemplate.opsForValue().set  操作字符串
 * redisTemplate.opsForHash()   操作hash,以此类推
 * @param factory
 * @return
 */
@Bean
public RedisTemplate redisTemplate(JedisConnectionFactory factory) {

   RedisTemplate template = new RedisTemplate<>();

   RedisSerializer redisSerializer = new StringRedisSerializer();

   Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
   ObjectMapper om = new ObjectMapper();
   om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
   om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
   jackson2JsonRedisSerializer.setObjectMapper(om);

   template.setConnectionFactory(factory);
   //key序列化方式
   template.setKeySerializer(redisSerializer);
   //value序列化
   template.setValueSerializer(jackson2JsonRedisSerializer);
   //value hashmap序列化
   template.setHashValueSerializer(jackson2JsonRedisSerializer);

   return template;
}

@Bean
public CacheManager cacheManager(RedisTemplate redisTemplate){
   RedisCacheManager manager = new RedisCacheManager(redisTemplate);
   manager.setDefaultExpiration(3000);  // 设定失效时间
   return new RedisCacheManager(redisTemplate);
}


/**
 * keyGenerator 自定义@Cacheable key生成策略,必须得配置,否则用redis做缓存时会报错,一般发生于@Cacheable方法参数为空或者为多个时,
 * 默认的key生成策略是SimpleKey[];
 * org.springframework.cache.interceptor.SimpleKey cannot be cast to java.lang.String
 * @return
 */
@Override
@Bean
public KeyGenerator keyGenerator() {
   // lambda表达式
   return (target, method, params) -> {
      StringBuilder sb = new StringBuilder();
      sb.append(target.getClass().getName());
      sb.append("."+method.getName());
      for (Object obj : params) {
         sb.append(obj.toString()+",");
      }
      if(sb.substring(sb.length()-1).toString().equals(","))
         return sb.substring(0,sb.length()-1).toString();
      return sb.toString();
   };
}

二. redis 保存类型

    service中的配置很基本,大致如下

        // 如果方法没有参数,则使用SimpleKey[]作为key
	@Cacheable(value="people")
	public List list(String name){
		return jpa.findAll();
	}

    那么执行了这个方法后,redis里保存的是什么类型的数据呢?我们用redis可视化工具查看,会发现生成了一个名为"people~keys"的zset类型key,里面保存的是字符串,同时又对应了另外的String类型的key

redis-cluster做spring-boot的缓存_第1张图片

    

redis-cluster做spring-boot的缓存_第2张图片

三.结尾

    源码自取,很多地方需要自己手动打断点看看才会有个更全面的认知,大家共勉!

你可能感兴趣的:(redis,spring)