[스프링과 캐시] - 신작 API

yeom yaloo·2023년 8월 18일
1

쇼핑몰

목록 보기
19/19
post-thumbnail

[들어가기에 앞서..]

📄 조금 더 자세한 이론은 이곳에서..

1. 캐시를 사용하려고 한 이유

스프링이 제공하고 있는 캐시의 기능이 있음을 깨닫고 이를 어디에 사용하면 좋을까를 고민했다.

반복되고 매번 호출하기엔 복잡한 로직이나 DB에서 읽어오는 작업이 느린 데이터들을 캐시에 저장하고 사용하면 서버의 부하와 성능을 높일 수 있다고 한다.

2. 왜 신작을 찾아오는 기능에 캐시를 사용하려 했나?

  1. 해당 작업은 신작이 나와서 해당 신작을 웹페이지에 등록하기 전까지 변하지 않는다.
  • 즉 매번 API를 호출할 필요가 없이 저장된 값을 불러오기만 하면 된다는 것이다.
  1. 일정 기간이 지나면 해당 데이터는 업데이트 되어야 한다.

-최신작 도서 목록을 캐시하여 사용자가 빠르게 접근할 수 있도록 합니다.

  • 캐시의 유효 기간을 적절히 설정하여 일정 기간 동안 캐시를 활용하고 그 후에 업데이트된 데이터로 갱신할 수 있습니다.

[캐시 적용과 서비스레이어]

1. 왜 서비스 레이어에서 이를 적용하나?

  • 조금 더 비지니스 로직에 적응하기 위해서 서비스 레이어에서 이를 적용해서 사용합니다.
  • 레포지토리에서 해당 캐시 기술을 적용하게 될 경우 db와 관련된 기능을 수행하는 것에 치중하지 못할 수 있기 때문에 캐시와 관련된 기술의 적용은 서비스레이어의 메서드에서 주로 사용합니다.

2. 레포지토리에 적용할 경우?

  • 데이터와 관련된 작업만 진행해야 하는 레이어로 이 레이어에서 해당 작업을 진행하면 효율성이 떨어진다고 한다.

[Cache 적용 API Server]

1. CacheConfiguration

import com.querydsl.core.annotations.Config;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Configuration;


/**
 * 스프링이 제공하는 캐시를 사용하기 위한 캐시 관련 설정 파일입니다.
 * */
@Configuration
@EnableCaching
public class CacheConfig {

}
  • 자바코드를 이용해서 해당 설정 작업을 진행합니다.
  • 캐시 사용을 위해서 @EnableCaching 애너테이션을 붙여주세요.

2. CacheManager 빈 등록

기본적으로 ConcurrentHashMap의 자료구조로 데이터를 메모리에 저장하는데 분산 서버의 경우엔 외부 프로바이더를 사용해서 캐시를 저장하는 것이 좋다.
그렇기 때문에 여러 기본 제공 CacheManager 대신해서 RedisCacheManager를 CacheManager로 빈 등록해 사용할 것이다.

2-1. Redis CacheManager?

  • RedisCacheManager는 Spring에서 제공하는 캐시 매니저 구현 중 하나로, Redis를 캐시 저장소로 사용합니다.
  • Redis는 인메모리 데이터 스토어로서 빠른 읽기 및 쓰기 성능을 제공하며, 분산 캐싱을 위한 클러스터링 기능도 지원합니다.
  • Redis를 사용하면 여러 서버 간에 공유되는 중앙 집중식 캐시를 구성할 수 있고, 데이터를 영속적으로 저장하여 애플리케이션 재시작 시에도 캐시 데이터를 유지할 수 있습니다.

[샘플 코드]

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);
    }
}

3. Cache를 적용한 Service Layer

3-1. @Cacheable 사용

  • 해당 애너테이션을 사용하면 수정, 조회에 사용합니다.
  • 삭제등의 작업은 @CacheEvict를 사용해야 합니다

3-2. @CacheEvict를 이용한 캐시 삭제

  • 해당 애너테이션을 사용하면 캐시를 삭제합니다.
  • 이때 삭제 작업은 해당 기능의 변경이 있어서 다시 해야 할때 등에 사용합니다.
    ex) 신작이 추가되면 신작이 추가되는 로직에 @CacheEvict를 붙여 해당 캐시 데이터를 삭제하고 다시 실행할 수 있게 구현해야 합니다.

4. Controller

4-1. @Cacheable 서비스를 호출하는 컨트롤러

  • 해당 컨트롤러를 다른 컨트롤러와 같이 그냥 사용하면 됩니다.

[API 호출 FE Server]

1. 캐시를 사용한 신작 API 불러온 뷰 페이지

2. API 호출 시간

3. Redis에 저장한 나의 캐시 데이터

[앞으로 개선할 부분?]

1. 잦은 API 호출

  • 메인 페이지를 확인하면 해당 부분이 계속 접속할때마다 호출됨을 알수 있다.
  • 이부분이 만약 잘 바뀌지 않는 부분이라면 굳이 우리는 비용을 계속해서 지불해가며 이를 호출할 이유가 없다.
  • 그러니 이 부분을 FE Server 측에서 해당 API관련 호출 작업에 Cache를 적용해서 호출 비용이나 여러 효율을 높일 수 있게 할 예정이다.

1-1. 그렇다면 잦은 API 호출의 Cache 적용은 어디서 해야 하나?

  • API 제공, API를 사용하는 쪽이라는 관점에서 보면 API를 사용하는 쪽에서 해당 캐시 작업을 진행하는 것을 권장한다.

1-2. API를 사용하는 쪽에서 캐시를 적용해야 하는 이유

[API를 사용하는 쪽에서 캐시를 적용해야 하는 이유]

  • 느슨한 결합: MSA에서는 각 서비스가 독립적으로 배포되고 운영되는 것이 중요한 개념입니다. API를 제공하는 쪽에서 캐싱을 수행하면, 클라이언트가 해당 서비스에 더 강하게 결합되는 결과를 초래할 수 있습니다. 클라이언트가 API를 호출하는 방식에 따라 API 서버의 캐싱 전략을 변경할 수 있도록, 캐싱을 클라이언트 쪽에서 관리하는 것이 더욱 유연한 설계입니다.
  • 클라이언트 특화 캐싱: 서비스의 다양한 클라이언트들은 동일한 API에 대해 다른 캐싱 전략을 필요로 할 수 있습니다. 클라이언트의 특성에 따라 캐싱 기간, 캐싱 대상 등을 다르게 설정하고 관리하는 것이 중요합니다. API를 제공하는 쪽에서 캐싱을 수행한다면, 이러한 클라이언트 특화 캐싱을 구현하기가 어려워질 수 있습니다.
  • 네트워크 부하 최소화: 클라이언트에서 캐싱을 수행하면, 같은 API를 여러 클라이언트들이 호출할 때 API 서버에 대한 네트워크 부하를 줄일 수 있습니다. 캐싱된 결과를 클라이언트 측에서 사용하므로, 중복적인 API 호출을 줄이고 네트워크 트래픽을 최적화할 수 있습니다.

2. 검색 기록, 최근 본 상품과 같이 캐시를 사용해서 구현하면 좋을 기능 추가 구현하기

1. 검색 기록

2. 최근 본 상품

profile
즐겁고 괴로운 개발😎

0개의 댓글