코드잇 BE스프린트

위클리 페이퍼 - 16주차

beginner-development 2026. 5. 4. 14:40

Spring Cache에서 @Cacheable, @CachePut, @CacheEvict의 차이점과 각각을 어떤 상황에서 사용하는 것이 적절한지 설명해주세요.

1. @Cacheable

설명 : 메서드 실행 결과를 캐시에 저장하고, 동일한 인자로 호출 시 저장된 값을 반환하여 조회 성능을 향상시키기 위해 사용

  • @Cacheable("products") → 캐시 이름이 products인 저장소에 결과를 저장
  • 동일한 ID로 다시 호출되면 DB 접근 없이 캐시된 결과를 반환
  • condition unless 속성을 이용하면 캐시 조건을 제어할 수 있음
속성 설명
condition 캐싱을 수행할 조건 지정 (true일 때만 저장)
unless 메서드 실행 후 결과에 따라 저장 여부 결정

 

@Service
public class ProductService {

    @Cacheable(value = "products", condition = "#id > 0", unless = "#result == null")
    public Product findProductById(Long id) {
        System.out.println("DB 접근 발생!");
        return new Product(id, "노트북", 1200000);
    }
}

2. @CachePut

설명 : 항상 메서드를 실행하고, 실행 결과를 캐시에 강제로 갱신하여 데이터 갱신 후 캐시 동기화를 위해 사용

  • condition  unless 외에 key 속성을 사용
속성 설명
key 캐시 키를 SpEL로 지정. 지정하지 않으면 기본 키 생성 규칙(모든 파라미터 기반)이 사용

 

@Service
public class ProductService {

    @CachePut(value = "products", key = "#product.id")
    public Product updateProduct(Product product) {
        System.out.println("DB에서 제품 업데이트 후 캐시 갱신");
        return product;
    }
}

3. @CacheEvict

설명 : 캐시된 데이터를 제거할 때 사용

  • beforeInvocationallEntries 속성을 사용하여 삭제 조건을 제어할 수 있음
속성 설명
beforeInvocation 메서드를 실행하기 전에 캐시를 삭제하도록 지정(기본값은 false로 메서드 실행 후 삭제)
allEntries 모든 캐시를 삭제하도록 지정

 

@Service
public class ProductService {

    @CacheEvict(value = "products", key = "#id")
    public void deleteProduct(Long id) {
        System.out.println("DB에서 제품 삭제 후 캐시 제거");
    }
}

//전체 캐시 삭제
@CacheEvict(value = "products", allEntries = true)
public void clearCache() {
    System.out.println("모든 캐시 제거");
}

 

나만의 언어로 정리해보기

Spring Cache
@Cacheable
-
메서드 실행 결과를 캐시에 저장하고, 동일한 인자로 호출 시 저장된 값을 반환하여 조회 성능을 향상 시키기 위해 사용

@CachePut
- 항상 메서드를 실행하고, 실행 결과를 캐시에 강제로 갱신하여 데이터 갱신 후 캐시 동기화를 위해 사용

@CacheEvict
캐시된 데이터를 제거할 때 사용

 

로컬 캐시와 분산 캐시의 개념 차이와 각각의 장단점, 그리고 실무에서 어떤 기준으로 선택해야 하는지 설명해주세요.

1. 로컬 캐시(In-Memory Cache)

1. 개념

  • 애플리케이션 내부 메모리(RAM) 에 데이터를 저장하는 캐시 구조
  • 서버 자체에 존재하므로 외부 네트워크 요청 없이 가장 빠르게 데이터에 접근할 수 있음
  1. 장점
    • 네트워크 호출이 없어 응답 속도가 가장 빠릅니다.
    • 단순 구현 가능 (HashMap, Caffeine 등)
    • 외부 장애(네트워크, Redis 다운 등)에 영향받지 않습니다.
  2. 단점
    • 서버마다 캐시가 달라 데이터 불일치 가능성이 있습니다.
    • 서버 재시작 시 캐시가 모두 초기화됩니다.
    • 확장성(Scalability)이 낮습니다.
항목 설명
속도 매우 빠름(메모리 직접 접근)
범위 서버 프로세스 내부에서만 사용 가능
일관성 서버간 공유 불가 → 데이터 불일치 발생 가능
운영 난이도 낮음(별도 서버 없음)

 

2. 분산 캐시(Distributed Cache)

1. 개념

  • 여러 서버 인스턴스가 동일한 캐시 서버를 공유하는 구조
  • 일반적으로 Redis, Memcached 같은 인메모리 서버를 사용
  • 여러 서버가 하나의 중앙 캐시 저장소를 공유
  • 데이터 일관성 유지가 용이하며, 확장성(Scale-out)에 유리
  1. 장점
    • 여러 서버 간 데이터 공유 가능.
    • 캐시 서버 장애 시에도 Persistence(데이터 영속화) 설정 가능.
    • 수평 확장(Scale-Out) 에 유리함.
  2. 단점
    • 네트워크 지연이 존재합니다.
    • Redis 장애 시 모든 요청이 DB로 몰릴 수 있습니다.
    • 운영/모니터링 복잡도가 증가합니다.
항목 설명
속도 빠름 (네트워크 접근 존재)
데이터 일관성 모든 서버가 동일 캐시 사용 → 높은 일관성
확장성 높음 (노드 추가 가능)
운영 복잡도 Redis/Memcached 서버 운영 필요

 

3. 로컬 캐시와 분산 캐시의 실무 선택 기준

기준 로컬 캐시 분산 캐시
속도 매우 빠름 (네트워크 없음) 네트워크 왕복 있음 (수 ms)
일관성 낮음 (인스턴스별 불일치 가능) 높음 (모든 인스턴스 공유)
확장성 서버 수 증가 시 히트율 ↓ 수평 확장에 유리
데이터 크기 인스턴스 메모리 한정 큰 데이터도 저장 가능
운영 복잡도 단순 (별도 서버 X) 인프라 필요 (Redis 등 운영)
주요 사용처 설정값, 권한, 자주 읽는 소형 데이터 세션, 랭킹, 토큰, 대용량 캐시
일관성 요구 약한 경우 적합 강한 경우 필수
장애 영향 서버 재시작 시 캐시 초기화 재시작에도 캐시 유지 가능
  • 속도와 간결성이 우선 → 로컬 캐시
  • 여러 인스턴스 간 공유와 일관성이 중요 → 분산 캐시

나만의 언어로 정리해보기

로컬 캐시와 분산 캐시
로컬 캐시
-
 애플리케이션 내부 메모리에 데이터를 저장하는 캐시 구조로, 서버 자체에 존재하므로 외부 네트워크 요청 없이 가장 빠르게 데이터에 접근할 수 있다.
- 장점
-
외부 장애에 영향을 받지 않으며 단순 구현이 가능하고 응답 속도가 가장 빠르다.

- 단점

확장성이 낮고 서버 재시작 시 캐시가 모두 초기화되며, 서버마다 캐시가 달라 데이터 불일치의 가능성이 있다.

분산 캐시
- 여러 서버 인스턴스가 동일한 캐시 서버를 공유하는 구조로, 일반적으로 Redis, Memcached 같은 인메모리 서버를 사용한다.
- 여러 서버가 하나의 중앙 캐시 저장소를 공유하고, 데이터 일관성 유지가 용이하며, 확장성에 유리하다.

- 장점
- 
여러 서버 간 데이터 공유가 가능하고, 캐시 서버 장애 시에도 데이터 영속화 설정이 가능하며 수평 확장에 유리하다.

- 단점

네트워크 지연이 존재하고, Redis 장애 시 모든 요청이 DB로 몰릴 수 있으며 운영/모니터링 복잡도가 증가한다.

로컬 캐시와 분산 캐시의 실무 선택 기준
속도와 간결성이 우선되면 로컬 캐시
- 여러 인스턴스 간 공유와 일관성이 중요하면 분산 캐시

'코드잇 BE스프린트' 카테고리의 다른 글

위클리 페이퍼 - 17주차  (1) 2026.05.04
위클리 페이퍼 - 15주차  (0) 2026.05.01
위클리 페이퍼 - 14주차  (0) 2026.04.30
위클리 페이퍼 - 13주차  (0) 2026.04.29
위클리 페이퍼 - 12주차  (0) 2026.04.29