JAVA/Application

Spring의 캐싱 기능

히어로맛쿠키 2023. 8. 27. 21:54

스프링 캐싱 Intro

웹애플리케이션의 대표적 성능 문제는 RDB에서 대량의 데이터를 자주 가져오는 상황이라고  한다. 

그런 상황을 최대한 줄이려고 노력해보자!

잘 변경되지 않는 데이터라면 캐싱해두면 되겠다.

스프링 3.1 이상부터는 데이터 캐시 기능을 제공한다. 즉 캐시의 추상화를 제공한다.

스프링은 Cache & CacheManager 인터페이스를 제공하고 있다. 개발자가 실제 사용할 Cache Provider를 적용할 수 있도록 Service Provider Interface (SPI)를 제공하는 개념이다. 스프링 4.1부터는 어노테이션도 제공한다. 

 

(들어가며..)

캐싱 개념은 운영체제 공부할 때 배우기만 했고 이렇게 스프링에서 사용할 수 있다는 생각은 해보지도 않았다. 오늘 일과가 끝나고 지하철에서 가볍게 스프링 책을 읽다가 스프링의 캐싱 기능을 알게되었다. 그 때 느낀것은 이제 정말 웹개발을 열심히 해보고 싶다는 생각이었다. 여러 문제의 필요성을 느끼고 다양한 솔루션을 찾아 적용해보고 싶다는 그런 생각 말이다.


스프링의 캐싱

어떤 데이터를 RDB에서 가져오는 메서드인 methodA()가 호출될 때 10초가 걸린다고 해보자. 매번 10초를 소요할 것인가? 아니다. 데이터를 캐싱해두자. 

 

 

캐싱하기 위한 Bean 정의 파일

 

캐시를 사용하기 위해서 설정이 필요하다.

설정파일이 xml 이라면 다음과 같이 정의할 수 있다. 

- schema & schema Location 설정

- cache:annotation-driven 어노테이션 사용 설정

- CacheManager 설정 (스프링의 SimpleCacheManager으로 예시)

- 캐시를 작성할 ConcurrentMapCacheFactoryBean 

 

아 이런 설정들을 하는구나 정도 알아두고 넘어간다.

 

 


메서드에 @Cacheable을 추가하면 캐싱 가능

캐시 어노테이션을 설정하여 캐싱 설정을 간단히 할 수 있다. @Cacheable을 설정할 때 value를 지정한다. value는 캐시의 이름이다. key도 지정한다. 메서드의 첫번째 인수를 key로 사용하려면 생략가능하다.

 

@Cacheable(value="area")

public Product findProduct(String name){

    ...

}

 

이런 경우에는 "area"라는 캐시 영역에 캐싱되는 값을 보관한다.

캐싱되는 값은 Product의 name이다. key를 지정하지는 않았지만, 메서드의 첫번째 인자가 key로 된다.

 

 

 

 


이미 캐싱된 값 수정 필요성 (@CacheEvict)

 

데이터 값을 변경해도 이미 캐싱된 값이 삭제되지 않는다면 계속 동일한 값을 캐시에서 가져올 것이다. 그럼 안되기 때문에, 값이 변경되면 캐시에도 반영이 되도록 해야 한다. 그것은 @CacheEvict 어노테이션을 사용하면 해결된다.

 

@CacheEvict(value="area", key="#product.name")

public void addProduct(Product product){

   storage.put(product.getName(), product);

}

 

이런 식이다.

value는 아까와 동일하게, 캐시 영역의 이름을 넣는다. "area"라는 캐시 영역을 지정하였다.

key에는 캐시를 삭제하는 조건이다. #product.name이 지정되었는데, product의 name값이 초기화 대상이다.

만약 name만이 아니고 캐싱된 데이터 전체를 삭제하고 싶으면, @CacheEvict(value="area", allEntries=true) 로 설정하면 된다. 캐시 관련 어노테이션은 이외에도 다양하다. 나중에 캐싱을 적용할 때 공부해볼 수 있겠다.

 

이렇게 값 변경할 때 캐시가 초기화되면, 다시 캐싱이 일어난다. 변경 값이 캐싱되면 아까와 동일하게 그냥 그 변경된 값을 캐시에서 읽어오는 개념이다.

 

 


캐싱 응용

위에는 스프링 캐싱 기능을 인지하기 위한 기본적인 내용이었다.

그러나 캐시도 여러 상황을 고려하여 설계해야 한다. 

캐시를 여러 서버가 공유할 수도 있고, 캐시를 스토리지에 저장 및 확장할 수도 있다. 사실 아직 감은 오지 않지만, 책에 언급된 내용을 정리해보고자 한다. 

 

웹 애플리케이션의 세션 저장 방식으로 캐시를 적용할 수 있다. 

그러면 캐시를 서로 다른 웹 어플리케이션이 공유하도록 할 수도 있다.

 

Spring Data 프로젝트 중 Spring Data Redis, Spring Data GemFire가 있다고 한다. Redis나 GemFire을 캐시의 기반으로 사용 수 있다 한다. 예를 들어 Redis를 이용한다면 코드를 변경하지 않고 Redis 설정만 해두면 Redis 캐시를 사용할 수 있다고 한다.

 

예전에 HSJ강사님이 데이터베이스 기술같은거 관심있으면 Redis같은거 알아두면 좋다고 하셨던 것 같다. (음.. 단순 회상입니다)

 

 


스프링 캐싱 예제 검색해보다가 찾은 글!

책의 설명 맥락이랑 비슷해서 첨부한다.

신입사원들을 위해 작성하신 글이라고 한다.

멋지시다!!

 

https://jojoldu.tistory.com/57

 

SpringBoot + Ehcache 기본 예제 및 소개

팀내 신입사원들이 입사하게 되어 간단하게나마 참고할 수 있도록 Spring Cache에 대해 샘플예제와 소개를 정리하게 되었다. 아주 간단한 예제이기도 하고, 웬만한 경력 웹 개발자분들은 다 아는

jojoldu.tistory.com