Databases 12 min read

Integrating Redis Cluster with SpringBoot: Configuration, Dependencies, and Utility Classes

This tutorial explains how to upgrade a SpringBoot application from a single‑node Redis setup to a Redis cluster by adjusting configuration parameters, adding the correct Maven dependencies, injecting a RedisTemplate with JedisConnectionFactory, and providing a reusable utility class for common Redis operations.

Full-Stack Internet Architecture
Full-Stack Internet Architecture
Full-Stack Internet Architecture
Integrating Redis Cluster with SpringBoot: Configuration, Dependencies, and Utility Classes

The author introduces Redis as a widely used cache and data store, noting that many projects start with a single‑node instance but may need to migrate to a Redis cluster as traffic grows.

To perform the migration, four main adjustments are required: modify configuration parameters for cluster nodes and passwords, ensure the Jedis version (and spring‑data‑redis) supports password authentication, inject a RedisTemplate, and create a utility class for common Redis operations.

Configuration Parameters

The following properties should be added to the SpringBoot configuration file (e.g., application.properties) to describe the cluster topology and connection settings:

############### Redis 集群配置 #########################
spring.custome.redis.cluster.nodes=172.20.0.1:7001,172.20.0.2:7002,172.20.0.3:7003
spring.custome.redis.cluster.max-redirects=3
spring.custome.redis.cluster.max-active=500
spring.custome.redis.cluster.max-wait=-1
spring.custome.redis.cluster.max-idle=500
spring.custome.redis.cluster.min-idle=20
spring.custome.redis.cluster.timeout=3000
spring.custome.redis.cluster.password=redis.cluster.password

Adding Maven Dependencies

If the project uses SpringBoot version 1.4.x or earlier, the default Jedis client does not support password authentication. The solution is to exclude the old Jedis and spring‑data‑redis artifacts and add newer versions manually:

<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
        <!-- 1.4 version SpringBoot Jedis does not support password login -->
        <exclusions>
            <exclusion>
                <groupId>redis.clients</groupId>
                <artifactId>jedis</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.springframework.data</groupId>
                <artifactId>spring-data-redis</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <!-- Manually add Jedis and spring-data-redis -->
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>2.9.0</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-redis</artifactId>
        <version>1.8.0.RELEASE</version>
    </dependency>

Injecting RedisTemplate

Three components are needed: JedisConnectionFactory, RedisClusterConfiguration, and JedisPoolConfig. The following Java class creates a RedisTemplate bean configured for a cluster:

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisNode;
import org.springframework.data.redis.connection.jedis.JedisClientConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;

public class RedisClusterConfig {

    @Bean(name = "redisTemplate")
    @Primary
    public RedisTemplate redisClusterTemplate(@Value("${spring.custome.redis.cluster.nodes}") String host,
                                             @Value("${spring.custome.redis.cluster.password}") String password,
                                             @Value("${spring.custome.redis.cluster.timeout}") long timeout,
                                             @Value("${spring.custome.redis.cluster.max-redirects}") int maxRedirect,
                                             @Value("${spring.custome.redis.cluster.max-active}") int maxActive,
                                             @Value("${spring.custome.redis.cluster.max-wait}") int maxWait,
                                             @Value("${spring.custome.redis.cluster.max-idle}") int maxIdle,
                                             @Value("${spring.custome.redis.cluster.min-idle}") int minIdle) {
        JedisConnectionFactory connectionFactory = jedisClusterConnectionFactory(host, password,
                timeout, maxRedirect, maxActive, maxWait, maxIdle, minIdle);
        return createRedisClusterTemplate(connectionFactory);
    }

    private JedisConnectionFactory jedisClusterConnectionFactory(String host, String password,
                                                                 long timeout, int maxRedirect, int maxActive, int maxWait, int maxIdle, int minIdle) {
        RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration();
        List<RedisNode> nodeList = new ArrayList<>();
        String[] cNodes = host.split(",");
        for (String node : cNodes) {
            String[] hp = node.split(":");
            nodeList.add(new RedisNode(hp[0], Integer.parseInt(hp[1])));
        }
        redisClusterConfiguration.setClusterNodes(nodeList);
        redisClusterConfiguration.setPassword(password);
        redisClusterConfiguration.setMaxRedirects(maxRedirect);

        GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig();
        genericObjectPoolConfig.setMaxIdle(maxIdle);
        genericObjectPoolConfig.setMaxTotal(maxActive);
        genericObjectPoolConfig.setMinIdle(minIdle);
        genericObjectPoolConfig.setMaxWaitMillis(maxWait);
        genericObjectPoolConfig.setTestWhileIdle(true);
        genericObjectPoolConfig.setTimeBetweenEvictionRunsMillis(300000);

        JedisClientConfiguration.DefaultJedisClientConfigurationBuilder builder = (JedisClientConfiguration.DefaultJedisClientConfigurationBuilder) JedisClientConfiguration.builder();
        builder.connectTimeout(Duration.ofSeconds(timeout));
        builder.usePooling();
        builder.poolConfig(genericObjectPoolConfig);
        JedisConnectionFactory connectionFactory = new JedisConnectionFactory(redisClusterConfiguration, builder.build());
        connectionFactory.afterPropertiesSet();
        return connectionFactory;
    }

    private RedisTemplate createRedisClusterTemplate(JedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);

        Jackson2JsonRedisSerializer<Object> 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);

        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(stringRedisSerializer);
        redisTemplate.setHashKeySerializer(stringRedisSerializer);
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
}

Utility Class for Common Redis Operations

The following snippet shows a partial utility class that wraps typical Redis commands such as delete, get, set, increment, and hash operations. The full source is available in the author's GitHub repository.

/**
 *  Delete a key
 */
public boolean delete(String key) {
    try {
        return getTemplate().delete(key);
    } catch (Exception e) {
        log.error("redis hasKey() is error");
        return false;
    }
}

/**
 * Get a value by key
 */
public Object get(String key) {
    return key == null ? null : getTemplate().opsForValue().get(key);
}

/**
 * Set a value
 */
public boolean set(String key, Object value) {
    try {
        getTemplate().opsForValue().set(key, value);
        return true;
    } catch (Exception e) {
        log.error("redis set() is error");
        return false;
    }
}

/**
 * Set a value with expiration time (seconds)
 */
public boolean set(String key, Object value, long time) {
    try {
        if (time > 0) {
            getTemplate().opsForValue().set(key, value, time, TimeUnit.SECONDS);
        } else {
            set(key, value);
        }
        return true;
    } catch (Exception e) {
        log.error("redis set() is error");
        return false;
    }
}

/**
 * Increment a counter
 */
public Long incr(String key) {
    return getTemplate().opsForValue().increment(key);
}

/**
 * Increment by a specific step
 */
public Long incrBy(String key, long step) {
    return getTemplate().opsForValue().increment(key, step);
}

/**
 * Get a hash field
 */
public Object hget(String key, String item) {
    return getTemplate().opsForHash().get(key, item);
}

/**
 * Get all hash entries
 */
public Map<Object, Object> hmget(String key) {
    return getTemplate().opsForHash().entries(key);
}

In summary, the article demonstrates how to configure a SpringBoot project to connect to a Redis cluster, covering property settings, Maven dependencies, bean creation, and a reusable utility class. It also advises that developers should only adopt a cluster when the single‑node instance can no longer meet performance requirements.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavadatabaseredisConfigurationSpringBootRedisClusterSpringData
Full-Stack Internet Architecture
Written by

Full-Stack Internet Architecture

Introducing full-stack Internet architecture technologies centered on Java

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.