캐시(Cache)와 캐싱(Caching)
캐시(Cache)란?
캐시
란 임시 데이터 저장소를 의미한다.
다양한 종류의 데이터를 저장할 수 있으며
자주 사용하거나 불러오는 데 오래 걸리는 데이터를 저장한다.
캐싱(Caching)이란?
캐싱
이란 임시 데이터 저장소인 캐시에 접근에서 데이터를 가져오는 방식을 의미한다.
캐시에 원하는 데이터가 없거나 캐시에 있는 데이터가 너무 오래되었다면
원본 데이터를 다시 가져오면서 캐시에 접근하여 데이터를 저장/갱신한다.
일반적인 개념
캐시와 캐싱은 레디스에만 있는 개념은 아니다.
DB, CDN, 웹, 브라우저 등 다양한 곳에서 사용되는 일반적인 개념이다.
캐싱 전략
캐싱이란 것은 캐시에서 데이터를 저장하고 가져오는는 방식
이다.
이러한 방식은 여러 가지 종류가 있으며 이를 전략(Strategy)
이라고 부른다.
캐싱 전략의 종류에는
캐시를 읽는 캐시 읽기 전략(Read Cache Strategy)
과과
캐시를 쓰는 캐시 쓰기 전략(Write Cache Strategy)
가 있다.
전략이 필요한 이유
레디스는 기본적으로 디스크가 아닌 메모리에 데이터를 저장한다.
보통 메모리 용량을 16기가에서 32기가정도인 것을 쓸텐데
데이터를 모두 메모리에 저장해버리면 용량이 부족해서 시스템이 다운될 수도 있다.
그래서 어떤 캐시를 저장하고, 캐시를 얼만큼 저장하고, 얼마동안의 기간동안 가지고 있을 건인지에 대한 캐싱 전략
이 중요한 것이다.
캐시를 사용할 때의 문제점
캐시를 사용하게 되면 임시 저장소인 캐시의 데이터와 DB의 데이터가 동일하지 않은
데이터 정합성
문제가 발생하게 된다.
만약에 조회 기록을 저장하는 쿼리가 너무 자주 발생해서
DB의 부하를 막기 위해 레디스를 도입했다고 가정해보자.
레디스에 데이터를 모아뒀다가 일정 기간마다 한꺼번에 DB에 적용하려고 한다면
레디스에는 100건 넘게 쌓여 있는데, DB에는 해당 데이터가 아예 없을 수도 있다.
그래서 캐시 역할을 하는 레디스를 도입할 때는
애플리케이션의 구조와 상황에 따라
데이터를 읽는 캐시 읽기 전략
과 데이터를 쓰는 캐시 쓰기 전략
을
적절한 방식으로 선택하는 것이 중요하다.
관련 용어
Cache Hit
- 캐시에 데이터 요청 시 데이터가 있는 경우
Cache Miss
- 캐시에 데이터 요청 시 데이터가 없는 경우
Cache Warming
- DB에서 캐시에 데이터를 미리 넣어주는 작업
Cache Hit Rating
- 캐시 데이터로 저장했을 때 성능이 향상될 수 있는지 판단하는 작업
- 자주 사용되면서 자주 변경되지 않는 데이터일 수록 캐시 서버에 적용하였을 때 성능이 많이 향상된다.
캐시 읽기 전략 (Read Cache Strategy)
Cache Aside 전략
- 정의
- 데이터 요청 시 캐시에서 먼저 조회하고, 그 다음에 DB에 요청하는 방식
- 기본 원리
- 서버가 요청한 데이터가 캐시에 있는 경우
- 캐시로부터 데이터를 응답받는다.
- 서버가 요청한 데이터가 캐시에 없는 경우
- 서버가 DB에 데이터를 요청해서 응답받는다.
- 서버가 DB로부터 받아온 데이터를 캐시에 저장한다.
- 서버가 요청한 데이터가 캐시에 있는 경우
- 특징
- 무조건 캐시를 거쳐보고 그 다음에 DB에 데이터를 저장한다.
- 캐시랑 DB가 분리되어 있어서 원하는 데이터만 캐시에 저장할 수 있다.
- 캐시랑 DB가 분리되어 있어서 캐시 장애 대비 구성이 되어있다.
- 그래서 레디스가 다운되도 DB에서 데이터를 가져올 수 있다보니 서비스 자체에는 문제가 없다.
- 대신에 만약 캐시에 커넥션이 많았다면 순간적으로 DB에 부하가 몰릴 수 있다.
- 자주 요청되는 데이터의 경우
Cache Warming
을 해둬야 한다.
- 적용하기 좋은 경우
- 반복적으로 동일한 쿼리를 수행하는 경우
- 적용하기 좋지 않은 경우
- 단건 호출 빈도가 높은 쿼리를 수행하는 경우
- 별칭
- Look Aside 전략
- Lazy Loding 전략
Read Through 전략
- 정의
- 데이터 요청 시 캐시에서만 데이터를 조회하는 방식
- 기본 원리
- 서버가 요청한 데이터가 캐시에 있는 경우
- 캐시로부터 데이터를 응답받는다.
- 서버가 요청한 데이터가 캐시에 없는 경우
- 캐시가 DB에 데이터를 조회해서 자체적으로 데이터를 저장한다.
- 서버가 요청한 데이터가 캐시에 있는 경우
- 특징
- 데이터 동기화를 라이브러리나 캐시 제공자에게 위임한다.
- 데이터가 없으면 캐시가 DB를 무조건 갔다와야 하기 때문에 전체적으로 속도가 느린 편이다.
- 데이터 조회를 캐시에만 의지하기 때문에 레디스가 다운되면 서비스 이용에 문제가 생길 수 있다.
- 무조건 데이터 동기화가 이루어지다보니 데이터 정합성은 보장된다.
- 직접적인 DB 접근은 최소화하고, 읽기 비용을 최소화할 수 있다.
- 레디스 다운 시 서비스에 문제가 생기는 것을 방지해서 Replication나 Cluster같은 구성 방식을 사용해야 한다.
- 자주 요청되는 데이터의 경우
Cache Warming
을 해둬야 한다.
캐시 쓰기 전략 (Write Cache Strategy)
Write Around 전략
- 정의
- 데이터 저장 시 캐시에 저장하지 않고 DB에만 저장하는 방식
- 특징
- 캐시를 갱신하지 않는다.
Cache Miss
가 발생하기 전에 DB에 쓰기 작업이 발생한다면데이터 불일치
가 발생한다.데이터 불일치
를 방지하는 방법- 캐시 데이터 삭제
- 캐시 데이터 변경
- 캐시 만료시간 단축
- 적용하기 좋은 경우
- 쓰기 작업 및 읽기 작업이 빈번하지 않은 쿼리를 수행하는 경우
- 적용하기 좋지 않은 경우
- 쓰기 작업 및 읽기 작업이 빈번한 않은 쿼리를 수행하는 경우
Write Through 전략
- 정의
- 데이터 저장 시 DB와 캐시에 동시에 저장하는 방식
- 특징
- 캐시에 데이터를 먼저 저장하고 그 다음에 DB에 바로 저장한다.
- 데이터를 모아서 저장하는 방식이 아닌 바로 저장하는 방식이다.
- 반드시 2단계를 거치다보니 기본적인 속도가 느리다.
- 데이터 동기화를 라이브러리나 캐시 제공자에게 위임한다.
- 무조건 데이터 동기화가 이루어지다보니 데이터 정합성은 보장된다.
- 무조건적인 데이터 동기화때문에 자주 사용되지 않는 불필요한 리소스도 저장된다.
- 그래서 만료시간(TTL) 설정이 필수다.
- 캐시에 데이터를 먼저 저장하고 그 다음에 DB에 바로 저장한다.
- 적용하기 좋은 경우
- 데이터 유실이 발생하면 안 되는 경우
- 적용하기 좋지 않은 경우
- 데이터 생성, 수정, 삭제가 자주 일어나는 경우
- 1번의 요청에 무조건 2번의 쓰기 작업이 발생하기 때문이다.
- 기억장치의 속도가 느린 경우
- 데이터 기록 시 CPU가 대기하는 시간이 길어져서 전반적인 성능이 감소한다.
- 데이터 생성, 수정, 삭제가 자주 일어나는 경우
Write Back 패턴
- 정의
- 데이터 저장 시 캐시에만 우선 저장하고, 일정 주기마다 쌓인 캐시를 모아서 DB에 저장하는 방식
- 특징
- 캐시와 DB를 비동기적으로 연계하기 때문에 동기화 과정이 생략된다.
- 캐시를 모아서 일정 주기마다 배치 작업을 통해서 DB에 반영한다.
- 캐시를 모아서 DB에 반영하기 때문에 쓰기 쿼리 회수 비용과 부하를 줄일 수 있다.
- 무조건적인 데이터 동기화때문에 자주 사용되지 않는 불필요한 리소스도 저장된다.
- 그래서 만료시간(TTL) 설정이 필수다.
- Write Through 전략과의 차이점은 그냥 비동기적이란 것 뿐이다.
- 무조건 데이터 동기화가 이루어지다보니 데이터 정합성은 보장된다.
- 캐시를 모아서 처리하기 때문에 만약에 레디스에서 오류가 발생하면 DB에 반영하지 못하고 소실되는 데이터가 발생할 수도 있다.
- 캐시를 모아뒀다가 처리하는 방식이라서 캐시(레디스)가 일종의 큐 역할을 겸한다.
- 적용하기 좋은 경우
- 쓰기 작업이 빈번하면서, 읽기 작업을 할 때 많은 양의 리소스가 소모되는 경우
- 적용하기 좋지 않은 경우
- 쓰기 작업이 빈번하지 않은 경우
- 읽기 작업을 할 때 적은 양의 리소스가 소모되는 경우
조합 전략
캐시는 읽기도 하고 쓰기도 해야한다.
그래서 보통은 읽기 전략과 쓰기 전략을 조합해서 사용한다.
공통사항으로 리소스 관리를 위해 캐시 저장 시 만료시간(TTL)을 설정한다.
Cache Aside 전략 + Write Around 전략
- 가장 일반적으로 자주 쓰이는 조합
Read Through 전략 + Write Around 전략
- 데이터 정합성 이슈에 대한 완벽한 안전 장치를 구성하는 조합
- 쓰기 작업은 항상 DB에 요청하고, 읽기 작업은 항상 캐시에 요청한다.
Read Through 전략 + Write Through 전략
- 최신 캐시 데이터를 보장하는 조합
- 읽기 작업과 쓰기 작업 모두 항상 캐시에 요청한다.
- 쓰기 작업 시 항상 캐시에서 실시간으로 DB로 보내기 때문에 데이터 정합성도 보장된다.
캐시에 대한 작업 지침
캐싱 전략은 이름 그대로 캐시를 저장하고 조회하는 것에 대한 전략이다.
레디스에는 캐싱 전략과 별개로 캐시에 특화된 일종의 지시사항이 존재하는데
이를 지침
이라고 표현한다.
캐시 저장 방식 지침
- 캐시는 자주 사용되며 자주 변경되지 않는 데이터를 저장하는 것이 우선사항이다.
- 캐시는 데이터를 메모리에 저장하기 때문에 메모리의 휘발성을 고려하여 일정 주기마다 디스크에 저장해야 한다.
- 데이터가 유실되거나 데이터 정합성이 맞지 않는 상황을 고려하여 중요하거나 민감한 정보는 캐시에 저장하지 않는 것이 좋다.
- 캐시 솔루션에 장애가 발생했을 경우를 대비하여 타임아웃이나 DB 조회 병행 등 미리 대응방안을 준비해둬야 한다.
캐시 제거 방식 지침
- 만료시간 설정을 통해 캐시가 오래된 데이터가 아닌 최신 데이터를 보유하도록 해야한다.
- 어떤 서비스에 대한 데이터인지에 따라 어느 정도는 가장 최신 데이터가 아니어도 되긴 한다.
- 서비스의 유형에 따라 알맞는 만료시간을 설정해야 한다.
- 만료시간이 너무 짧으면 데이터가 너무 빨리 제거되서 캐시를 사용했을 때의 이점이 줄어든다.
- 만료시간이 너무 길면 공간 차지로 인해 메모리가 부족해지거나, 오래된 데이터를 들고 있는 등의 문제가 발생한다.
캐시 공유 방식 지침
- 캐시에 있는 데이터를 수정하려고 할 때 이미 다른 인스턴스가 변경한 사항이 있다면 덮어쓰지 않아야 한다.
- 캐시는 애플리케이션의 여러 인스턴스가 공유하도록 설계되어 있다.
- 만약 다른 인스턴스가 이미 수정했는데 별도 작업 없이 그대로 덮어쓰게 된다면 데이터 정합성 문제가 발생한다.
- 데이터 정합성이 맞지 않는 문제를 방지하기 위해 미리 대응방안을 준비해둬야 한다.
- 데이터가 검색된 이후 변경된 적이 있는지 확인한다.
- RDBMS처럼 데이터에 Lock을 건다.
캐시 가용성 지침
- 캐시를 사용하는 목적은 빠른 데이터 전달이라는 것을 유의하고 설계해야 한다.
- 캐시는 데이터 읽기에 집중해서 성능을 확보한다.
- 데이터의 영속성은 캐시가 아닌 DB에 위임한다.
- 캐시 서버가 장애로 인해 다운되거나 서비스가 불가능하더라도 서비스 자체는 운영이 가능해야 한다.
- 성능 상의 하락은 잇어도 서비스 자체가 운영이 불가능한 상태가 되면 안 된다.
레디스 적용하기 전 알아야 하는 상황
데이터 조회 성능을 개선하는 방법은 매우 다양하다.
- SQL 튜닝
- 캐싱 서버 활용 (Redis 등)
- 레플리케이션 (Master/Slave 구조)
- 샤딩
- DB 스케일업 (CPU, Memory, SSD 등 하드웨어 업그레이드)
그런데 가장 중요하게 알아야 하는 사항은
SQL 튜닝 외의 모든 방법은 추가적인 시스템 구축을 진행해야 한다는 것이다.
이는 금전적 비용, 시간적 비용, 관리 비용 모두가 증가한다.
SQL 자체가 비효율적이면 애초에 시스템 성능이 개선되봤자 한계가 있다.
SQL 튜닝을 우선적으로 진행하고, 그 다음에 다른 방법을 추가 도입하는 것을 고민해봐야 한다.
출처
비전공자도 이해할 수 있는 Redis 입문/실전 (조회 성능 최적화편)
[REDIS] 📚 캐시(Cache) 설계 전략 지침 💯 총정리
[Redis] 캐시란? 캐싱전략? 알고 써보자!
[데이터베이스] Redis 캐시(Cache) 설계 전략