How to Connct to Bitnami Redis (6 Nodes) Cluster deployed on Self-Managed OpenShift Cluster from Spring Boot Microservices?

:warning: IMPORTANT, please fill the questions

We assume you are using Bitnami to deploy your application.

  • Which version of the application are you using?:
    Bitnami Redis Cluster (The Helm Chart in the link: https://github.com/bitnami/charts/tree/master/bitnami/redis-cluster)

  • Please choose how you got the application: Installer (Windows, Linux, macOS), cloud image (AWS, GCE, Azure, …) or VM (VMDK, VBOX): Self-Managed OpenShift Cluster

  • Have you installed any plugin or modified any configuration file?: No, just changed the following Helm Chart values:
    "
    networkPolicy:
    enabled: true
    "

and

"
serviceAccount:
name: redis-sa

"

  • Describe here your question/suggestion/issue (expected and actual results):

Please, I need to know how to connect to Bitnami Redis-Cluster (6 Nodes) deployed on self-managed “on-prem” OpenShift Cluster from a Spring Boot microservice. I’m using the headless service “redis-cluster-headless” to connect to the Redis Cluster, and I’m not sure whether this is the right way so the Redis Cluster continue doing the required replication and data Sharding:

  • Steps to reproduce the issue (if relevant):

This is the project details:

application.yml

 **Spring Cache Configuration:**

spring:
  cache:
    type: redis
  redis:
    #time-to-live: 60000
    cluster:
      nodes:
      ## One Single node holds the headless-service-name.namespace-where-redis-cluster-installed:port-number - The other examples I found 
      - mdi-redis-cluster-headless.caching-system-cluster:6379
      maxRedirects: 3
    password: K4H8qm1b7I 
    timeout: 30000

## Custom Configuration to handle differn TTL per cache Name:
cacheNames:
    ttlDefault: 60
    cacheExpirations:
      myControlledCache: 240





**Spring Configuration:**



package net.atos.mdi.backend.microgateway.config;

import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisPassword;
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
@ EnableConfigurationProperties(CacheConfigurationProperties.class)
public class CacheConfig extends CachingConfigurerSupport
{
	
	private RedisProperties redisProperties;
		
	public CacheConfig(RedisProperties redisProperties) {
		this.redisProperties = redisProperties;

	}

	@ Bean
	public LettuceConnectionFactory redisConnectionFactory(RedisClusterConfiguration redisConfiguration) {

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

		return new LettuceConnectionFactory(redisConfiguration, clientConfig);
	}

	@ Bean
	public RedisClusterConfiguration redisConfiguration() {
		RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration(
				redisProperties.getCluster().getNodes());
		redisClusterConfiguration.setMaxRedirects(redisProperties.getCluster().getMaxRedirects());
		redisClusterConfiguration.setPassword(RedisPassword.of(redisProperties.getPassword()));
		return redisClusterConfiguration;
	}
	

	@ Bean
	@ ConditionalOnMissingBean(name = "redisTemplate")
	@ Primary
	public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
		RedisTemplate<String, Object> template = new RedisTemplate<>();
		template.setConnectionFactory(connectionFactory);
		template.setKeySerializer(new StringRedisSerializer());
		// other settings...
		return template;
	}
		
	
	private static RedisCacheConfiguration createCacheConfiguration(long timeoutInSeconds) {
		return RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(timeoutInSeconds));
	}
	
	@ Bean
	public RedisCacheConfiguration cacheConfiguration(CacheConfigurationProperties customeProperties) {
		return createCacheConfiguration(customeProperties.getTtlDefault());
	}

	@ Bean(name = "cacheManager")
	public CacheManager cacheManager(CacheConfigurationProperties customeProperties) {
		Map<String, RedisCacheConfiguration> cacheConfigurations = new HashMap<>();

		// to Handle differen TTL per cache names
		for (Entry<String, Long> cacheNameAndTimeout : customeProperties.getCacheExpirations().entrySet()) {
			cacheConfigurations.put(cacheNameAndTimeout.getKey(),
					createCacheConfiguration(cacheNameAndTimeout.getValue()));
		}

		return RedisCacheManager.builder(redisConnectionFactory(redisConfiguration()))
				.cacheDefaults(cacheConfiguration(customeProperties)) // to Handle default TTL from "cacheNames.ttlDefault" configuration
				.withInitialCacheConfigurations(cacheConfigurations)
				.build();
	}
	
}


**This is the Caching:**


import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import net.atos.mdi.backend.microgateway.service.ControlledCacheService;

@ Service
public class ControlledCacheServiceImpl implements ControlledCacheService{

    private static final Logger LOGGER = LogManager.getFormatterLogger(ControlledCacheServiceImpl.class);

    private static final String CONTROLLED_PREFIX = "myControlledPrefix_";

    public static String getCacheKey(String relevant){
        return CONTROLLED_PREFIX + relevant;
    }

    @ Cacheable(cacheNames = "myControlledCache", cacheManager = "cacheManager", key = "T(net.atos.mdi.backend.microgateway.service.impl.ControlledCacheServiceImpl).getCacheKey(#relevant)")
    public String getFromCache(String relevant) {
    	LOGGER.info("Returning NOT from cache. Tracking: {}!", relevant);
        return "Dummy String";
    }
    

}

  • Copy the apache log (if relevant):
PASTE HERE

Hi @irefaat

Thanks for using the Bitnami Redis-Cluster Chart!

We provide technical support for our containers & charts in our Github repositories. Our team is actively monitoring them and will be glad to help you there, usually within a business day, and the whole community will benefit from your contribution. Could you please post your question by creating a new issue in the https://github.com/bitnami/charts repo?

https://github.com/bitnami/charts/issues

Best regards,
Jose Antonio Carmona


Was my answer helpful? Click on :heart:

Hi @jcarmona

Thanks a lot for supporting me.

My Question is how to create a Spring Boot Client for the installed Bitnami Redis-Cluster Chart, I have created one, but not sure of.

As per your kind advice, I will write my question to the repository.

Thanks a lot.
Ibrahim