Redis 集群与 Spring Boot 的集成

Posted

技术标签:

【中文标题】Redis 集群与 Spring Boot 的集成【英文标题】:Redis cluster integration with Spring boot 【发布时间】:2017-06-14 14:04:24 【问题描述】:

我有一个 redis 集群,其中包含主服务器、从属服务器和 3 个哨兵服务器。 master 和 slave 映射到 dns 名称为 node1-redis-dev.com,node2-redis-dev.com。 redis服务器版本为2.8

我在 application.properties 文件中包含以下内容。

spring.redis.cluster.nodes=node1-redis-dev.com:6379,node2-redis-dev.com:6379
spring.redis.pool.max-idle=8
spring.redis.pool.min-idle=0
spring.redis.pool.max-active=-1
spring.redis.pool.max-wait=-1

但是当我检查 StringRedisTemplate 时,我看到的是 localhost 而不是 JedisConnectionFactory 的 hostName 属性下的集群信息

我还在 JedisPool 的 creationStackTrace 属性中看到了异常。

java.lang.Exception
    at org.apache.commons.pool2.impl.BaseGenericObjectPool.<init>(BaseGenericObjectPool.java:139)
    at org.apache.commons.pool2.impl.GenericObjectPool.<init>(GenericObjectPool.java:107)
    at redis.clients.util.Pool.initPool(Pool.java:43)
    at redis.clients.util.Pool.<init>(Pool.java:31)
    at redis.clients.jedis.JedisPool.<init>(JedisPool.java:80)
    at redis.clients.jedis.JedisPool.<init>(JedisPool.java:74)
    at redis.clients.jedis.JedisPool.<init>(JedisPool.java:55)
    at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.createRedisPool(JedisConnectionFactory.java:228)
    at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.createPool(JedisConnectionFactory.java:204)

CasheRepository 类如下所示,

@Component
@CacheConfig(cacheNames = "enroll", cacheManager = "enrollCM")
public class EnrollCashRepository 
    @Autowired
    private StringRedisTemplate stringRedisTemplate;    
    //Other methods 

我正在使用带有 spring-boot-starter-redis 1.2.7 的 spring boot 1.3.4 导入 jedis 2.7.3 依赖项。

将 redis 集群与 Spring boot 应用程序集成缺少什么?

【问题讨论】:

你是如何配置缓存的? @Arpit 就像在属性文件中配置单个节点时一样,集群也在其中配置。无其他特殊配置 你能显示你的配置文件吗? Redis Sentinel 不是 Redis 集群。 @Arpit 它是我在问题中发布的 application.properties 【参考方案1】:

只需在 RedisClusterConfiguration 中设置集群节点的初始集合并将其提供给 JedisConnectionFactory。

@Configuration
class Config 

    List<String> clusterNodes = Arrays.asList("node1-redis-dev.com:6379", "node2-redis-dev.com:6379");

    @Bean
    RedisConnectionFactory connectionFactory() 
      return new JedisConnectionFactory(new RedisClusterConfiguration(clusterNodes));
    

    @Bean
    RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) 

      // just used StringRedisTemplate for simplicity here.
      return new StringRedisTemplate(factory);
    

【讨论】:

在属性文件中添加集群节点还不够? 如果您使用最新版本的 Spring Boot,仅通过属性文件进行配置将与 @EnableAutoConfiguration 一起使用。 docs.spring.io/spring-data/redis/docs/current/reference/html/… 我使用@SpringBootApplication Spring boot 1.3.4 从 application.properties 配置 redis 集群有问题,要么升级到最新的 spring boot 版本以从属性中使用它,要么使用 java 配置。谢谢。【参考方案2】:

以下应该可以工作

application.properties

spring.redis.cluster.nodes=127.0.0.1:6379
spring.redis.cluster.max-redirects=3

ClusterConfigurationProperties.java

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "spring.redis.cluster")
public class ClusterConfigurationProperties 

/*
 * spring.redis.cluster.nodes[0] = 127.0.0.1:7379 spring.redis.cluster.nodes[1]
 * = 127.0.0.1:7380 ...
 */
private List<String> nodes;
/**
 * spring.redis.cluster.max-redirects=3
 */
private int maxRedirects;

/**
 * Get initial collection of known cluster nodes in format @code host:port.
 *
 * @return
 */
public List<String> getNodes() 
    return nodes;


public void setNodes(List<String> nodes) 
    this.nodes = nodes;


public int getMaxRedirects() 
    return maxRedirects;


public void setMaxRedirects(int maxRedirects) 
    this.maxRedirects = maxRedirects;



RedisConfig.java

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import io.lettuce.core.ReadFrom;

@Configuration
public class RedisConfig 

@Autowired
private ClusterConfigurationProperties clusterProperties;

@Bean
LettuceConnectionFactory redisConnectionFactory(RedisClusterConfiguration redisConfiguration) 

    LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder()
            .readFrom(ReadFrom.REPLICA_PREFERRED).build();

    return new LettuceConnectionFactory(redisConfiguration, clientConfig);


@Bean
RedisClusterConfiguration redisConfiguration() 
    RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration(clusterProperties.getNodes());
    redisClusterConfiguration.setMaxRedirects(clusterProperties.getMaxRedirects());

    return redisClusterConfiguration;


@Bean
@ConditionalOnMissingBean(name = "redisTemplate")
@Primary
RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) 
    RedisTemplate<String, Object> template = new RedisTemplate<>();
    template.setConnectionFactory(connectionFactory);
    template.setKeySerializer(new StringRedisSerializer());
    // other settings...
    return template;


【讨论】:

赞成,它的作品,在redis 2最新的spring boot和jdk 11中测试 你好,可以从RedisProperties获取redis属性,无需添加ClusterConfigurationProperties

以上是关于Redis 集群与 Spring Boot 的集成的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot学习笔记——Spring Boot与Redis的集成

7Spring Boot 与 Redis 集成

Spring Boot 入门:集成Redis哨兵模式,实现Mybatis二级缓存

spring boot集成redis缓存

redis集群 与spring-data-redis 集成

springboot项目集成 redis详解