In this tutorial, we will enhance the Fibonacci Service built earlier by adding Redis caching. This allows us to store previously calculated Fibonacci numbers and avoid recalculating them, significantly improving performance for repeated requests.
1. Why Use Caching?
In computationally heavy operations like Fibonacci calculations:
- Repeated requests for the same input result in redundant calculations.
- Using in-memory caching for each instance is inefficient when multiple application instances exist.
- Redis provides a centralized cache, accessible by all instances, ensuring consistency and improving response time.
2. Project Setup
We assume the Spring Boot project already includes:
spring-boot-starter-data-redis
- Redis server running locally or remotely
3. Configure Cache Manager
Create a separate package called config
to configure the cache manager:
package com.example.fib.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.cache.RedisCacheConfiguration; import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.connection.RedisConnectionFactory; @Configuration public class CacheConfig { @Bean public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) { RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig(); return RedisCacheManager.builder(redisConnectionFactory) .cacheDefaults(config) .build(); } }
Explanation:
RedisCacheManager
is used to manage caches in Redis.- Without this configuration, Spring Boot will default to using a
ConcurrentHashMap
, storing cache only locally in each instance.
4. Make Fibonacci Method Cacheable
Update the FibonacciService
to store results in Redis:
package com.example.fib.service; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; @Service public class FibonacciService { @Cacheable(value = "fibonacci", key = "#index") public long getFibonacci(int index) { return calculateFibonacci(index); } private long calculateFibonacci(int index) { if (index < 2) return index; return calculateFibonacci(index - 1) + calculateFibonacci(index - 2); } }
Key Points:
@Cacheable
marks the method as cacheable.value = "fibonacci"
specifies the cache bucket name in Redis.key = "#index"
ensures only theindex
parameter is used as the cache key, ignoring other parameters.
5. Enable Caching in Spring Boot
Add @EnableCaching
to the main application class:
package com.example.fib; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCaching; @SpringBootApplication @EnableCaching public class FibApplication { public static void main(String[] args) { SpringApplication.run(FibApplication.class, args); } }
6. Handling Multiple Method Parameters
By default, if a method has multiple parameters, Spring will use all parameters to generate the cache key. This may result in redundant entries in Redis.
Example:
@Cacheable(value = "fibonacci", key = "#index") public long getFibonacci(int index, String name) { ... }
- Without specifying
key = "#index"
, the cache would considername
as part of the key. - Specifying
key = "#index"
ensures only the Fibonacci index determines the cached value, ignoring irrelevant parameters.
7. Testing the Cache
- Start the application.
- Call the endpoint multiple times:
GET /fib/45
Observations:
- First request: Takes time due to calculation.
- Subsequent requests: Return immediately from Redis cache.
- Only the relevant
index
is used as the key.
8. Inspecting Redis
Use redis-cli
or a GUI tool:
127.0.0.1:6379> KEYS * 1) "fibonacci::45"
- Redis stores a hash or serialized object for each cached Fibonacci index.
- Accessing the same index returns the cached value instantly.
9. Summary
By integrating Redis caching:
- We avoid recalculating Fibonacci numbers for repeated requests.
- Performance improves drastically for computationally heavy or frequently requested operations.
- Multiple application instances can share a centralized cache, maintaining consistency.