스프링이 제공하고 있는 캐시의 기능이 있음을 깨닫고 이를 어디에 사용하면 좋을까를 고민했다.
반복되고 매번 호출하기엔 복잡한 로직이나 DB에서 읽어오는 작업이 느린 데이터들을 캐시에 저장하고 사용하면 서버의 부하와 성능을 높일 수 있다고 한다.
- 해당 작업은 신작이 나와서 해당 신작을 웹페이지에 등록하기 전까지 변하지 않는다.
- 일정 기간이 지나면 해당 데이터는 업데이트 되어야 한다.
-최신작 도서 목록을 캐시하여 사용자가 빠르게 접근할 수 있도록 합니다.
import com.querydsl.core.annotations.Config;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Configuration;
/**
* 스프링이 제공하는 캐시를 사용하기 위한 캐시 관련 설정 파일입니다.
* */
@Configuration
@EnableCaching
public class CacheConfig {
}
기본적으로 ConcurrentHashMap의 자료구조로 데이터를 메모리에 저장하는데 분산 서버의 경우엔 외부 프로바이더를 사용해서 캐시를 저장하는 것이 좋다.
그렇기 때문에 여러 기본 제공 CacheManager 대신해서 RedisCacheManager를 CacheManager로 빈 등록해 사용할 것이다.
[샘플 코드]
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.support.SimpleCacheManager;
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
@EnableCaching // 캐시 기능을 활성화
public class CacheConfig {
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();
RedisCacheManager redisCacheManager = RedisCacheManager.builder(redisConnectionFactory)
.cacheDefaults(cacheConfiguration)
.build();
return new SimpleCacheManager(redisCacheManager);
}
}
[API를 사용하는 쪽에서 캐시를 적용해야 하는 이유]
- 느슨한 결합: MSA에서는 각 서비스가 독립적으로 배포되고 운영되는 것이 중요한 개념입니다. API를 제공하는 쪽에서 캐싱을 수행하면, 클라이언트가 해당 서비스에 더 강하게 결합되는 결과를 초래할 수 있습니다. 클라이언트가 API를 호출하는 방식에 따라 API 서버의 캐싱 전략을 변경할 수 있도록, 캐싱을 클라이언트 쪽에서 관리하는 것이 더욱 유연한 설계입니다.
- 클라이언트 특화 캐싱: 서비스의 다양한 클라이언트들은 동일한 API에 대해 다른 캐싱 전략을 필요로 할 수 있습니다. 클라이언트의 특성에 따라 캐싱 기간, 캐싱 대상 등을 다르게 설정하고 관리하는 것이 중요합니다. API를 제공하는 쪽에서 캐싱을 수행한다면, 이러한 클라이언트 특화 캐싱을 구현하기가 어려워질 수 있습니다.
- 네트워크 부하 최소화: 클라이언트에서 캐싱을 수행하면, 같은 API를 여러 클라이언트들이 호출할 때 API 서버에 대한 네트워크 부하를 줄일 수 있습니다. 캐싱된 결과를 클라이언트 측에서 사용하므로, 중복적인 API 호출을 줄이고 네트워크 트래픽을 최적화할 수 있습니다.