$ sudo apt update
$ sudo apt install redis-server
Custom TTL for Spring data Redis Cache
Upasana | October 01, 2020 | 2 min read | 2,978 views
Spring Boot 2.2+ provides options to customize Redis Cache using RedisCacheManagerBuilderCustomizer enabling us to set custom value for TTL (time-to-live/expiry) for each of the configured cache.
At the time of writing this article, Spring Boot 2.3.4.RELEASE does not allow configuring TTL value for each individual cache through application.yml
, so we need to use RedisCacheManagerBuilderCustomizer
if we want to configure different timeout for each individual cache.
Redis Setup
You can easily setup Redis on Ubuntu machine using the below command
Check redis service status using the below systemctl command:
$ sudo systemctl status redis-server.service
I have a separated dedicated article on installing, configuring and securing redis on Ubuntu server.
If you are using Mac, then homebrew can be used to quickly install Redis server.
$ brew install redis
On windows, you can get pre-compiled executable of redis from here redislab or here microsoftarchive redis 3.2
Gradle setup
We will be using Spring Boot 2.3.4.RELEASE
for this tutorial with dependencies on Spring Data Redis. You can find about Spring Data Redis project here Spring Boot Features
implementation("org.springframework.boot:spring-boot-starter-data-redis")
Spring Boot Redis configuration
We need to configure Spring data redis cache in application.yml
for properties hostname, port number and cache names.
spring.redis.host: localhost
spring.redis.port: 6379
spring.cache.cache-names: cache1, cache2
spring.cache.redis.time-to-live: 600000 (1)
1 | redis.time-to-live allows setting up TTL for the all caches to same value. |
The only caveat with this setting (spring.cache.redis.time-to-live
) is that you cannot specify custom TTL value for individual cache.
Customize TTL for individual cache in Redis
We will create a custom configuration to create a Bean of type RedisCacheManagerBuilderCustomizer
to allow RedisCacheManager configuration. RedisCacheConfiguration
allows a method named entryTtl(Duration)
that allows us to set custom value for TTL for a given Cache.
import org.springframework.boot.autoconfigure.cache.RedisCacheManagerBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class RedisConfig {
@Bean
RedisCacheManagerBuilderCustomizer redisCacheManagerBuilderCustomizer() {
return (builder) -> {
Map<String, RedisCacheConfiguration> configurationMap = new HashMap<>();
configurationMap.put("cache1", RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(20))); (1)
configurationMap.put("cache2", RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(2))); (2)
builder.withInitialCacheConfigurations(configurationMap);
};
}
}
1 | cache1 will have expiry of 20 seconds from time of creation. |
2 | cache2 will have expiry of 2 hours from time of creation (time-to-live). |
Kotlin equivalent of the same configuration is this:
@Configuration
class RedisConfig {
@Bean
fun redisCacheManagerBuilderCustomizer() = RedisCacheManagerBuilderCustomizer { builder ->
val configurationMap = HashMap<String, RedisCacheConfiguration>()
configurationMap["cache1"] = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(20))
configurationMap["cache2"] = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(2))
builder.withInitialCacheConfigurations(configurationMap)
}
}
Now we are good to use Redis cache within our controllers.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class RedisTestController {
@RequestMapping("/hello/{name}")
@Cacheable("cache1")
public String hello(@PathVariable String name) throws InterruptedException {
Thread.sleep(3000);
return "Hello " + name;
}
}
If we call GET /hello/carvia
, the very first call should take around 3 seconds, subsequent calls should be instant since method invocation results will be cached for next 20 seconds.
That’s all.
Top articles in this category:
- Redis rate limiter in Spring Boot
- Custom banner in spring boot
- Setting a Random Port in Spring Boot Application at startup
- Prevent Lost Updates in Database Transaction using Spring Hibernate
- Disable SSL validation in Spring RestTemplate
- N+1 problem in Hibernate & Spring Data JPA
- Elasticsearch with Spring Boot + Spring Data