0

How to enable distributed/clustered cache when using Redis with spring-boot cache.

Especially when using Redis through spring-boot-starter-data-redis

1 Answer 1

2

Enable caching in the spring boot app is very simple. You would need to just follow three steps.

  • Define cache configuration
  • Add EnableCaching to any configuration class
  • Provide a CacheManager bean

For Redis, we've RedisCacheManager that can be configured and created.

Cache Configuration

@Configuration
@Getter
@Setter
@ConfigurationProperties(prefix = "cache")
public class CacheConfigurationProperties {
 // Redis host name
  private String redisHost;
 // Redis port
  private int redisPort;
  // Default TTL
  private long timeoutSeconds;
  // TTL per cache, add enties for each cache
  private Map<String, Long> cacheTtls;
}

Set their values via properties or yaml file like

cache.redisHost=localhost
cache.redisPort=6379
cache.timeoutSeconds=1000
cache.cacheTtls.cach1=100
cache.cacheTtls.cach2=200

Once you have created configuration, you can create cache config for RedisCacheManger by builder.

@Configuration
@EnableCaching
public class CacheConfig {
  private static RedisCacheConfiguration createCacheConfiguration(long timeoutInSeconds) {
    return RedisCacheConfiguration.defaultCacheConfig()
        .entryTtl(Duration.ofSeconds(timeoutInSeconds));
  }

  @Bean
  public LettuceConnectionFactory redisConnectionFactory(CacheConfigurationProperties properties) {
    RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
    redisStandaloneConfiguration.setHostName(properties.getRedisHost());
    redisStandaloneConfiguration.setPort(properties.getRedisPort());
    return new LettuceConnectionFactory(redisStandaloneConfiguration);
  }

  @Bean
  public RedisCacheConfiguration cacheConfiguration(CacheConfigurationProperties properties) {
    return createCacheConfiguration(properties.getTimeoutSeconds());
  }

  @Bean
  public CacheManager cacheManager(
      RedisConnectionFactory redisConnectionFactory, CacheConfigurationProperties properties) {
    Map<String, RedisCacheConfiguration> cacheConfigurations = new HashMap<>();

    for (Entry<String, Long> cacheNameAndTimeout : properties.getCacheTtls().entrySet()) {
      cacheConfigurations.put(
          cacheNameAndTimeout.getKey(), createCacheConfiguration(cacheNameAndTimeout.getValue()));
    }

    return RedisCacheManager.builder(redisConnectionFactory)
        .cacheDefaults(cacheConfiguration(properties))
        .withInitialCacheConfigurations(cacheConfigurations)
        .build();
  }
}

If you're using Redis cluster than update cache properties as per that. In this some beans would become primary if you want cache specific bean than make these methods private.

Sign up to request clarification or add additional context in comments.

Comments