캐싱 설정

hibernate.cfg.xml 파일의 캐싱 설정으로 돌아가 보겠습니다.

<property name="hibernate.cache.provider_class" value="net.sf.ehcache.hibernate.SingletEhCacheProvider"/>
<property name="hibernate.cache.use_second_level_cache" value="true"/>
<property name="hibernate.cache.use_query_cache" value="true"/>

첫 번째 줄에 주의하십시오. 캐싱 엔진 클래스의 이름이 포함되어 있습니다. Hibernate는 실제로 내부적으로 캐싱을 구현하지 않고, 대신 자신만의 캐싱 엔진을 구현할 수 있는 일련의 인터페이스를 제공합니다.

널리 사용되는 구현은 다음과 같습니다.

  • EHCache
  • OS캐시
  • 스웜캐시
  • JBoss 트리캐시

EHCache

클러스터 캐싱은 물론 메모리나 디스크에 캐싱할 수 있으며 Hibernate 쿼리 결과의 선택적 캐시도 지원합니다.

OS캐시

풍부한 만료 정책 세트 및 쿼리 캐시 지원을 통해 동일한 JVM에서 메모리 및 디스크 캐싱을 지원합니다.

스웜캐시

JGroups 기반 클러스터 캐시. 클러스터된 무효화를 사용하지만 Hibernate 쿼리 캐시를 지원하지 않습니다.

JBoss 캐시

JGroups 멀티캐스트 라이브러리를 기반으로 하는 완전한 트랜잭션 복제 클러스터 캐시입니다. 복제 또는 무효화, 동기식 또는 비동기식 통신, 낙관적 및 비관적 잠금을 지원합니다. Hibernate 쿼리 캐시가 지원됩니다.

이러한 엔진은 모든 병렬 액세스 전략을 지원하지 않습니다. 실제 상황은 아래 표에 설명되어 있습니다.

전략/제공자 읽기 전용 엄격하지 않은 읽기-쓰기 읽기-쓰기 트랜잭션
EHCache 엑스 엑스 엑스
OS캐시 엑스 엑스 엑스
스웜캐시 엑스 엑스
JBoss 캐시 엑스 엑스

EHCache 구성 예시

EHCache 엔진에는 ehcache.xml이라는 자체 구성 파일이 있습니다. 해당 파일의 대략적인 내용:

<diskStore path="java.io.tmpdir"/>

<defaultCache
    maxElementsInMemory = "1000"
    eternal = "false"
    timeToIdleSeconds = "120"
    timeToLiveSeconds = "120"
    overflowToDisk = "true"
/>

<cache name = "Employee"
    maxElementsInMemory = "500"
    eternal = "true"
    timeToIdleSeconds = "0"
    timeToLiveSeconds = "0"
    overflowToDisk = "false"
/>

여기에서 일반적으로 그리고 각 엔터티에 대해 개별적으로 캐싱 설정을 구성할 수 있습니다. 자세한 내용은 공식 문서를 참조하세요 .

캐싱 통계 분석

캐싱 메커니즘이 얼마나 잘 구성되어 있는지 확인해야 할 수도 있습니다. Hibernate는 이를 위해 특별히 특별한 Statistics 객체를 제공합니다.

예:

Statistics statistics = session.getSessionFactory().getStatistics();
CacheRegionStatistics cacheStatistics = statistics.getDomainRegionStatistics(“com.codegym.employee”);

long hitCount = cacheStatistics.getHitCount();
long missCount = cacheStatistics.getMissCount();
double hitRatio = (double) hitCount / (hitCount + missCount);

표준 캐싱 솔루션이 고갈되고 이를 수동으로 개선해야 하는 데 몇 년이 더 걸릴 것이기 때문에 이에 대해 자세히 설명하지 않겠습니다. 그건 그렇고, 이 댓글은 유사한 사례에서 추출되었을 수 있습니다.

// Dear programmer:
// When you're done "optimizing" this routine
// and realize how big of a mistake it was to do this,
// please increment the counter at the bottom as a warning
// for the next guy:
// number_of_hours_spent_here = 42