WalzoneInterview Prep
📞 Interviewing soon? Practice with a realistic AI mock phone interview — it calls you, then scores you. First 15 min FREE →

Spring Framework · Guru · question 91 of 100

How can you implement distributed caching and cache synchronization in a Spring application using Spring Cache and third-party caching solutions like Redis or Hazelcast?

📕 Buy this interview preparation book: 100 Spring Framework questions & answers — PDF + EPUB for $5

Caching is essential to maintain the performance and scalability of any application. Distributed caching is a solution that stores the same data in multiple cache servers to achieve high availability, fault tolerance, and faster retrieval speed. In a Spring application, we can use Spring Cache along with third-party caching solutions like Redis, Hazelcast, or Ehcache to implement distributed caching and cache synchronization.

Here is a step-by-step guide to implementing distributed caching and cache synchronization using Spring Cache and Redis:

1. Add Redis dependency to your project:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>

2. Configure Redis Cache Manager in your Spring configuration file. In this example, Redis is being used as the cache store:

    @Bean
    public RedisConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory(new RedisStandaloneConfiguration("localhost", 6379));
    }

    @Bean
    public CacheManager cacheManager() {
        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofMinutes(1))
                .disableCachingNullValues();

        return RedisCacheManager.builder(redisConnectionFactory())
                .cacheDefaults(redisCacheConfiguration)
                .build();
    }

This configuration sets up the Redis server and creates the cache manager instance that is later used to interact with Redis.

3. Annotate methods that need to be cached with ‘@Cacheable‘.

    @Cacheable(value = "exampleCache", key = "#id")
    public Example getCachedExample(String id) {
        return exampleService.getExample(id);
    }

This annotation tells Spring to use the ‘CacheManager‘ to look up the cache named ‘exampleCache‘. When this method is called with ‘id‘ parameter, Spring will try to fetch the cached result for the given ‘id‘ from the cache. If it’s a cache miss, then the method is executed, and the output is cached in Redis. Subsequent calls with the same ‘id‘ get a cached result.

4. Refresh the cache when data is updated.

When data is updated, we need to refresh the cache to ensure that subsequent requests get the updated data. For that, we can use ‘@CachePut‘ annotation, which updates the cache with the new data.

    @CachePut(value = "exampleCache", key = "#id")
    public Example updateExample(String id, Example example) {
        return exampleService.updateExample(id, example);
    }

This method updates the ‘example‘ object for the given ‘id‘. The updated object will be cached with the same ‘id‘. Subsequent calls with the same ‘id‘ will get the updated data from the cache.

5. Remove data from the cache using ‘@CacheEvict‘ annotation

We might need to remove data from the cache when it is no longer needed or when it becomes stale. We can use the ‘@CacheEvict‘ annotation to remove data from the cache.

    @CacheEvict(value = "exampleCache", key = "#id")
    public void evictExample(String id) {
        exampleService.deleteExample(id);
    }

This method deletes the ‘example‘ object for the given ‘id‘. The cache entry with the same ‘id‘ is removed from the cache.

6. Configure Hazelcast as a distributed cache store

Hazelcast is another popular distributed caching solution. We can use the ‘spring-boot-starter-cache‘ dependency and ‘hazelcast-spring‘ to use Hazelcast as a cache store.

    <dependency>
        <groupId>com.hazelcast</groupId>
        <artifactId>hazelcast</artifactId>
    </dependency>

    <dependency>
        <groupId>com.hazelcast</groupId>
        <artifactId>hazelcast-spring</artifactId>
    </dependency>
    
    @Configuration
    @EnableCaching
    public class HazelcastConfig {

        @Bean
        public HazelcastInstance hazelcastInstance() {
            Config config = new Config();
            config.setInstanceName("hazelcast-instance")
                    .addMapConfig(new MapConfig().setName("exampleCache")
                            .setMaxSizeConfig(new MaxSizeConfig(200, MaxSizeConfig.MaxSizePolicy.FREE_HEAP_SIZE))
                            .setEvictionPolicy(EvictionPolicy.LRU)
                            .setTimeToLiveSeconds(20));

            return Hazelcast.newHazelcastInstance(config);
        }

        @Bean
        public CacheManager cacheManager() {
            return new HazelcastCacheManager(hazelcastInstance());
        }
    }

This configuration sets up the Hazelcast instance and creates the Hazelcast Cache manager instance that is later used to interact with Hazelcast.

In conclusion, distributed caching and cache synchronization are essential to maintain the performance and scalability of any application. In Spring, we can use Spring Cache along with third-party caching solutions like Redis or Hazelcast to implement distributed caching and cache synchronization. Implementing caching with Spring Cache and Redis is an easy way to start caching in your Spring application.

Reading is step one. Saying it out loud is the interview. Our AI interviewer calls your phone and runs a realistic Spring Framework interview — then scores it.
📞 Practice Spring Framework — free 15 min
📕 Buy this interview preparation book: 100 Spring Framework questions & answers — PDF + EPUB for $5

All 100 Spring Framework questions · All topics