[System Design] Caching Strategies and How to Choose the Right One

Caching Strategies and How to Choose the Right One

캐시를 올바르게 사용하면 응답 시간을 단축하고 데이터베이스 부하를 줄이며 비용 절감을 할 수 있다. 캐싱 전략은 데이터와 데이터 액세스 패턴에 따라 달라진다.

Cache-Aside

  • 캐시는 측면에 위치해 애플리케이션은 캐시 및 데이터베이스와 직접 통신
  • 캐시와 기본 데이터베이스 사이에는 연결이 없음
  • 캐시와 데이터베이에 대한 모든 작업은 애플리케이션이 처리

  1. 애플리케이션이 먼저 캐시를 확인
  2. 캐시가 데이터에서 발견되면 캐시 히트가 발생하고 클라이언트로 반환
  3. 캐시가 데이터에서 발견되지 못하면 캐시 미스가 발생. 애플리케이션은 데이터베이스를 쿼리하여 읽은 후 클라이언트에 반환하고 데이터를 캐시에 저장하여 이후 캐시 히트가 발생하도록 조치

Use Cases, Pros and Cons

Cache Aside는 범용적이고 읽기 작업이 많은 경우 적합하다. 이 전략을 사용하는 시스템은 캐시 장에에 대한 복원력이 뛰어나다. 캐시 클러스터가 다운되더라도 시스템은 데이터베이스를 통해 계속 동작한다. 다만 최대 부하중에 캐시가 다운되는 경우는 제외한다.

캐시의 모델이 데이터베이스 모델과 다를수 있다. 예를 들어 여러 쿼리의 결과로 생성된 응답을 특정 요청 ID에 대해 저장할 수 있다.

Cache-Aside가 사용될때 가장 일반적인 쓰기 전략은 데이터베이스에 직접 데이터를 쓰는 것이다. 이 경우 데이터 불일치가 발생할 수 있는데 이는 TTL을 통해 해결한다.

Read-Through Cache

  • 읽기 캐시는 데이터베이스와 인라인으로 배치
  • 캐시가 누락되면 데이터베이스에서 누락된 데이터를 로드하고 캐시를 채운 다음 애플리케이션으로 반환
  • Cache-Aside와 Read-Through 전략 모두 데이터를 처음 읽을때만 느리게 로드 됨

Use Cases, Pros and Cons

Cache-Aside와 유사한 면이 있지만 최소 두 가지 차이점이 있다. Cache-Aside는 애플리케이션이 데이터베이스에서 데이터를 가져와 캐시를 채우는 역할을 담당한다. Read-Through에서 이 작업은 일반적으로 라이브러리 또는 독립형 캐시 공급자가 지원한다. 그래서 Cache-Aside와 달리 Read-Through는 캐시와 데이터베이스의 데이터 모델이 다를 수 없다.

Read-Through 전략은 동일한 데이터를 여러 번 요청하는 읽기 부하가 많은 작업에 적합하다. 단점은 데이터를 처음 요청할 때 항상 캐시 미스가 발생하고 캐시 데이터를 로드하는데 추가 비용이 든다. 이는 개발자가 수동으로 캐시를 warm up하면서 해결할 수 있다. 데이터베이스와 캐시 데이터가 불일치하는 경우도 발생할 수 있다. 이 문제는 Write-Through 전략이 도움될 수 있다.

Write-Through Cache

  • 데이터가 먼저 캐시에 쓰인 다음 데이터베이스에 기록 됨
  • 캐시는 데이터베이스와 인라인으로 배치
  • 쓰기는 항상 캐시를 통해 주 데이터베이스로 이동하게 되어 캐시와 데이터베이스간 일관성을 유지시킴

  1. 애플리케이션에 캐시를 직접 씀
  2. 캐시는 메인 데이터베이스의 데이터를 업데이트 함. 쓰기가 완료되면 캐시와 데이터베이스는 모두 동일한 값을 가지며 캐시는 항상 일관성을 유지함

Use Cases, Pros and Cons

Write-Through 그 자체로는 데이터가 캐시에 먼저 쓰인 다음 메인 데이터베이스에 쓰여지기 때문에 쓰기 지연 시간이 추가로 발생한다. 하지만 Read-Through와 함께 사용되면 Read-Through의 이점과 함께 데이터 일관성이 보장되 캐시를 무효화하지 않아도 된다.

Write-Around

  • 데이터는 데이터베이스에 직접 쓰여지고 읽은 데이터만 캐시로 이동

Use Cases, Pros and Cons

이 전략은 Read-Through나 Cache-Aside와 함께 쓰일 수 있다. 데이터를 한 번만 쓰고 읽는 빈도가 낮거나 아예 읽지 않는 경우 우수한 성능을 보인다. 예를 들어 실시간 로그나 채팅방 메세지가 해당된다.

Write-Back or Write-Behind

  • 애플리케이션은 데이터를 저장하는 캐시에 데이터를 쓰고 즉시 응답함
  • 나중에 캐시가 데이터를 데이터베이스에 다시 씀

이 전략은 Write-Through와 유사해보이지만 매우 중요한 차이점이 있다. Write-Through는 동기식으로 캐시에 쓰인 데이터가 메인 데이터베이스에 업데이트 되지만 Write-Back에서는 캐시에 기록된 데이터가 메인 데이터베이스에 비동기적으로 업데이트 된다. 애플리케이션 관점에서만 보면 응답을 반환하기 전에 캐시만 업데이트하면 되므로 Write-Back에 대한 쓰기가 더 빠르다.

Use Cases, Pros and Cons

Write-Back 전략은 쓰기 성능을 향상시켜 쓰기 작업이 많은 경우에 적합하다. Write-Through와 함께 사용되면 가장 최근에 업데이트 되고 액세스된 데이터를 항상 캐시에서 사용할 수 있는 혼합 워크로드에 적합하다.

데이터베이스 장애에 대한 복원력이 뛰어나 약간의 데이터베이스 다운타임을 견딜 수 있다. 또한 배치 프로세싱이나 병합이 지원되는 경우 데이터베이스에 대한 전체 쓰기를 줄일 수 있다. 일부 케이스의 경우 피크 부하에 스파이크 흡수를 위해 Cache-Aside와 Write-Back 모두에 Redis를 사용하기도 한다. 가장 큰 단점은 캐시 장애가 발생하면 데이터에 영구적 손실이 발생할 수 있는 점이다.

대부분의 관계형 데이터베이스 스토리지 엔진은 내부에 Write-Back 캐시가 활성화 되어있다. 쿼리는 먼저 메모리에 기록된 후 최종적으로 디스크에 플러시된다.

Author: Song Hayoung
Link: https://songhayoung.github.io/2023/03/08/System%20Design/etc/caching-strategies-and-how-to-choose-the-right-one/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.