본문으로 바로가기

18

다단 캐싱

댐은 하나로 막지 않는다

먼저 보면 좋은 강의: CDN, 캐시 무효화

단계별로 보기

스페이스바로 재생/정지, 좌우 화살표로 단계 이동, R로 처음으로 돌아갑니다.

대기 중1 / 4 단계 — 한 겹으로는 막히지 않는다

CDN만 두면 초당 500건이 75건으로 줄어 웹 서버는 삽니다. 그런데 그 75건이 데이터베이스로 그대로 갑니다. 한계는 66건입니다. 데이터베이스가 무너집니다. 막아야 할 곳이 두 군데인데 한 곳만 막은 것입니다.

유입 요청초당 500건
큐 적체20건

이 강의를 마치면

  • 캐시 계층을 여러 겹으로 두면 각 계층이 남은 트래픽만 상대한다는 구조를 설명한다.
  • 각 계층의 적중률이 곱해져서 원본 도달량이 결정되는 것을 계산한다.
  • 계층마다 목적(거리·부하)과 무효화 난이도가 다름을 구분한다.
  • 계층을 늘릴수록 커지는 대가(신선도 지연, 디버깅 난이도)를 설명한다.

한 겹으로는 부족할 때

지금까지 우리는 캐시를 한 겹만 봤습니다. CDN 하나, 또는 애플리케이션 캐시 하나. 각각은 잘 작동했습니다.

그런데 초당 500건이 들어오고, 웹 서버는 초당 200건이 한계이고, 데이터베이스는 초당 66건이 한계라면 어떻게 될까요?

  • CDN만 두면? 500건이 75건으로 줄어 웹 서버는 삽니다. 하지만 그 75건이

데이터베이스로 그대로 가면 66건 한계를 넘습니다. 데이터베이스가 죽습니다.

  • 애플리케이션 캐시만 두면? 데이터베이스는 삽니다. 하지만 500건이 전부

웹 서버로 밀려옵니다. 웹 서버가 죽습니다.

하나만으로는 안 됩니다. 막아야 할 곳이 두 군데이기 때문입니다.

댐을 여러 개 두는 이유

홍수를 막을 때 상류에 댐 하나만 짓고 그 아래를 무방비로 두지 않습니다. 상류 댐이 큰 물을 잡고, 중류 댐이 그다음을 잡고, 하류에는 얼마 안 오게 합니다.

캐시도 같습니다.

사용자 →  CDN  →  웹 서버 →  캐시  → 데이터베이스
        85% 차단          90% 차단

곱셈으로 계산한다

이 강의의 핵심 계산입니다. 각 겹은 앞 겹을 통과한 것만 상대합니다.

들어오는 요청                초당 500건
CDN 적중률 85%  →  통과       초당  75건    (500 × 0.15)
캐시 적중률 90%  →  통과      초당 7.5건    (75 × 0.10)
─────────────────────────────────────────
데이터베이스가 보는 것          초당 7.5건

500이 7.5가 됐습니다. 약 67분의 1입니다.

주목할 점은 이 67배가 85%와 90%라는 평범한 숫자에서 나왔다는 것입니다. 통과율끼리 곱해지기 때문입니다.

0.15 × 0.10 = 0.015  →  1.5%만 원본에 닿는다

한 겹으로 이 효과를 내려면 적중률 98.5%가 필요합니다. 그건 현실적이지 않습니다. 두 겹의 평범한 캐시가 한 겹의 완벽한 캐시보다 쉽고 안전합니다.

겹마다 목적이 다르다

단순히 같은 걸 두 번 하는 게 아닙니다. 각 겹이 잘하는 일이 다릅니다.

어디에주로 무엇을잘하는 것무효화
CDN사용자 옆 (수백 곳)이미지·스크립트거리를 줄인다어렵다. 수백 곳에 전파해야
애플리케이션 캐시데이터센터 안 (한 곳)조회 결과원본 부하를 줄인다쉽다. 한 곳만 지우면 된다
데이터베이스 내부 캐시원본 안자주 읽는 페이지디스크 접근을 줄인다자동

CDN은 거리를 줄이는 데 압도적이지만, 값을 바꿨을 때 전 세계 수백 곳의 복사본을 지우는 것은 느리고 완전하지 않습니다. 애플리케이션 캐시는 거리는 못 줄이지만 한 곳만 지우면 되므로 무효화가 정확합니다.

그래서 자주 바뀌는 것은 안쪽 겹에, 거의 안 바뀌는 것은 바깥 겹에 둡니다.

늘어나는 청구서

겹이 늘면 좋은 것만 늘지 않습니다.

1. 신선도 지연이 겹마다 쌓인다

가격을 바꿨습니다. 애플리케이션 캐시는 즉시 지웠습니다. 그런데 CDN은 아직 옛날 값을 들고 있습니다. 가장 바깥 겹의 유효 시간이 곧 사용자가 겪는 지연입니다.

안쪽을 아무리 정확하게 관리해도, 바깥 겹이 10분짜리 TTL이면 사용자는 10분 뒤에야 새 가격을 봅니다. 겹을 늘린다는 건 이 지연을 늘린다는 뜻입니다.

2. "왜 이 값이 나오지?"가 어려워진다

사용자가 옛날 가격을 봤다고 신고했습니다. 어느 겹의 문제입니까? 브라우저 캐시? CDN? 애플리케이션 캐시? 데이터베이스가 진짜 안 바뀐 건가? 후보가 네 곳이고, 각각 확인하는 방법이 다릅니다.

3. 겹마다 죽을 수 있다

CDN이 죽으면 500건이 통째로 웹 서버로 옵니다. 애플리케이션 캐시가 죽으면 75건이 통째로 데이터베이스로 갑니다. 각 겹은 다음 겹의 생존 조건입니다.

그래서 몇 겹이 맞나

정답은 "필요한 만큼만"입니다. 겹을 하나 더 둔다는 건 무효화 지점을 하나 더 만드는 것이고, 장애 원인 후보를 하나 더 만드는 것입니다.

실무의 기준은 대체로 단순합니다.

막아야 할 병목이 있는 곳에만 겹을 둔다.

병목이 없는 자리에 캐시를 넣으면 얻는 것은 없고 복잡도만 늘어납니다. "혹시 몰라서" 넣은 캐시가 몇 달 뒤 원인 불명의 옛날 값 버그로 돌아옵니다.

직접 해보세요

아래 과제는 이 단원의 마무리입니다. 초당 500건이 들어오고 병목이 두 군데 있습니다. 겹을 두 개 쌓아야 합니다. 하나만 넣으면 다른 하나가 무너지는 것을 직접 확인하고 시작하세요.

이 강의가 단순화한 것

교육용 모형은 언제나 무언가를 생략합니다. 무엇을 생략했는지 아는 것도 학습의 일부입니다.

전제한 것

  • CDN 계층의 적중률을 85%로 고정해서 준다. 애플리케이션 캐시의 적중률은 항목 인기도와 용량에서 결과로 나온다.
  • 각 계층의 유효 시간이 실행 시간보다 길어서 이 시뮬레이션 동안 만료가 일어나지 않는다. 실제 다단 캐싱의 핵심 난점은 계층마다 다른 만료 시각이다.
  • 이 과제의 트래픽은 전부 읽기다. 다단 구조에서 쓰기가 섞이면 모든 계층을 무효화해야 하고, 그것이 이 구조의 진짜 비용이다.
  • 브라우저 캐시와 데이터베이스 내부 버퍼 캐시는 모델링하지 않는다. 실제 시스템에는 이 두 겹이 더 있다.

다루지 않은 것

  • 계층 간 무효화 전파와 그 지연
  • 브라우저 캐시와 Cache-Control 헤더의 계층별 설정
  • 각 계층의 이중화와 장애 조치
  • 계층별 적중률 관측과 원인 분석 도구

더 읽을거리: RFC 9111 — HTTP Caching · Scaling Memcache at Facebook

이제 직접 만들어 보세요

읽어서 아는 것과 만들어서 아는 것은 다릅니다. 컴포넌트를 배치하고 트래픽을 흘려서 실제로 동작하는지 확인해 보세요.

실습 과제 열기

이 강의에 물어보기

하루 5번

이 강의 본문만 근거로 답합니다. 강의에 없는 내용은 지어내지 않습니다.