사용자와 가까운 곳에 콘텐츠를 복제해 두는 분산 서버 네트워크.
왜 거리가 문제인가
빛은 광섬유에서 초당 약 20만 km 를 간다 서울 ↔ 미국 동부 약 11,000km → 편도 최소 55ms, 왕복 110ms
- 중간 라우터 · 큐잉까지 더하면 실제로는 150~250ms
- 대역폭을 아무리 늘려도 이 시간은 줄지 않는다
대역폭으로 해결 안 되는 것을 거리로 해결한다 — 이것이 CDN의 존재 이유다.
어떻게 가까운 곳으로 보내나
- DNS 기반 — 사용자 위치에 따라 다른 IP 를 응답한다
- Anycast — 같은 IP 를 여러 곳에서 광고하고, 라우팅이 가장 가까운 곳으로 보낸다
캐시 히트와 미스
[사용자] → [엣지 서버] 캐시에 있으면 즉시 응답 (HIT)
│ 없으면
↓
[오리진] 원본 서버에서 가져와 저장 후 응답 (MISS)
curl -I https://example.com/img.png
# x-cache: HIT ← 엣지에서 응답
# age: 3200 ← 캐시된 지 3200초
무엇을 캐시하나
잘 맞는 것 이미지 · CSS · JS · 폰트 · 동영상 (정적이고 모두에게 같다)
- 조건부 — HTML — 사용자마다 다르면 캐시 못 한다 안 되는 것 로그인 후 개인화 페이지 · API 응답 대부분
캐시 무효화 — 가장 까다로운 부분
-
파일을 바꿨는데 사용자는 옛 버전을 본다
-
① Purge API 로 강제 무효화 — 전파에 시간이 걸린다
-
② 파일명에 해시를 붙인다 (권장)
- app.a1b2c3.js → 내용이 바뀌면 이름이 바뀐다
- 무효화가 필요 없다. 새 이름은 어차피 캐시에 없다
- HTML 만 짧게 캐시하고 나머지는 영구 캐시로 둘 수 있다
②가 정석이다 — 무효화 문제를 아예 없애 버린다.
그 외에 얻는 것
- 오리진 부하 감소 — 대부분의 요청이 엣지에서 끝난다
- DDoS 완화 — 분산된 엣지가 트래픽을 흡수한다
- TLS 종료를 가까운 곳에서 → 핸드셰이크 왕복이 짧아진다
면접 함정
- ❌ "CDN은 대역폭을 늘려 준다" → 거리를 줄여 지연을 낮추는 것이 본질이다.
- ❌ "동적 콘텐츠는 CDN을 못 쓴다" → TLS 종료·경로 최적화만으로도 이득이 있다.
캐시 정책을 헤더로 통제한다
Cache-Control: public, max-age=31536000, immutable
- 해시 파일명이면 1년 캐시 + 재검증도 안 한다
Cache-Control: public, max-age=0, s-maxage=300
- 브라우저는 매번 확인, CDN 은 5분 캐시 (s-maxage 는 공유 캐시 전용)
Cache-Control: private, no-store
- 개인화 응답. 어디에도 저장하지 않는다
stale-while-revalidate=60
- 만료됐어도 일단 옛 것을 주고 뒤에서 갱신한다 (지연을 숨긴다)
s-maxage로 브라우저와 CDN의 정책을 분리하는 것이 실무의 핵심 기법이다.
캐시 키를 생각한다
기본 캐시 키 = URL
- 쿼리 파라미터가 다르면 다른 항목이 된다
- 추적용 파라미터(utm_source 등)가 붙으면 캐시가 산산조각 난다
- 캐시 키에서 제외하도록 설정한다
Vary 헤더에 든 것도 키에 포함된다
- Vary: User-Agent 는 사실상 캐시를 무력화한다 (UA 가 수천 종류다)