Yebali

Spring JPA의 Cache 본문

Spring

Spring JPA의 Cache

예발이 2021. 10. 31. 23:37

Cache란?

일반적으로 Cache는 자주 사용하는 데이터나 값을 복사해 놓는 임시 저장소를 말한다.

흔히 우리가 사용하는 폰-노이만 구조의 PC에서 cache는 CPU 내부에 있는 수 KB, MB 내외의 작은 저장 공간이 Cache이다. (Register, L1/L2 Cache, RAM 등)

Cache는 저장 공간이 작고 비용이 비싼 대신 빠른 성능을 제공한다.

Cache의 장점

다양한 장점이 있지만 가장 큰 장점은 빠르다는 것이다.

예를 들어 집에서 삼겹살을 먹으려고 할 때, 상추를 텃밭에서 뜯어오는 것과 마트에 가서 사 오는 것 중 어느 것이 빠르겠는가?
→ 당연히 텃밭에서 뜯어오는게 빠르다.

CPU가 연산을 하기 위해서는 연산에 필요한 값들이 필요하다.
그렇다면 이 값들을 어딘가로부터 불러와야 하는데 RAM에서 불러오는 것과 HDD에서 불러오는 것 중 어느 것이 빠를까?

당연히 RAM에서 불러오는게 빠르다.

Spring JPA에서의 Caching이란?

서버가 동작할 때 오래걸리는 대표적인 작업은 무엇일까?

바로 DB에 접근하는 작업이다.
DB와의 커넥션을 가져와야 하고, DB서버는 데이터를 읽어서 값을 반환하는 등의 과정을 거쳐야 한다.
또, 보통 커넥션 풀에서 커넥션의 갯수는 한정적이기 때문에 커넥션을 오랫동안 가지고 있을 수도 없다.

그렇게 때문에 Spring JPA에서 Caching의 목적은 DB에 최소한으로 접근하는 것이다.

원리

Spring JPA에서 Cache역시 일반적인 Cache와 동일한 원리로 동작한다.

한 번 불러왔던 값(Entity)을 저장해두었다가 동일한 값(Entity)을 요청하면 DB에 접근하지 않고 가지고 있는 값을 주는 것이다.

JPA의 Cache는 1차, 2차로 나누어진다. 알아보자

1차 Cache

JPA의 1차 Cache는 영속성 컨텍스트가 담당한다.

만약 ‘member1’이라는 Id로 member 엔티티를 찾는다고 가정하자.
처음 그 값을 찾을 때에는 DB에서 값을 요청하여 그 값을 영속성 컨텍스트 내부의 엔티티를 보관하는 저장소에 저장하고 member 엔티티를 반환한다.

그리고 다시 ‘member1’이라는 Id로 member 엔티티를 다시 찾으면 어떻게 될까?

영속성 컨텍스트는 이미 그 값을 가지고 있기 때문에 DB에 요청하지 않고 보관하고 있는 값을 반환한다.

특징

  1. Cache에서 찾은 엔티티에 대해서는 객체 동일성을 보장한다.(==)
    • == 연산은 참조 위치를 비교하는데 모두 영속성 컨텍스트에 보관된 엔티티를 참조하기 때문.
  2. 1차 캐시는 트랜잭션을 시작하고 종료할 때까지만 유효하다.
  3. @Id로 구분하기 때문에 Id로 조회했을 때에만 동작한다.

 

2차 Cache

애플리케이션 전체로 보면 1차 Cache만으로는 DB접근 횟수를 획기적으로 줄이지는 못한다.

그래서 대부분의 JPA 구현체들은 애플리케이션 범위의 캐시를 지원하는데 이것을 공유 캐시 또는 2차 Cache라고 한다.

1차 Cache에서 원하는 값을 찾지 못했을 때 추가로 2차 Cache에서 찾는다.
2차 Cache에 값이 있으면 그 값의 복사본을 만들어서 반환하고 없다면 DB에 요청한다.

특징

  1. 2차 Cache는 조회한 객체를 그대로 반환 하는 것이 아니라 복사본을 만들어서 반환한다.
    • 캐시 한 객체를 그대로 반환했을 때 여러 곳에서 같은 객체를 동시에 수정하는 등의 동시성 문제가 발생할 수 있기 때문에 복사본을 만들어서 반환함.
  2. 2차 Cache는 DB의 PK를 기준으로 캐시하지만 영속성 컨텍스트가 다르면 객체 동일성 (a==b)를 보장하지 않는다.