캐시 적용기 #0 (캐시 적용 배경과 학습 및 기획)

손문기·2023년 12월 13일
0

시작하며

현재 국내 상거래 사이트 가격 추적 애플리케이션을 개발하는 프로젝트를 진행 중입니다.

해당 어플리케이션은 사용자가 등록한 상품에 대해 주기적으로 정보를 수집하여 관리합니다. 사용자는 상품 별로 목표 가격을 설정하고 상품의 가격이 목표가격 이하로 하락하게 되면 알림을 받을 수 있습니다. 또한 앱 내에서 상품의 가격 변화를 담은 그래프와 상품 정보를 확인할 수 있습니다.

해당 프로젝트는 주기적으로 데이터를 수집하고 다수의 사용자에 대해 다양하고 많은 데이터를 전달하는 과정을 효율적으로 처리하는 것이 핵심 과제라고 생각하였으며, 이를 위해 캐시를 적용하는 과정에서 진행한 학습, 고민, 구현 등에 대해 기록하고자 합니다.

이번 파트에서는 Cache를 적용하게된 배경과 학습과정 및 고려사항에 대해 적어보도록 하겠습니다.

Cache

Cache는 미래의 요청에 대한 결과 데이터를 미리 저장해뒀다가 빠르고 효율적으로 서비스하는 것을 목표로 합니다. 이미 조회한 데이터나 연산 결과를 저장함으로써 향후 동일한 요청에 대한 처리 속도를 향상시키고 서버 부하를 감소시킬 수 있어 어플리케이션의 성능을 향상시킬 수 있습니다.

이러한 장점을 가진 Cache를 진행중이던 프로젝트에 적용하면 상품 데이터를 전달하거나 확인하기 위해서는 항상 외부 DB 서버에 접근하여 값을 읽어와야야해서 발생하던 비용을 대폭 줄일 수 있을 것이라고 생각하였습니다.

Cache Hit과 Cache Miss

위에서 언급한 Cache의 장점만을 보면, 무조건 사용해야 하는 것 아닌가? 하는 생각을 할 수 있습니다. 하지만 Cache의 장점을 가져가는 상황은 Cache가 Hit이 되어야 하는 상황에만 유한합니다.

Cache Hit

Cache Hit 이란 요청에 대한 데이터가 캐시에 존재하여 데이터를 캐시로부터 즉시 응답받을 수 있는 경우를 말합니다. 이 경우에는 데이터를 처리하기 위해 캐시만을 검색하므로 빠르게 응답할 수 있고 부가적인 I/O가 발생하지않습니다.

Cache Miss

Cache Miss는 요청에 대한 데이터가 캐시에 존재하지 않는 경우를 말합니다. 이 경우에는 캐시 검색 이후 DB와 같은 별도의 리소스에서 데이터를 검색하여 응답하는 과정을 거칩니다.
Cache Miss가 발생할 경우에는 오히려 Cache를 사용하지 않은 경우보다 Cache에 대한 I/O가 추가적으로 발생하여 성능이 저조한 현상을 보이게 됩니다.

따라서 Cache의 이점을 살리기 위해서는 Cache Hit 비율을 최대한 높이는 것이 중요합니다.

Cache Hit을 높이는 방법

Cache Hit을 높일 수 있는 이상적인 방법은 Cache에 모든 데이터를 저장하는 것입니다. 하지만 현실은 Cache 저장공간의 한계가 있기 때문에, Cache에 어떤 데이터를 저장할지에 대한 전략을 잘 세우는 것이 중요합니다.
우선 Cache에 저장할 데이터를 결정할 때에는 데이터가 자주 참조되며 변경이 적으며, 변경의 영향이 적은지에 대한 여부를 판단하는 것이 중요합니다.
또한 현재 비즈니스 로직에 적절한 캐시 전략을 선택하는 것도 중요합니다.

Cache Strategy

읽기 전략

  • Look Aside (Lazy Loading)
    • 데이터를 조회할 때, 캐시를 우선 조회하고 데이터가 없으면 DB를 조회
    • 캐시가 다운되더라도 장애 발생 없음
    • 새로운 캐시를 사용하거나 서비스 초기에 대량의 cache miss가 발생 할 수 있음
      • DB의 내용을 미리 Cache에 저장하는 Cache Warming을 통해 보완 가능
  • Read Through
    • 데이터를 캐시에서만 읽어오는 전략
    • 데이터 동기화를 캐시 제공자에게 위임하여 데이터 정합성 문제 해결 가능
    • 속도가 비교적 느림
    • 캐시 다운시 서비스 장애 발생

쓰기 전략

  • Write Around
    • 모든 데이터를 DB에 저장
    • Cache miss가 발생하면 DB의 데이터를 Cache에도 저장
    • DB와 Cache의 데이터가 불일치 할 수 있음
    • 속도가 빠름
  • Write Through
    • 데이터를 저장할 때 Cache에 저장하고 이를 DB에도 저장
    • Cache는 항상 최신 정보를 가지고 있음
    • 데이터 일관성 유지 가능
    • 속도가 느림
  • Write Back
    • 데이터를 저장할 때 Cache에 저장하고 이를 모아서 일정 주기마다 DB에 반영
    • DB 부하를 줄일 수 있음
    • 캐시 오류 발생시 데이터 소실 가능성 있음

제거 전략

  • LRU(Least Recently Used)
    • 가장 오래된 캐시를 제거
  • LFU (Least Frequently Used)
    • 가장 적게 사용된 캐시를 제거
  • TTL (Time-to-Live)
    • 캐시 데이터의 유효기간을 설정

Local Cache 와 Global Cache

Cache는 데이터를 저장하고 관리하는 범위에 따라 local cache와 global cache로 나뉩니다.

  • Local Cache
    • 로컬 서버 내에서만 사용되는 캐시
    • 로컬 서버마다 각각 캐시를 따로 저장
    • 로컬 내부의 리소스에 데이터를 저장하므로 접근 속도가 빠름
    • 로컬이 아닌 외부 서버와 데이터를 공유하기는 어려움
    • 서버간의 캐시 데이터 일관성을 유지하기 어려움
  • Global Cache
    • 여러 서버에서 접근할 수 있는 캐시
    • 별도의 캐시 서버에 캐시를 저장
    • 외부의 서버를 참조해야 하기 때문에 네트워크 트래픽이 발생하여 Local Cache 보다는 느림
    • 여러 서버간의 데이터 공유가 쉬움
    • 캐시를 분산하여 저장할 수 있고, 확장성이 좋음

프로젝트 Cache 기획

지금까지 설명한 내용을 바탕으로 진행중인 프로젝트에 어떻게 Cache를 적용하면 좋을지 고민을 해보았습니다. 학습을 목적으로 하는 프로젝트이기 때문에 다양한 Cache를 사용해보고자 하여, Local Cache와 Global Cache를 모두 사용하고자 하였습니다. 또한 Local Cache는 직접 Cache를 구현하여 적용해보는 과정을 가지고, Global Cache는 Redis를 사용하여 적용하기로 하였습니다.

Local Cache

  • 사용자별 트래킹 상품 목록 정보
  • 트래킹 인기 상품 목록 정보

Global Cache

  • 전체 상품 간략한 최신 정보
  • 상품 인기 순위 정보
  • 사용자별 토큰

다음 파트 내용

다음 파트에서는 Local Cache를 프로젝트에 적용하는 과정에 대해 소개하도록 하겠습니다.
어떤 데이터를 저장하고 활용하는지, Cache는 어떻게 구성하였는지 등에 대한 자세한 내용을 다루겠습니다.

마치며...

프로젝트를 진행하며 데이터 처리 성능 개선을 위해 Cache를 적용하기로 결정하여, Cache에 대해 학습하고 어떻게 현재 프로젝트에 적절하게 적용할 수 있을지 고민하는 시간을 가졌습니다.
Cache 구조 설계에 따라 Cache의 효율이 크게 차이가 날 수 있다는 것과 효율적인 구조 설계를 위해서는 고려해야하는 부분이 정말 많다는 것을 깨닫게 되었습니다.
현재 프로젝트의 상황에 적절한 Cache 구조와 학습을 병행 할 수 있도록 설계하는 것이 중요할 것 같습니다.

0개의 댓글