yata 프로젝트를 진행하며,
프로젝트 내 테이블과 연관관계가 많아지면서 데이터를 조회/검증 하는 데 
많은 쿼리가 나가게 되었다.
또, 이러한 쿼리들이 많아지면서 데이터 베이스 서버의 네트워크 트래픽 증가의 문제가 있었습니다.

따라서 2차캐시를 도입하였다.

 

 

1차캐시와 2차캐시

 

네트워크를 통해 DB에 접근하는 시간 비용은 애플리케이션 서버에서 내부 메모리에 접근하는 비용보다 훨씬 비싸다.
따라서 조회한 데이터를 메모리에 캐시해서 DB접근횟수를 줄이는 것이 효율적이다.

 

영속성 컨텍스트 내부에는 엔티티를 보관하는 저장소가 있는데 이것을 1차캐시라 한다.
그러나 일반적 웹 애플리케이션 환경은 트랜잭션을 시작하고 종료할 때까지만 1차 캐시가 유효하다.
따라서 애플리케이션 전체로 보면 DB접근 횟수를 획기적으로 줄이지는 못한다.

 

하이버네이트를 포함한 대부분의 JPA구현체들은 애플리케이션 범위의 캐시를 지원하는데, 이것을 공유캐시, 또는 2차캐시라 한다.

 

 

 

🔎1차캐시
영속성 컨텍스트 내부에 있다. 엔티티 매니저로 조회하거나 변경하는 모든 엔티티는 1차캐시에 저장된다.
트랜잭션을 커밋하거나 플러시를 호출하면, 1차캐시에 있는 엔티티의 변경 내역을 데이터베이스에 동기화한다.

JPA를 Spring Framework같은 컨테이너 위에서 실행하면 트랜잭션을 시작할 때, 영속성 컨텍스트를 생성하고, 트랜잭션을 종료할 때 영속성 컨텍스트도 종료한다. 1차캐시는 끄고 켤 수 있는 옵션이 아니다. 영속성 컨텍스트 자체가 사실상 1차캐시다.

🔎2차캐시
애플리케이션에서 공유하는 캐시를 JPA는 공유캐시라 하는데, 일반적으로 2차캐시라 부른다.
2차캐시를 적용하면 엔티티 매니저를 통해데이터를 조회할 때 우선 2차 캐시에서 찾고, 없으면 DB에서 찾는다. 따라서 적절히 활용하면 DB조회 횟수를 획기적으로 줄일 수 있다. 

 

 

yata 프로젝트에는 하이버네이트와 EHCACHE를 사용해서 2차캐시를 적용하였다.

 

하이버네이트가 지원하는 캐시는 크게 3가지가 있다.

 

엔티티 캐시 
엔티티 단위로 캐시한다. 식별자로 엔티티를 조회하거나, 컬렉션이 아닌 연관된 엔티티를 로딩할 때 사용한다.

 

컬렉션 캐시
엔티티와 연관된 컬렉션을 캐시한다. 컬렉션이 엔티티를 담고 있으면 식별자 값만 캐시한다.

 

쿼리 캐시
쿼리와 파라미터 정보를 키로 사용해서 캐시한다. 결과가 엔티티면 식별자 값만 캐시한다.

 

JPA표준에서는 엔티티 캐시만 정의되어 있다.

 

 

 

💡프로젝트 적용코드

build.gradle에 cache라이브러리 추가

application.yml파일 설정!

 

 

 

ecache.xml파일 추가!


자세한 설정 방법은 다음 포스팅에 정리해놓았다.
https://develoyummer.tistory.com/88

 

ehcache의 속성

💡ehcache의 주요 특징 경량의 빠른 캐시 엔진 확장(scable) - 메모리 & 디스크 저장 지원, 멀티 CPU의 동시 접근에 튜닝 분산 지원 - 동기/비동기 복사, 피어(peer) 자동 발견 높은 품질 - Hibernate, Confluenc

develoyummer.tistory.com

 

 

Application 범위에 @EnableCaching 애너테이션 추가

캐시를 사용할 엔티티 객체 위에 에너테이션 붙여줌

캐시의 저장/조회를 위한 @Cacheable에너테이션을 붙여주었고,
동시성 전략으로는 READ_WRITE를 설정해주었다.

💡에너테이션의 종류
@Cacheable
캐시의 저장/조회

@CachePut
캐시의 저장

@CacheEvict
캐시 제거
💡동시성 전략!

READ_ONLY 
자주 조회하고 수정 작업을 하지 않는 데이터에 적합합니다.

READ_WRITE 
조회 및 수정 작업을 하는 데이터에 적합합니다. Phantom Read 가 발생할 수 있으므로 SERIALIZABLE 격리 수준에서는 사용할 수 없습니다.

NONSTRICT_READ_WRITE
거의 수정 작업을 하지 않는 데이터에 적합합니다.

⏱️도입전후 시간비교

 

 

'Spring' 카테고리의 다른 글

Spring batch  (0) 2023.06.05
ehcache의 속성  (2) 2023.06.02
QueryDsl이란? 사용법+ 프젝 코드에 적용하기  (0) 2023.05.31
[프로젝트] N+1 문제와 QueryDsl  (0) 2023.05.31
[JPA] Entity 클래스에서 Setter 메소드의 사용  (0) 2023.04.09
복사했습니다!