티스토리 뷰

개요

  • Spring Boot, JPA 기반 프로젝트에서 Hibernate L2 Cache를 활성화하는 방법을 간단히 정리하였다.

Hibernate L1 Cache 특징

  • L1 캐시는 하나의 Hibernate Session 안에서만 유효하다. 다른 세션끼리는 캐시를 공유하지 않는다. (L2 캐시 전체 세션끼리 같은 캐시를 공유한다.)
  • L1 캐시는 기본 설정이 활성화되어 있으며 비활성화가 불가능하다. (L2 캐시는 기본 설정이 비활성화되어 있으며 활성화가 가능하다.)

Hibernate L2 Cache 특징

  • 현재 애플리케이션에 존재하는 전체 Hibernate Session이 동일한 캐시를 공유한다. (SessionFactory를 통해 가능하다.)
  • ID로 조회한 엔티티의 조회 결과만 캐시에 저장된다. 이를 통해 Read-Write 데이터베이스 인스턴스에 가해지는 부하를 줄일 수 있다.
  • Criteria, Projection, HQL을 이용한 조회 결과는 캐시에 저장되지 않는다.
  • 캐시된 엔티티의 변경점이 발생할 경우 소프트 잠금이 작동하여 오래된 캐시를 반환하지 않도록 보장한다. (Hibernate Session이 아닌 다른 방법으로 테이블의 변경점이 발생하면 보장하지 않는다.)

Hibernate Query Cache 특징

  • 쿼리 캐시를 활성화하면 엔티티에 대해 JPQL, Criteria API로 제작된 리파지터리 조회 메써드 실행시에도 L2 캐시에 저장된 캐시를 사용할 수 있다. (Native Query는 지원하지 않는다.)
  • L2 캐시만 사용할 때는 리파지터리의 findById()을 호출시에만 캐시를 사용할 수 있지만, 원하는 모든 findXXX() 호출 시점에 캐시를 사용할 수 있다.

pom.xml

  • 프로젝트 루트의 /pom.xml 파일에 아래 내용을 추가한다.
<project>
  <dependencies>
    <!-- 아래에 추가 -->
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-jcache</artifactId>
    </dependency>
  </dependencies>
</project>

application.yml

  • 환경 변수에 아래 내용을 추가해야 Hibernate Second-Level Cache가 작동한다.
spring:
  jpa:
    properties:
      # Hibernate L2 캐시를 활성화
      hibernate.cache.use_second_level_cache: true
      javax.persistence.sharedCache.mode: ENABLE_SELECTIVE
      # Hibernate 쿼리 캐시를 활성화
      hibernate.cache.use_query_cache: true
      hibernate.generate_statistics: true
      # Hibernate L2 캐시 매니저로 Infinispan을 지정
      hibernate.cache.region.factory_class: infinispan
      # Hibernate L2 캐시 매니저가 정의된 환경 설정 파일 지정
      hibernate.cache.infinispan.cfg: config/infinispan/infinispan-configs-prod.xml
      hibernate.cache.default_cache_concurrency_strategy: read-write
      hibernate:cache:use_minimal_puts: false

@Entity 클래스

  • 2차 캐시를 적용할 엔티티에 아래와 같이 클래스 레벨에 @javax.persistence.Cacheable@org.hibernate.annotations.Cache를 명시하면 해당 엔티티는 2차 캐시가 활성화된다.
import org.hibernate.annotations.CacheConcurrencyStrategy
import org.hibernate.annotations.Type
import javax.persistence.*

@Entity
@Table(name = "foobar")
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
data class Foobar {}

@Repository 클래스

  • 캐싱을 원하는 리파지터리 메써드에 @org.springframework.data.jpa.repository.QueryHints를 명시하면 Query Cache가 활성화되어 메써드 조회 시점에 해당 엔티티의 L2 캐시를 조회하고, 캐시가 존재할 경우 값을 응답하고 존재하지 않으면 데이터베이스를 조회한다.
import org.springframework.data.jpa.repository.QueryHints
import javax.persistence.QueryHint
import static org.hibernate.jpa.QueryHints.HINT_CACHEABLE

@Repository
class FoobarRepository {

    // Query Cache를 적용할 조회 메써드에 @QueryHints 명시
    @QueryHints(@QueryHint(name = HINT_CACHEABLE, value = "true"))
    findFirstByNameAndCategory(name: String, category: FooCategory): List<Foobar> 
}

참고 글

댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/03   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
글 보관함