Cache Strategy — 1

jrun
Research Team — DAWN
4 min readApr 4, 2022

--

개인 프로젝트를 진행하던 중, 여러 게시물에 관심 목록 (좋아요 기능)을 추가하게 되었습니다. 그런데 이런 기능들은 보통 별 생각없이 자주, 많이 누르게 되는 기능이고 1회당 전송되는 데이터의 양이 매우 적습니다. (보통 articleId, userId) 인스타그램만 봐도 다들 무념무상으로 좋아요 토도도도독 누르고 내려가잖아요?

때마침 데이터베이스 시스템 강의에서 I/O의 비용에 대해 배우고 있었고 이런 경우 데이터 양에 비해 너무 많은 Database I/O를 초래해 성능에 악영향이 생길 것이라 생각이 되었습니다. 어떻게 해결할까 고민을 하다가 캐시를 이용해보기로 했습니다.

먼저 캐시에 어떤 전략이 있는지 알아보겠습니다.

Cache-Aside

  1. 먼저 캐시를 확인해 데이터가 있을 경우 (Cache Hit) 캐시에서 데이터를 가져옵니다.
  2. 데이터가 없는 경우 (Cache Miss) 데이터베이스에서 애플리케이션 서버로 가져온 뒤 캐시에 다시 씁니다.

장점

  1. 가장 광범위하게 사용되며 Read-Heavy 한 작업에서 좋은 성능을 보입니다.
  2. Cache Failure에 Resilient 합니다. 캐시 서버가 다운되어도 문제 없이 바로 데이터베이스로 접근할 수 있어요.
  3. 캐시의 데이터와 데이터베이스의 데이터 모델의 형태가 달라도 괜찮습니다. 쿼리 결과를 캐시에 넣기만 할 뿐이고 가져온 데이터베이스의 모델을 애플리케이션에서 재가공해 캐시에 넣을 수 있으니까요.

단점

이 전략을 사용하는 경우 데이터의 쓰기는 보통 데이터베이스에 직접적으로 이뤄집니다. 그래서 캐시와 데이터베이스간의 불일치가 발생할 수 있습니다. 이 문제는 캐시에 TTL(Time-To-Live)를 설정해 어느정도 해결할 수 있습니다. 오래된 데이터를 만료시켜 다시 가져오게하는 것입니다.

Read-Through

  1. 먼저 캐시를 확인해 데이터가 있을 경우 (Cache Hit) 캐시에서 데이터를 가져옵니다. (동일)
  2. 데이터가 없는 경우 (Cache Miss) 데이터베이스에서 캐시로 가져온 뒤 캐시에서 꺼내옵니다. (순서가 다름)

Cache Aside와 비슷하나 미묘하게 다릅니다. 먼저 Cache Aside에서는 데이터를 데이터베이스에서 가져오고 캐시에 배포하는 역할을 애플리케이션이 담당합니다. 반면 Read-Through에서는 캐시 서버가 담당하게됩니다.

그리고 캐시의 데이터와 데이터베이스의 데이터 모델이 동일해야 합니다. 데이터를 저장하는 과정 사이에 애플리케이션이 개입할 여지가 없으니까요.

Write-Through

  1. 캐시에 데이터를 씁니다.
  2. 데이터는 캐시에서 데이터베이스로 이동합니다.

딱히 쓸모없어 보이지만? Cache-Aside와 함께 사용했을 때 이점을 발휘합니다. Cache-Aside의 장점을 누림과 동시에 Cache Miss라는 단점도 상쇄할 수 있습니다.

Write-Back

캐시에 데이터를 계속 쓰다가 일정 시간이 지난 후, 캐시 데이터를 모아 데이터베이스에 한 번에 쓰는 방식입니다.

Write-Heavy한 작업에 적합하며 Read-Through와 함께 사용할 때 정합성 문제를 해결하고 읽기, 쓰기의 이점을 모두 누릴 수 있습니다.

데이터베이스 장애에 잘 버틸 수 있지만 캐시에 장애가 생기면 데이터가 소실될 수 있다는 단점이 존재합니다.

그래서 나는?

기존의 목표는 작고 많은 Write에 대응하는 것이었습니다. 고로 Write-Back 방식을 사용해 Write를 캐시에 모아둔 뒤 한 번에 처리하는 방식을 사용하는 것이 옳다고 판단했고 가장 많은 조회 쿼리를 유발하는 게시물을 대상으로 Read-Through 방식을 사용하려 합니다.

구현은 다음 시간에!

참고

https://sabarada.tistory.com/142

--

--