엄지월드

[4차시] 캐싱 전략과 최적화 기법 : 속도와 자원을 동시에 잡는 방법 본문

기타

[4차시] 캐싱 전략과 최적화 기법 : 속도와 자원을 동시에 잡는 방법

킨글 2025. 3. 18. 20:44

스프링 부트 어플리케이션 캐시 적용 방법과 기본 원리

  • 캐시 활성화 : @EnableCaching 어노테이션 사용
  • 주요 어노테이션
    • @Cacheable : 캐시 저장
      • 캐시된 데이터가 있을 경우 메서드 실행을 건너뛰고 캐시된 값 반환
      • key 옵션 : 캐시에 저장될 키 값 지정 가능
      • condition 옵션 : 조건에 맞는 경우에만 캐시 적용 가능 

  • 주요 어노테이션
    • @CacheEvict : 캐시 삭제
    • @CachePut : 캐시 업데이트

  • 캐시 프로바이더 설정
    • Ehcache : 로컬 캐시를 제공하는 강력한 캐시 라이브러리
    • Caffeine : 높은 성능을 자랑하는 메모리 기반 캐시
    • Redis : 네트워크 기반의 분산 캐시로, 여러 인스턴스에서 데이터를 공유 가능 

  • 캐시 사용 시 고려해야 할 성능 이슈
    • 캐시 과다 사용 : 캐시가 너무 자주 갱신되면 오히려 성능에 악영향
    • 캐시 적중률(Cache Hit Ratio) : 캐시가 얼마나 자주 유용한지 비율을 측정
    • 캐시 만료와 갱신 빈도 : 캐시 데이터가 오래되면 성능 저하 발생
    • 캐시 저장 공간과 메모리 제한 : 캐시 데이터가 메모리를 과도하게 사용하지 않도록 설정 
  • 캐시 병목 현상 해결 방법
    • 캐시 쏠림 현상 : 한 번에 너무 많은 요청이 캐시에 집중될 때 발생
    • 캐시 동시성 문제 : 다중 스레드에서 캐시 접근 시 성능 저하
    • 해결 방법 
      • 동시성 관리 : 스레드 세이프한 캐시 설정 (예 : Caffeine의 동시성 관리)
      • 캐시 파티셔닝 : 여러 캐시 서버로 요청 분산
      • 배치 처리 : 데이터 갱신 시 배치 처리를 통해 부하 분산
  • 로컬 캐시 vs 분산 캐시
    • 로컬 캐시
      • 단일 어플리케이션 인스턴스에서만 사용
      • 빠르지만, 인스턴스 간 캐시 동기화가 어렵고, 확장성이 낮음
        -> 적은 인스턴스에서 속도와 간편함이 중요한 경우
    • 분산 캐시 
      • 여러 인스턴스가 동일한 데이터를 공유
      • 확장성이 좋지만 네트워크 지연이 발생할 수 있음
        -> 클라우드 환경이나 마이크로 서비스 구조에서 사용

스프링 부트 캐시 전략

  • 캐시 전략의 필요성
    • 무분별한 캐시 사용은 성능 저하와 메모리 사용 증가를 유발
    • TTL, LRU, 캐시 크기 설정을 통해 최적화 필요
  • TTL 설정의 개념과 필요성
    • TTL 설정을 통해 최적의 캐시 관리 가능
  • TTL 설정 방법

  • LRU 전략의 개념
    • 가장 오랫동안 사용되지 않은 데이터를 먼저 삭제
    • 캐시가 꽉 찼을 때 새로운 데이터를 저장하기 위한 메모리 확보
    • 자주 사용되는 데이터는 유지하고 사용 빈도가 낮은 데이터만 제거
  • LRU 전략 적용 방법

캐시 무효화 및 일관성 전략

  • 캐시 무효화 및 일관성 관리의 필요성
    • 캐시 무효화
      • 캐시 데이터가 유효하지 않게 되면 적절한 시점에 캐시를 제거
      • 수동 무효화 : 개발자가 명시적으로 캐시를 무효화
      • 자동 무효화 : TTL 설정을 통해 자동으로 캐시 무효화 
    • 일관성 관리
      • 캐시와 원본 데이터의 일치를 유지
    • 문제 발생
      • 캐시된 데이터와 원본 데이터의 불일치 시 잘못된 정보 반환 가능
  • 캐시 무효화 전략
    • Write-through
      • 데이터 업데이트 시 캐시와 DB를 동시에 갱신
      • 실시간 트랜잭션 시스템에서 캐시와 DB를 동기화
    • Write-around
      • 데이터 업데이트 시 DB만 갱신, 캐시는 무효화 
      • 주로 읽기 작업이 많은 경우 사용
    • Write-back 
      • 캐시를 먼저 업데이트하고 일정 시간 후 DB를 갱신
      • 성능을 중시하는 시스템에서 캐시를 먼저 갱신하고, 이후에 비동기로 DB를 업데이트하여 쓰기 성능 최적화
  • @CacheEvict로 캐시 무효화
    • 캐시된 데이터를 명시적으로 삭제
    • allEntries 옵션 : 캐시 내의 모든 항목을 무효화
    • beforeInvocation 옵션 : 메서드 실행 전 무효화할지 여부 설정

  • 캐시와 원본 데이터 간 일관성 관리 방법
    • TTL 기반 자동 갱신
      • TTL 설정을 통해 주기적으로 캐시를 갱신
    • 데이터 변경 이벤트 기반 갱신
      • 데이터가 변경되면 캐시도 즉시 갱신
    • 주기적인 캐시 갱신
      • 스케줄러를 사용해 정기적으로 캐시를 업데이트
  • Spring Boot에서 캐시 일관성 관리
    • @CachePut : 메서드 실행 시 캐시를 자동 갱신 
    • 즉시 일관성을 제공하며, 데이터 수정 후 캐시가 자동으로 갱신됨
    • @Cacheable과 함께 사용하여 데이터 갱신과 읽기를 분리 가능

API 및 DB 쿼리 캐싱을 통한 성능 최적화

  • Spring Boot에서 API 캐싱 적용 방법
    • @Cacheable 애노테이션을 사용하여 API 응답 캐싱 
    • 캐시 적용 시 key 설정을 통해 특정 요청에 대해 캐시 관리
    • 캐시된 데이터는 TTL 설정을 통해 일정 시간 후 만료 가능

  • Spring Boot에서 DB 쿼리 캐싱 적용 방법
    • Spring Data JPA에서 쿼리 캐싱 적용
    • @Cacheable을 사용하여 자주 사용하는 쿼리 캐시
    • 캐시된 쿼리 결과는 TTL 또는 갱신 시점에 따라 무효화

 

Comments