JPA의 1차캐시와 2차캐시.. 책이나 강의등을 통해 JPA를 공부하긴 하였으나,, 회사 프로젝트가 대부분 mybatis로 되어있기에 기억이 희미해져 간다.. 기억을 되살리고자 글로 정리하고자 한다.
일단, 네이버검색을 통해 캐시에 대한 사전적 정의를 본다.
캐시 (cache)
중앙 처리 장치의 성능 향상을 위해 사용하는 보조 기억 장치. 저용량, 고속의 반도체 기억 장치이다.
음.. 약간 하드웨어적 정의가 사전적 정의로 되어있다. cpu와 보조기억장치 사이에서 성능향상을 위해 두는 중간 레이어정도로 기술하고 있다.
그런데! 프로그래밍 용어와 관련된 사전적 정의도 있는데, JPA에서 말하는 캐시는 아래의 사전적 정의가 맞아보인다.
캐시(Cache)
캐시란 컴퓨터 프로그래밍 용어로, 자주 사용하는 데이터나 값을 미리 복사해 놓는 임시 장소를 가리킨다. 사용자가 직접 수동으로 삭제해야 한다는 점 등으로 쿠키(정보 저장을 위해 사용되는 작은 기록정보 파일)와는 차별화된다.
즉, 캐시란 위의 말대로 자주 사용하는 데이터나 값을 미리 복사해놓는 임시저장소이다.
그리고 JPA에서는 성능향상등의 이점을 취하기 위해 엔티티값을 캐시에 저장하고 있다.
(여기서 말하는 엔티티란 DB 테이블과 매핑된 객체로 이해하면 된다)
가령, Id가 1인 데이터를 DB로 부터 조회를 한다고하면 아래와 같은 과정이 이루어 진다.
2차캐시
2차캐시는 애플리케이션 범위의 캐시로 공유캐시라고 한다. 애플리케이션 범위라 함은 애플리케이션이 종료되기 전까지 캐시가 유지된다는 말이다. 2차캐시는 DB와 1차캐시 사이에 있다.
1차캐시가 하는 기능을 2차 캐시에서 뭔가 한번더 하는 느낌인데 굳이 왜 DB와 1차캐시 사이에 2차캐시가 존재해야 하는 것일까?
이에대한 질문을 생성형 AI에게 날려보았다.
JPA에서 1차 캐시는 영속성 컨텍스트에만 존재하는 캐시입니다. 영속성 컨텍스트는 트랜잭션 단위로 생성되며, 트랜잭션이 종료되면 함께 종료됩니다. 따라서 1차 캐시는 애플리케이션 전체에서 공유되지 않습니다.
2차 캐시는 애플리케이션 전체에서 공유되는 캐시입니다. 2차 캐시는 엔티티 매니저에 의해 관리되며, 애플리케이션을 종료할 때까지 유지됩니다. 2차 캐시는 1차 캐시와 동일한 기능을 제공하지만, 애플리케이션 전체에서 공유되기 때문에 성능 향상 효과가 더 큽니다.
예를 들어, 특정 엔티티를 조회하는 요청이 여러 번 들어온다면, 1차 캐시는 해당 엔티티를 한 번만 조회하고, 이후 요청에는 1차 캐시에서 엔티티를 제공합니다. 2차 캐시는 애플리케이션 전체에서 공유되기 때문에, 해당 엔티티를 조회하는 모든 요청에 대해 2차 캐시에서 엔티티를 제공할 수 있습니다.
따라서 2차 캐시를 사용하면 성능을 향상시킬 수 있습니다.이 외에도 2차 캐시는 다음과 같은 장점이 있습니다.
- 데이터베이스 접근 횟수를 줄일 수 있습니다.
- 데이터베이스 부하를 줄일 수 있습니다.
- 애플리케이션 성능을 향상시킬 수 있습니다.
- 캐시 동기화를 통해 데이터 일관성을 유지할 수 있습니다.
따라서 JPA에서 2차 캐시는 성능 향상과 데이터 일관성 유지를 위해 중요한 역할을 합니다.
아, 1차캐시는 트랜잭션 단위로 생성되었다 사라지므로, 2차캐시가 없을 경우 DB접근회수가 많아질 것이기 때문에 성능저하가
올 수 있으므로 이를 방지하기 위해 2차캐시를 두는 것으로 이해하면 될 것 같다.
단, 2차캐시는 기본적으로 활성화 되는것은 아닌것 같다. 아래와 같은 단점도 있기 때문에 선택사항으로 사용하게 한 듯..
-
캐시 메모리 사용량이 증가한다. (너무 많은 데이터를 2차캐싱하면 안될듯)
-
캐시 동기화로 인한 성능 저하가 발생할 수 있다. (데이터의 변화가 적을경우사용하면 좋을듯)
각설하고! 2차캐시를 사용하기 위해서는 아래와같은 작업이 필요하다.
// build.gradle에 ehcache 사용을 위해 의존성 추가
implementation 'org.hibernate:hibernate-ehcache:5.2.2.Final'
// application.yml에 아래의 설정 추가 hibernate.cache.use_second_level_cache=true hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory
그리고 아래와같이 @Cacheable 어노테이션을 붙이면 해당 엔티티는 2차캐시에 저장되어 관리되게 된다.
'IT > JPA' 카테고리의 다른 글
[JPA] Query DSL 사용해보기 (0) | 2021.08.29 |
---|---|
H2 에러 (Database "/Users/juhyeontae/test" not found, either pre-create it or allow remote database creation (not recommended in secure environments) (0) | 2021.08.03 |
JPA 개발환경 구성 (0) | 2019.12.14 |