본문 바로가기
츄Log/기타 끄적

다양한 캐시 전략들

by 츄츄🦭 2024. 1. 5.
728x90

출처 : https://en.wikipedia.org/wiki/Cache_(computing)

 

캐시는 일정 기간동안 임시로 데이터 하위집합을 저장하기 위한 fast data storage layer입니다.

 

캐시란? 캐시에 대하여

캐시는 일정 기간동안 임시로 데이터 하위집합을 저장하기 위한 fast data storage layer입니다. 캐시는 어디에나 존재합니다. 하드웨어 캐시(ex. L1, L2), 페이지 캐시, 데이터베이스 캐시, API캐시, DNS캐

chupin-tech.tistory.com

 

 

이런 캐시를 구성하는데 다양한 전략이 있습니다. 내 애플리케이션의 읽기/쓰기 패턴에 맞는 전략을 선택하면 매우 효과적인 캐시 시스템을 구축할 수 있을 것입니다. 

 

캐시에는 어떤 전략이 있는지 Read와 Write를 분리하여 알아보겠습니다.

 

Read 전략

1. Cache-Aside

가장 기본적이고 일반적인 전략입니다. 

캐시는 측면에 위치하여 애플리케이션은 캐시와 데이터베이스 모두 직접 통신합니다. 

캐시와 데이터베이스 사이에는 연결이 없고, 모든 작업은 애플리케이션에 의해 처리됩니다. 

 

이 방식은 read-heavy한 workload에 적합합니다. 

이 전략을 사용하는 시스템은 cache failure에 대해 resilent가 뛰어납니다. 캐시가 다운되더라도 데이터베이스로 이어서 작동할 수 있습니다. (하지만 데이터베이스로의 요청이 일정 수준을 넘어가면 문제가 되는 건 마찬가지겠죠.)

 

또 다른 특징은 캐시의 데이터 모델과 데이터베이스의 데이터 모델이 다를 수 있습니다. 

여러 쿼리를 통해 만들어진 결과를 하나의 key로 캐시할 수 있습니다. 

 

이 방식을 쓸 때 write는 데이터베이스에 하게 되는데, 그럼 캐시와 일관성 문제가 발생할 수 있습니다.

이를 위해 보통 짧은 시간의 TTL을 설정하고, TTL이 만료되기 전까지는 stale data가 제공될 수 있습니다.

만약 언제나 fresh한 데이터를 제공해야 하는 경우에 데이터가 업데이트 될 때 캐시를 무효화 하거나 다른 쓰기 전략을 선택해야 합니다.

 

2. Read-Through

read-through 전략은 데이터베이스 앞에 캐시가 있는 것입니다.

애플리케이션에서 캐시에 조회를 하면, 데이터가 있으면 반환 없으면 캐시가 데이터베이스에 조회하여 데이터를 가져오고 저장한 후 반환합니다.

 

cache-aside와 비슷하지만 다른 점이 있습니다. 

read-through는 애플리케이션의 책임이 많이 줄어듭니다. 캐시 레이어에서 데이터베이스의 업데이트를 담당하기 때문입니다. 

또한 cache-aside와 달리 read-through 캐시의 데이터 모델은 데이터베이스 데이터 모델과 같습니다. 

 

read-through는 동일한 데이터가 여러번 요청되는 read-heavy한 workload에 적합합니다. 

 

데이터를 맨 처음 요청한 경우 항상 cash miss가 발생하여 캐시에 데이터를 로드해야하는 추가 로드가 발생합니다. 

이를 위해 수동으로 쿼리를 실행하여 warming하거나, 미리 만들어두는 pre-heating을 해서 이를 방지할 수 있습니다. 

 

Write 전략

1. Write-Through

read-through처럼 데이터베이스 앞에 캐시가 있고 애플리케이션은 캐시를 통해 데이터를 씁니다. 

데이터가 캐시에 먼저 기록된 다음에 데이터베이스에 기록되므로 2개의 쓰기 작업이 발생하여 추가적인 write latency가 발생합니다. 

그러나 read-through와 함께 사용하면 캐시를 통해 읽기의 모든 이점을 얻고, 데이터 일관성도 보장되어 캐시 invalidation을 아예 할 필요가 없습니다. (AWS의 Dynamo Accelerator가 이 모델인 것 같습니다.)

다만, 모든 데이터가 캐시 레이어를 통과하므로 꽤 많은 메모리 용량을 쓸 것 같습니다.(만약 메모리 공간이 작다면 매번 데이터가 교체되어 cache miss가 계속 발생할 것 같다는 생각이 듭니다.) 혹은 매번 unique한 데이터를 읽고 쓰면 굳이 write를 두번씩 하여 latency를 늘릴 필요도 없어 보입니다. 

(보면 볼수록 캐시는 잘 변하지 않는 혹은 자주 쓰이는 데이터에 사용하는게 맞아보입니다.)

 

2. Write-Around

데이터베이스에 직접 기록하며 읽은 데이터만 캐시에 저장됩니다.

 

이 전략은 read-through 혹은 cache-aside 와 결합되어 데이터가 한 번 기록되고 읽히는 빈도가 적은 상황에서 좋은 성능을 제공합니다. (로그나 채팅방 메시지에서 사용할 수 있습니다) 

 

3. Write-Back(Write-Behind)

애플리케이션은 "저장하고 즉시 응답하는 캐시"에 데이터를 씁니다. 

그럼 나중에 캐시가 데이터베이스에 데이터를 씁니다.

 

write-through와 다른점이 바로 이것입니다. 

write-through은 캐시에 기록된 데이터가 데이터베이스에 동기식으로 업데이트 되지만,

write-back은 비동기적으로 업데이트됩니다.

애플리케이션 관점에서는 캐시만 업데이트 되면 응답을 받을 수 있으므로 write-back 캐시에 대한 쓰기가 훨씬 빠릅니다. 

 

이 전략은 write-heavy한 workload에 적합합니다. read-through와 결합하면 가장 최근에 업데이트되고 접근된 데이터를 항상 캐시에서 사용할 수 있게 됩니다.

 

또한 이 전략은 데이터베이스 failure에 대한 resilent가 뛰어나고 일부 데이터베이스 downtime에 tolerant합니다. 

만약 애플리케이션으로부터 오는 요청을 batching하거나 병합할 수 있다면 데이터베이스에 대한 전체 쓰기 또한 줄일 수 있습니다. 

(데이터베이스 공급자가 요청 수에 따라 비용을 청구한다면 로드가 감소하여 비용도 절감됩니다)

 

가장 큰 단점은 캐시 failure가 발생하면 데이터가 영구적으로 손실될 수 있다는 것입니다. 

InnoDB또한 내부적으로 write-back 캐시가 활성화되어있다고 볼 수 있습니다.

쿼리가 메모리에 저장되고, 디스크로 플러시되기 때문입니다. (버퍼풀과 버퍼풀 플러시, Real MySQL8.0 책을 참고하시면 됩니다.) 

 

지금까지 다양한 캐시 전략을 알아봤습니다. 

내 애플리케이션의 access 패턴에 맞추어 캐시 전략을 선택한다면 latency를 줄이고 쓰기 증폭을 줄여 효과적인 캐시 구조를 만들 수 있을 것입니다. 

 


 

관련 : https://chupin-tech.tistory.com/59

 

Side Cache / Transparent Cache

캐시에 대해 공부하다가 Side Cache, Transparent Cache 키워드를 보았습니다. 이 두가지 키워드를 알아보겠습니다. Side Cache 전통적인 external cache의 형태를 뜻합니다. 캐시는 데이터베이스와 독립적으로

chupin-tech.tistory.com

도움 : https://codeahoy.com/2017/08/11/caching-strategies-and-how-to-choose-the-right-one/

728x90