들어가며 — 당신이 보는 웹의 99%는 Edge에서 온다
2026년 현재 주요 웹사이트에 접속하면, 당신이 받는 바이트의 거의 전부는 original 서버가 아니라 edge 서버에서 온다. Cloudflare는 전 세계 300+ 도시, Akamai는 4,000+ 위치, Fastly는 수십 개 주요 PoP에 서버를 둔다. 이 edge 서버들이 HTML, 이미지, JS, 비디오를 캐시하고, 실시간 규칙 변환을 적용하고, TLS를 종료하고, DDoS를 흡수한다.
이 계층 없이 현대 웹은 불가능하다. Netflix가 하루 1EB를 스트리밍하면서 origin 서버를 망가뜨리지 않는 이유는 edge 때문이다. 쇼핑몰이 블랙프라이데이에 1000배 트래픽을 견디는 이유, 뉴스 사이트가 기사 하나가 바이럴 될 때 살아남는 이유, 전 세계 사용자가 비슷한 latency로 웹을 쓸 수 있는 이유 — 전부 CDN의 edge caching이 있기에 가능하다.
이 글은 CDN의 모든 것을 1,500줄에 걸쳐 파헤친다. 1998년 Akamai의 탄생, 라우팅의 삼위일체(Anycast + DNS + GSLB), PoP의 물리적 구조, Cache Key 설계의 미묘함, HTTP 캐싱 헤더의 정확한 의미, Origin Shield로 origin을 보호하는 법, Edge Compute의 실행 모델, Image 최적화의 내부 동작, 대역폭 비용 경제학, DDoS 흡수 메커니즘, 그리고 현장의 실제 운영 노하우까지.
이 글은 DNS 글의 자연스러운 후속이다. DNS가 사용자를 edge PoP으로 라우팅한 다음에 일어나는 일을 바이트 수준에서 그린다.
1. CDN의 짧은 역사
1.1 Akamai의 탄생
1995년 MIT 수학 교수 Tom Leighton과 박사과정 학생 Danny Lewin이 "어떻게 하면 웹 콘텐츠를 전 세계에 빠르게 배포할까"를 연구한다. 그들의 아이디어는 수학적이었다: consistent hashing으로 콘텐츠를 여러 서버에 분산하고, 사용자를 가장 가까운 서버로 라우팅하라.
1998년 Akamai Technologies 창업. 1999년 슈퍼볼 중계 웹사이트가 다운됐을 때 Akamai가 트래픽을 처리하면서 CDN이라는 개념이 업계에 알려졌다.
2001년 9/11 테러 때 대형 뉴스 사이트들이 Akamai 덕에 살아남는다. 그 후 CNN, ESPN, Fox News가 Akamai를 표준으로 채택.
1.2 새로운 세대
- 2000년대 중반: CloudFront, Limelight, EdgeCast 등장.
- 2010년: Cloudflare 창업. "DDoS 보호 + CDN"을 무료 플랜으로 번들.
- 2011년: Fastly 창업. "Instant Purge" — 150ms 안에 전 세계 캐시 무효화.
- 2017년: Cloudflare Workers 발표. V8 Isolate 기반 edge compute.
- 2019년: Fastly Compute@Edge. WebAssembly + Rust 기반.
- 2020–2024년: Netflix, AWS, Meta가 자체 CDN을 구축하는 흐름.
2026년 현재 주요 플레이어:
- Cloudflare: 점유율 1위, 개발자 친화적, edge compute 선도.
- Akamai: 엔터프라이즈 지배, 보안 제품군.
- Fastly: 성능 선도, 개발자 친화적.
- Amazon CloudFront: AWS 통합, 가격 경쟁력.
- Google Cloud CDN, Microsoft Azure CDN, Bunny.net, KeyCDN 등.
1.3 왜 CDN이 필요한가 (라텐시의 수학)
빛은 1초에 30만 km. 광섬유에서는 그 2/3 속도. 서울에서 뉴욕까지 편도 11,000km → 최소 55ms RTT는 110ms. 실제로는 라우팅 hop과 큐잉으로 180–250ms.
TLS + HTTP 요청이 3–4 RTT면 1초 가까이 간다. 사용자가 버튼을 클릭하고 반응을 볼 때까지 1초 지연. UX 파탄.
CDN은 사용자와 물리적 거리를 줄인다:
- 서울 사용자 → 서울 edge PoP: 5–10ms RTT.
- 원본 서버는 여전히 미국에 있더라도 edge가 대부분 요청 처리.
물리법칙을 이긴 게 아니라 피해간 것이다.
2. CDN의 세 기둥
2.1 라우팅의 삼위일체
사용자를 가장 가까운 edge로 보내는 세 가지 메커니즘:
- Anycast BGP: 같은 IP를 여러 지역이 광고 → BGP가 "가까운" 곳으로 라우팅.
- DNS 기반 라우팅 (GSLB): 사용자 IP의 지역에 따라 다른 edge IP 반환.
- HTTP 기반 리다이렉트: 초기 요청 후 더 가까운 edge로 리다이렉트 (레거시).
주요 CDN은 보통 Anycast + GSLB 혼합.
2.2 Anycast의 장점과 한계
장점:
- DNS 변경 없이 즉시 라우팅 조정.
- BGP 변경 단위로 페일오버 (분 단위).
- 운영 단순.
한계:
- BGP가 "네트워크 거리"만 보지 "서버 부하"는 모름.
- route flap 시 TCP 연결 끊김.
- 지리와 네트워크 경로가 항상 일치하지는 않음 (사우디 요청이 네덜란드로 갈 수 있음).
2.3 GSLB (Global Server Load Balancing)
DNS 기반. Authoritative 서버가 요청자 IP(EDNS Client Subnet이 있으면 더 정확)의 지역에 맞는 edge IP를 반환.
(Tokyo 사용자) → resolver → Authoritative: "www.example.com?"
← Authoritative: "192.0.2.100" (Tokyo PoP)
(London 사용자) → resolver → Authoritative: "www.example.com?"
← Authoritative: "203.0.113.50" (Amsterdam PoP)
장점:
- 서버 부하, 지연, 지역 규제 등 고려한 정교한 결정.
- TCP 연결이 한 edge에 고정 (안정).
한계:
- DNS TTL이 라우팅 변경 속도 제한.
- Resolver 위치와 사용자 위치가 다를 수 있음 (퍼블릭 resolver 사용 시).
2.4 PoP (Point of Presence)
한 지역에 배치된 CDN의 물리적 서버 집합. 일반적 구성:
- Tier-1 ISP 네트워크 내 또는 **IXP (Internet Exchange Point)**에 위치.
- 수십~수백 대 서버.
- 로드 밸런서, edge 서버, 캐시 저장소, 네트워크 장비.
- Tier-1 ISP와 직접 peering → BGP 관점에서 유리한 경로.
Cloudflare는 300+ cities, Akamai는 4,000+ locations. 숫자 차이가 큰 이유:
- Cloudflare: 중요한 IXP 위주의 큰 PoP.
- Akamai: ISP 내부에 깊이 침투한 수많은 작은 "embedded" 서버들.
두 모델의 트레이드오프. 큰 PoP는 유지 쉽고 많은 사이트 커버. 작고 많은 서버는 latency 더 낮지만 운영 복잡.
3. Cache Key — CDN의 근본 결정
3.1 Cache Key의 역할
CDN이 캐시에서 객체를 찾을 때 사용하는 식별자. 올바른 key 설계가 hit rate을 결정한다.
기본 cache key:
scheme + host + path + querystring
예:
https://example.com/images/hero.jpg?w=800
이게 전체 cache key가 된다. 같은 URL을 가진 모든 요청이 같은 캐시 항목에 매핑.
3.2 Vary 헤더 — 복잡성의 시작
Vary 응답 헤더는 "이 응답은 이 요청 헤더에 따라 달라진다"고 CDN에 알린다.
Cache-Control: public, max-age=3600
Vary: Accept-Encoding, Accept-Language
CDN이 cache key를 확장: URL + Accept-Encoding 값 + Accept-Language 값. 같은 URL이지만 gzip과 br이 다른 캐시 항목.
Vary의 함정들:
- Vary: User-Agent: 각 브라우저마다 다른 캐시 → hit rate 파탄. 절대 쓰지 말 것.
- Vary: Cookie: 거의 모든 요청에 다른 쿠키 → 캐시 무용지물.
- 너무 많은 Vary: 조합 폭발로 cache population 어려움.
3.3 Query String 정규화
?utm_source=twitter와 ?utm_source=facebook은 같은 콘텐츠여야 하지만 다른 cache key가 된다. CDN의 "query string normalization" 기능으로 특정 파라미터 무시:
Cloudflare Cache Rules: remove "utm_*" from cache key
Fastly VCL: remove "utm_*" before cache lookup
반대로 중요 파라미터는 명시적 포함:
/search?q=...→q만 cache key에 포함./product?id=...→id포함, tracking 파라미터 제거.
3.4 Cookie와 Personalization
쿠키 있으면 보통 캐시 안 함 (사용자별 다름). 하지만 특정 쿠키만 의미 있으면 다르게:
__logged_in=1유무로 캐시 분리: 익명 사용자에겐 정적 페이지, 로그인 사용자에겐 SSR.- A/B 테스트:
ab_variant=B쿠키로 분리.
CDN의 "Cache by Cookie" 기능. Cloudflare의 "Bypass Cache on Cookie", Fastly VCL의 req.http.Cookie 조작.
3.5 Device Type 기반 분리
Accept-CH: Sec-CH-UA-Mobile 같은 클라이언트 힌트로 모바일/데스크탑 구분. 한 URL이 디바이스별로 다른 HTML 반환 시 필요.
안티패턴: User-Agent 전체를 Vary → cache 폭발. 패턴: 서버가 User-Agent 파싱 후 Vary: X-Device-Type 같은 축소 값으로 변환.
4. HTTP 캐싱 헤더 — 정확한 의미
4.1 Cache-Control
가장 중요한 캐싱 헤더. 디렉티브 조합:
응답 기준:
public: 어떤 캐시든 가능 (브라우저 + CDN).private: 브라우저만 (CDN은 캐시 금지).no-cache: 캐시하되 매번 origin에 유효성 확인.no-store: 절대 캐시 금지.max-age=N: N초 동안 fresh.s-maxage=N: CDN만을 위한 max-age. 브라우저는 무시.immutable: 콘텐츠가 영원히 불변 (폰트, hashed JS 등).stale-while-revalidate=N: 만료 후 N초는 stale을 주면서 백그라운드 갱신.stale-if-error=N: origin 오류 시 N초 동안 stale 반환.
요청 기준:
no-cache: 캐시된 응답 무시하고 origin에서 가져와.only-if-cached: 캐시 없으면 504 반환 (오프라인 모드).
4.2 전형적 패턴들
정적 자산 (hashed filename):
Cache-Control: public, max-age=31536000, immutable
파일명에 해시가 있으므로(app.a3f2b1.js) 변경 시 URL이 바뀜 → 영원히 캐시 안전.
HTML:
Cache-Control: public, max-age=60, s-maxage=300, stale-while-revalidate=3600
브라우저 1분, CDN 5분, 그 후 1시간은 stale 허용(갱신은 백그라운드).
API 응답 (공개 데이터):
Cache-Control: public, max-age=10, stale-while-revalidate=60
개인화 응답:
Cache-Control: private, no-cache
브라우저는 캐시 가능하지만 매번 유효성 확인.
민감 데이터:
Cache-Control: no-store
4.3 ETag와 조건부 요청
ETag는 응답의 버전 식별자. 내용이 바뀌면 ETag도 바뀜.
HTTP/1.1 200 OK
ETag: "a3f2b1c4"
Cache-Control: max-age=60
60초 후 브라우저(또는 CDN)가 재요청 시:
GET /page HTTP/1.1
If-None-Match: "a3f2b1c4"
서버가 내용이 바뀌지 않았으면:
HTTP/1.1 304 Not Modified
본문 없이 304만 반환. 대역폭 절약.
Strong vs Weak ETag:
"a3f2b1c4": strong — 바이트 단위 동일.W/"a3f2b1c4": weak — 의미적으로 동일 (예: 응답이 gzip vs br만 다름).
4.4 Last-Modified와 If-Modified-Since
ETag 대안. 파일의 변경 시각 기반.
Last-Modified: Wed, 15 Apr 2026 12:00:00 GMT
If-Modified-Since: Wed, 15 Apr 2026 12:00:00 GMT
시계 문제 있고 해상도가 초라 부정확. 현대 시스템은 ETag 선호.
4.5 stale-while-revalidate — 가장 과소평가된 기능
Cache-Control: max-age=10, stale-while-revalidate=3600
만료 후 1시간 동안은:
- 캐시된 (stale) 응답 즉시 반환.
- 백그라운드에서 origin 갱신 요청.
- 다음 요청부터는 fresh 버전 반환.
사용자 체감은 항상 캐시 속도. Origin 부하는 첫 갱신 요청 하나. SWR (stale-while-revalidate)가 제대로 적용된 서비스는 origin의 트래픽이 놀랍게 적다.
2024년부터 Cloudflare, Fastly, CloudFront 모두 SWR 기본 지원. 2026년 현재는 사용하지 않는 게 이상한 수준.
4.6 Age와 X-Cache 헤더
응답을 받았을 때 CDN이 추가:
Age: 123 # 캐시에 들어간 지 123초
X-Cache: HIT # 캐시 적중
X-Cache-Hits: 5 # 이 객체를 5번 서빙
CF-Cache-Status: HIT # Cloudflare 전용
디버깅의 표준 도구. X-Cache: MISS가 나오면 왜 캐시 안 탔는지 조사.
5. Origin Shield와 Tiered Caching
5.1 일반적 CDN의 위험
Edge PoP 수백 개. 각각이 동일한 origin을 뒤에 둠. 원본 응답이 캐시 만료되면 수백 개 edge가 동시에 origin에 요청 → origin 폭발.
더 나쁜 경우: 핫 콘텐츠 발표 순간 전 세계 edge에서 cold cache → origin DDoS. "Thundering herd" 문제.
5.2 Origin Shield의 개념
Edge와 origin 사이에 단일 중간 캐시 계층 삽입:
User → Edge PoP (전 세계 수백) → Origin Shield PoP (1~몇 개) → Origin
- Edge cache miss → Origin Shield에 요청 (origin 아님).
- Shield cache miss → origin에 요청.
- Shield가 한 번 받아오면 모든 edge가 공유.
효과: origin 부하 10–100배 감소.
5.3 구현 형태
- Cloudflare Tiered Cache / Argo Smart Routing: 각 edge PoP이 "upper tier" 데이터센터로 먼저 조회.
- AWS CloudFront Origin Shield: 특정 region 하나를 shield로 지정.
- Akamai Tiered Distribution: 기본 아키텍처가 이미 다단.
- Fastly Shielding: 쿼리로 어느 PoP을 shield로 쓸지 지정.
5.4 Cache Coalescing (Request Collapsing)
같은 객체에 대한 동시 요청 여럿이 miss면, edge는 한 번만 origin(or shield)에 요청하고 나머지는 기다림.
Nginx의 proxy_cache_lock on, Cloudflare의 자동 request collapsing, Fastly의 request collapsing (기본 활성).
수천 사용자가 동시에 같은 바이럴 콘텐츠를 요청해도 origin 부하는 한 요청.
5.5 Cache Hierarchies의 진화
2020년대 이후 CDN들은 "cache 계층을 더 쌓는" 방향으로 간다:
Browser cache
→ Service Worker cache (PWA)
→ CDN Edge cache
→ CDN Regional cache (mid-tier)
→ Origin Shield
→ Origin
각 계층이 hit ratio 95%+면 origin 실제 부하는 0.001% 수준. 이것이 "99.9% offload" 같은 CDN 마케팅 숫자의 실체.
6. Purge — 캐시 무효화의 기술
6.1 왜 Purge가 어려운가
분산 시스템 필연의 문제: 수백 개 PoP의 캐시를 "동시에" 지울 수 있는가?
- 순차 purge → 수초~수분. 그 사이 어느 사용자는 구 콘텐츠 봄.
- 병렬 purge → 수백 개 요청을 즉시 전파해야 함 → 메시지 버스 필요.
6.2 Purge 전략
URL 기반 (가장 일반적):
POST /api/purge
{ "urls": ["https://example.com/page", "https://example.com/image.jpg"] }
Tag 기반 (surrogate key):
응답에 Surrogate-Key: product-123 category-electronics 추가. purge 시 product-123 태그로 일괄 무효화.
Fastly가 이 기능의 선구자. 상품 하나 업데이트 시 관련 페이지 수백 개 한 번에 purge.
Prefix 기반:
/products/* 같은 패턴. 구현은 CDN마다 다름 (O(N) 스캔이거나 radix tree).
Full site purge: "모두 지워". 비상 수단. origin 폭주의 원인이 되므로 신중히.
6.3 속도 차이
- Cloudflare: 보통 30초 내 전 세계. 태그 기반은 150ms 내.
- Fastly: "Instant Purge" — 150ms 내.
- AWS CloudFront: 수 분 (10–15분). 느리다.
CloudFront의 느린 purge가 아키텍처 선택의 이유가 되곤 한다. Netflix 같은 대형 사용자는 purge보다는 "versioned URLs"로 우회.
6.4 Versioned URLs — Purge 없이 사는 법
<link rel="stylesheet" href="/static/app.v3f2b1a.css">
새 배포 시:
- 새 해시 URL로 파일 빌드.
- HTML만 업데이트 (HTML은 짧은 TTL).
- 기존 캐시된 파일은 자연스레 죽음.
핵심 아이디어: 변경되면 URL이 바뀐다. Purge가 필요 없다. 대부분의 SPA, Next.js, SvelteKit 빌드가 이 방식.
6.5 Soft Purge vs Hard Purge
- Hard Purge: 캐시 즉시 삭제. 다음 요청은 miss.
- Soft Purge: 캐시를 stale로 마크. stale-while-revalidate로 즉시 응답 + 백그라운드 갱신.
Soft purge가 소비자 경험에 훨씬 부드럽다. Fastly가 도입, 이제 대부분 CDN이 지원.
7. Edge Compute — 코드가 edge로 간다
7.1 Edge Compute가 필요한 이유
정적 캐싱만으로 안 되는 것들:
- A/B 테스트의 분기 로직.
- 사용자 인증, JWT 검증.
- 지리 기반 리다이렉트.
- 개인화된 응답.
- API 응답의 경량 변환 (JSON 필드 재배열).
Origin에서 하면 RTT 추가. Edge에서 처리하면 사용자와 가까운 곳에서 즉시.
7.2 Cloudflare Workers — V8 Isolate 모델
2017년 발표. V8 isolate 기반 — 컨테이너/VM 아닌 JS 엔진 수준의 샌드박스.
export default {
async fetch(request, env, ctx) {
const url = new URL(request.url);
if (url.pathname === '/hello') {
return new Response('Hello from edge!');
}
// 기본: origin으로 포워딩
return fetch(request);
}
};
- Cold start: 5ms 이하 (컨테이너의 100ms+ 대비).
- 메모리: 128MB per isolate.
- CPU time: 10ms–50ms 기본 한도.
- 분리: 한 worker가 다른 worker 상태 못 봄.
이 가벼움의 비결은 V8 isolate가 프로세스/스레드 생성 없이 격리된 실행 컨텍스트를 만들 수 있는 것. 수만 개 worker가 한 프로세스에서 돌 수 있다.
7.3 Cloudflare Workers의 생태계
- KV: 글로벌 key-value, 최종 일관성. 읽기 빠름, 쓰기 전파 수 초.
- Durable Objects: 단일 인스턴스 stateful. actor 모델.
- D1: SQLite 기반 edge DB.
- R2: S3 호환 object storage. egress 비용 없음.
- Queues: 비동기 메시징.
- Workers Analytics Engine: 시계열 분석.
- AI: LLM 추론 (Llama, Mistral 등).
"backend-as-a-service at edge" — 전통적 서버리스와 구별되는 생태계.
7.4 Fastly Compute@Edge — WebAssembly 모델
2019년 발표. Wasmtime으로 WebAssembly 실행. Rust, AssemblyScript, Go(TinyGo) 지원.
use fastly::http::StatusCode;
use fastly::{Request, Response};
#[fastly::main]
fn main(req: Request) -> Result<Response, Error> {
if req.get_path() == "/hello" {
return Ok(Response::from_status(StatusCode::OK)
.with_body_text_plain("Hello from WASM!"));
}
Ok(req.send("origin_0")?)
}
- Cold start: 50ms 이하.
- 각 요청이 독립 WASM instance → 강한 격리.
- Rust의 성능과 안전성.
7.5 AWS Lambda@Edge vs CloudFront Functions
- Lambda@Edge: 일반 Lambda, Node.js/Python. cold start 있음 (100ms+). viewer request/response, origin request/response 네 지점에서 실행.
- CloudFront Functions: 2021년 발표. V8 기반 초경량. viewer request/response만. 1ms 이하.
Cloudflare Workers의 영향을 받은 CloudFront Functions가 AWS 고객에게 비슷한 경험 제공.
7.6 Vercel Edge Functions — Next.js 통합
Vercel이 Cloudflare Workers 플랫폼 위에 자체 추상. Next.js의 export const runtime = 'edge'로 함수를 edge에서 실행. 프레임워크가 서버리스 경계를 숨긴다.
2024–2026년 Next.js, Astro, Remix, SvelteKit 모두 edge runtime 지원. "어디서 실행되는가"가 프레임워크 문제가 아닌 배포 옵션.
7.7 Edge Compute의 한계
- CPU/메모리 제한: 무거운 계산은 origin으로.
- 파일시스템 없음: 상태는 KV/DB/cache로.
- 장시간 연결 어려움: WebSocket은 지원하지만 connection limits.
- 디버깅 복잡: 글로벌 로그 수집이 필수.
그래서 edge는 "HTTP 경로 변환, 인증, 캐시 결정, 라이트 API"가 주 영역. 무거운 작업은 여전히 origin에.
8. Image/Video 최적화
8.1 왜 이미지가 중요한가
웹 페이지 전송 바이트의 50%+가 이미지. 이미지 최적화 = 페이지 로드 속도 + 대역폭 비용 = UX + 돈.
8.2 포맷 선택
- JPEG: 1992년부터. 여전히 호환성 왕.
- PNG: 무손실. 아이콘, 투명 배경.
- WebP (Google, 2010): JPEG 대비 25–35% 작음.
- AVIF (Alliance for Open Media, 2019): WebP 대비 추가 30% 작음. AV1 코덱 기반.
- JPEG XL (JPEG 그룹, 2021): 고품질 무손실 + 손실 호환. Chrome이 2022년에 잠깐 지원하다 제거, 2024년 다시 실험 플래그.
8.3 Content Negotiation
브라우저가 Accept 헤더로 지원 포맷을 알림:
Accept: image/avif,image/webp,image/apng,image/*,*/*;q=0.8
CDN이 이 헤더 기반으로 다른 포맷 반환. <picture> 요소 없이 한 URL로 최적 포맷.
Cloudflare Polish, Fastly Image Optimizer, CloudFront (Lambda@Edge 통해), Imgix, Cloudinary 등이 이 기능 제공.
8.4 Responsive Images
디스플레이 크기별로 다른 이미지:
<img src="hero.jpg"
srcset="hero-400.jpg 400w, hero-800.jpg 800w, hero-1200.jpg 1200w"
sizes="(max-width: 600px) 100vw, 50vw">
CDN이 srcset의 각 URL을 알아서 생성:
https://cdn.example.com/hero.jpg?width=400&format=auto
https://cdn.example.com/hero.jpg?width=800&format=auto
format=auto가 accept 헤더 기반 최적 포맷. 각 URL이 별도 cache key로 저장.
8.5 Video — HLS와 DASH
스트리밍의 실제는 HTTP 기반 적응형 스트리밍:
- HLS (HTTP Live Streaming, Apple):
.m3u8playlist +.ts세그먼트. - MPEG-DASH:
.mpdmanifest + 세그먼트. - CMAF (Common Media Application Format): HLS/DASH 공통 포맷.
서버가 비디오를 여러 해상도 × 여러 비트레이트로 인코딩 → 작은 세그먼트(2–10초)로 쪼갬 → 각 세그먼트가 개별 HTTP GET으로 다운. 네트워크 상태에 따라 세그먼트별로 품질 조정.
CDN에게는 수많은 작은 정적 파일의 집합. 캐싱이 매우 잘 됨. Netflix, YouTube, Twitch가 이 모델로 스케일.
8.6 Perceptual Quality Metrics
"얼마나 압축할 것인가"의 결정. 파일 크기 vs 시각 품질.
- PSNR: 고전. 픽셀 차이 기반. 사람 지각과 안 맞음.
- SSIM: 구조적 유사도. PSNR보다 나음.
- VMAF (Netflix, 2016): 머신러닝으로 실제 사람 평가 예측. 업계 표준이 됨.
Netflix는 같은 콘텐츠를 수백 가지 인코딩 조합으로 만들어 VMAF 높은 것만 선택. 대역폭 20% 절감.
9. TLS Termination과 보안
9.1 TLS Termination at Edge
사용자 ↔ edge 사이 TLS 종료. edge ↔ origin 사이는 별도 TLS (또는 사설망).
User --TLS 1.3 (X25519)--> Edge --TLS (mutual auth)--> Origin
장점:
- 인증서 관리 중앙화.
- 최신 TLS/QUIC을 edge에서 즉시 배포.
- TLS 핸드셰이크를 사용자 가까이에서 → RTT 감소.
9.2 Universal SSL (Cloudflare 2014)
Cloudflare가 "모든 고객에게 무료 SSL" 발표. SNI를 활용해 한 IP에 수천 도메인 호스팅. Let's Encrypt 이전 시대의 혁명.
지금은 HTTP/3, ECH까지 edge에서 자동 적용.
9.3 Origin 보호
Edge가 있어도 origin이 공개돼 있으면 공격자가 edge를 우회. 방어:
- Authenticated Origin Pulls: origin이 CDN의 client cert만 허용.
- IP 제한: CDN의 IP 범위만 origin이 accept.
- Origin 숨기기: origin DNS 이름 공개 안 함.
- Cloudflare Tunnel 같은 reverse tunnel: origin이 outbound 연결만.
9.4 DDoS 흡수
CDN의 대역폭 용량은 수 Tbps 규모. 작은 origin 서버(수 Gbps)보다 1000배 많음. 공격 트래픽을 edge가 흡수 → origin 보호.
주요 CDN의 공격 완화 능력:
- Cloudflare: 228 Tbps 글로벌 용량 (2025년 수치).
- Akamai: 비슷한 규모.
- AWS Shield Advanced: AWS 계정 보호.
알려진 최대 공격 (2023 공식 기록): 398 Tbps HTTP/2 Rapid Reset. Cloudflare/Google/AWS가 동시 완화.
9.5 Bot 관리
트래픽의 30–50%가 봇이라는 통계. 일부는 합법(Googlebot, Bingbot), 대부분은 악성(스크래퍼, credential stuffing).
CDN의 bot 관리:
- Fingerprinting: TLS/HTTP2 fingerprint, JA3 해시.
- Challenge: JS challenge, CAPTCHA, Cloudflare Turnstile.
- Behavioral: 마우스 움직임, 클릭 패턴 분석.
- ML classification: 수백 개 시그널로 bot score.
Cloudflare Bot Management, Akamai Bot Manager, Fastly Bot Management가 이 시장. 전통 CAPTCHA는 접근성 문제로 밀려나는 중.
9.6 WAF (Web Application Firewall)
SQL injection, XSS, RCE 등을 edge에서 차단.
- 규칙 기반: OWASP Core Rule Set (CRS)이 표준.
- 커스텀 규칙: 자사 API 패턴 보호.
- 머신러닝: 이상치 탐지, novel attack 탐지.
클라우드 WAF: Cloudflare WAF, AWS WAF, Akamai AppSec. 전통 on-prem WAF (F5, Imperva)의 대체재.
10. 대역폭 경제학
10.1 Egress 비용의 진실
AWS S3, GCS, Azure Blob이 egress 비용을 청구: 데이터를 "밖으로" 내보낼 때. 안으로(ingress)는 공짜.
2024년 AWS 요금(변동):
- 100TB/월까지: $0.09/GB → 월 9,000달러.
- 1PB/월: ~$0.05/GB 할인 → 월 50,000달러.
웹사이트가 100TB 트래픽이면 CDN 없이 AWS 비용만 월 1,000만 원.
10.2 CDN의 경제학
CDN 요금은 보통 AWS egress의 1/3–1/5:
- Cloudflare: 무료 플랜 있음, 유료는 약 $0.02/GB.
- Fastly: $0.12/GB (비싸지만 성능/기능).
- CloudFront: $0.085/GB.
- Bunny.net: $0.01/GB (저렴형).
그리고 CDN이 대부분을 cache에서 서빙 → origin egress 99%+ 감소. AWS egress + CDN 비용 < AWS egress만.
10.3 R2, B2, Cloudflare R2 — "Zero Egress"
Cloudflare R2, Backblaze B2 가 egress 무료. AWS S3의 egress 청구 모델에 대한 반격.
R2: S3 호환 API, egress 0.015/GB (S3보다 저렴). Cloudflare가 이 모델을 유지할 수 있는 이유 — Cloudflare 네트워크 자체의 트래픽은 이미 sunk cost.
Bandwidth Alliance: Cloudflare + Backblaze + DigitalOcean + Wasabi 등이 서로 간 egress 무료/할인. 멀티클라우드의 경제적 동력.
10.4 P2P와 Peer-Assisted CDN
Netflix의 Open Connect: ISP 내부에 서버 배치 → 해당 ISP 사용자는 ISP 내부에서 영상 받음. ISP도 대외 대역폭 절약 → ISP가 환영.
P2P 방식: 다른 사용자의 브라우저를 peer로 활용. WebTorrent, Peer5 등. 라이센스/프라이버시 이슈로 제한적.
10.5 Cache Hit Ratio의 경제학
95% hit ratio → 5%만 origin 부담. 99% hit ratio → 1%만 origin 부담.
4 percentage points 차이가 origin 비용을 5배 절감. cache key, TTL, purge 전략의 ROI가 거대하다.
11. 실전 설정
11.1 Cache-Control 정책 템플릿
# 정적 자산 (hashed)
Cache-Control: public, max-age=31536000, immutable
# HTML
Cache-Control: public, max-age=60, s-maxage=300, stale-while-revalidate=86400
# 공개 API
Cache-Control: public, max-age=10, s-maxage=60, stale-while-revalidate=300
# 개인화 (로그인 사용자)
Cache-Control: private, max-age=0, must-revalidate
# 비공개 민감 데이터
Cache-Control: no-store
11.2 Cloudflare Page Rules (또는 Cache Rules)
# /static/* — 오래 캐시
Match: (http.request.uri.path matches "^/static/")
Action: Cache Level = Cache Everything
Edge Cache TTL = 1 year
Browser Cache TTL = 1 year
# /api/* — 캐시 안 함
Match: (http.request.uri.path matches "^/api/")
Action: Cache Level = Bypass
# 쿠키로 분기
Match: (http.cookie contains "logged_in=1")
Action: Cache Level = Bypass
11.3 Fastly VCL 예
sub vcl_recv {
# uppercase 경로 정규화
set req.url = std.tolower(req.url);
# tracking 파라미터 제거
set req.url = regsuball(req.url, "(utm_[^&=]+|fbclid|gclid)=[^&]+&?", "");
set req.url = regsub(req.url, "[?&]$", "");
# 로그인 쿠키 있으면 캐시 bypass
if (req.http.Cookie ~ "session=") {
return(pass);
}
}
sub vcl_fetch {
# SWR 추가
if (beresp.http.Cache-Control !~ "stale-while-revalidate") {
set beresp.http.Cache-Control = beresp.http.Cache-Control + ", stale-while-revalidate=3600";
}
}
11.4 Next.js의 edge 최적화
// next.config.js
module.exports = {
async headers() {
return [
{
source: '/_next/static/:path*',
headers: [{ key: 'Cache-Control', value: 'public, max-age=31536000, immutable' }]
},
{
source: '/',
headers: [{ key: 'Cache-Control', value: 'public, max-age=0, s-maxage=300, stale-while-revalidate=86400' }]
}
];
}
};
Vercel에 배포하면 자동으로 edge 네트워크로 배포 → 전 세계 사용자에게 빠름.
11.5 모니터링 지표
- Cache hit ratio: >90% 목표. 낮으면 cache key/TTL 재검토.
- Origin RPS: 갑자기 치솟으면 purge/배포 이슈 의심.
- p99 latency from edge: 지역별.
- Bandwidth egress: origin과 edge 각각.
- 5xx rate: origin vs edge.
Cloudflare Analytics, Fastly Observability, CloudFront CloudWatch 등 기본 제공.
11.6 안티패턴
- Cache-Control 안 설정: 브라우저 기본(heuristic)에 맡김 → 일관성 없음. 반드시 명시.
- Vary: User-Agent: 캐시 폭발. 절대 금지.
- 쿠키 의존 페이지를 캐시: 사용자별 다른 내용이 잘못된 사용자에게 보임. 데이터 유출.
- PII를 쿼리 스트링에: 캐시 키로 들어가 로그/분석에 노출.
- Purge 남용: 변경마다 전면 purge → origin 폭주.
- Origin의 Cache-Control 무시: CDN이 강제 override하면 앱 의도와 어긋남.
12. 최신 트렌드
12.1 HTTP/3 at Edge
Cloudflare, Fastly, CloudFront 모두 HTTP/3 기본 지원. 모바일 사용자에게 특히 효과 — connection migration으로 Wi-Fi ↔ 셀룰러 전환 중에도 끊김 없음.
12.2 Streaming SSR
React Server Components, Next.js App Router의 streaming은 edge와 찰떡. 첫 바이트(TTFB) 수 ms, HTML이 도착하는 대로 점진적 렌더링.
12.3 Edge AI
Cloudflare Workers AI, Fastly AI Accelerator: LLM 추론을 edge에서. 사용자 가까이에서 토큰 생성 → 첫 토큰 지연 대폭 감소.
GPU를 모든 edge PoP에 배치 못 함 → 주요 PoP에 GPU, 나머지는 가까운 GPU PoP으로 라우팅. Edge AI와 Edge Compute의 hybrid.
12.4 Zero Trust Networking
CDN이 확장된 기업 네트워크 되기. Cloudflare Zero Trust (Cloudflare One), Akamai Zero Trust, Zscaler. VPN 대체.
"edge가 모든 트래픽의 관문" 비전. 개인 사용자 → edge → 사내 리소스. identity 기반 접근 제어.
12.5 WebAssembly Components
WASM의 새 인터페이스 표준(Component Model). 언어 간 상호운용 + 안전한 샌드박스. Fastly Compute@Edge가 선도. 여러 언어로 작성된 미들웨어를 조합.
13. 깊이 들어간 운영자를 위한 팁
13.1 Cache 디버깅 루틴
# 응답 헤더 확인
curl -I https://example.com/page
# Cloudflare 디버깅
curl -I https://example.com/page \
-H "X-Cloudflare-Debug: 1"
# 다른 지역에서 테스트 (cloudflare-radar, fastly-network-info)
CF-Cache-Status, X-Cache, Age 헤더를 확인하라. MISS 반복이면 cache key 재검토.
13.2 Cache warming
배포 후 또는 새 지역 추가 시 주요 URL 목록에 미리 요청 → cache populate.
while read url; do
for region in US EU APAC; do
curl -H "X-Test-Region: $region" "$url" > /dev/null &
done
done < critical-urls.txt
13.3 A/B 테스트를 edge에서
// Cloudflare Worker 예시
export default {
async fetch(req) {
const cookie = req.headers.get('Cookie') || '';
let variant = cookie.match(/exp=(\w)/)?.[1];
if (!variant) {
variant = Math.random() < 0.5 ? 'A' : 'B';
}
const url = new URL(req.url);
if (variant === 'B') url.pathname = '/v2' + url.pathname;
const resp = await fetch(url, req);
const newResp = new Response(resp.body, resp);
newResp.headers.append('Set-Cookie', `exp=${variant}; Max-Age=2592000`);
return newResp;
}
};
Origin이 모르는 사이 variant 분기. 각 사용자는 쿠키 기반으로 고정 variant 유지.
13.4 Incident 대응
"갑자기 트래픽이 origin에 몰려요":
- CDN dashboard의 cache hit ratio 확인. 급락했나?
- 최근 purge 이벤트 로그 확인.
- Cache-Control 헤더 설정이 바뀌지 않았나.
- 5xx 응답이 증가했나 (5xx는 캐시 안 됨, origin에 반복 요청).
- Vary 헤더에 새 값이 추가됐나.
대응:
- 임시로 origin shield 활성.
- CDN 설정에서
Edge Cache TTL강제 (origin 무시). - WAF rule로 abuse 패턴 차단.
13.5 "Cache Poisoning" 조심
공격자가 요청 헤더 조작 → 서버가 오염된 응답 생성 → CDN 캐시 → 모든 사용자가 감염.
예: X-Forwarded-Host: attacker.com → 앱이 이를 링크에 사용 → 캐시.
방어: 의심스러운 헤더 제거(unset), cache key에 신뢰할 수 있는 헤더만 포함, canonicalization.
James Kettle의 2018 DEF CON 발표 "Practical Web Cache Poisoning"이 이 분야의 고전.
맺음 — 바이트를 사용자 옆으로
CDN의 본질은 간단하다: 바이트를 사용자 옆에 두라. 그리고 그 간단한 원리가 현대 웹의 속도와 경제성을 가능하게 한다.
운영자로서 본능적으로 체크할 세 가지:
- Cache hit ratio를 측정하라. 90% 이상이 기본. 낮으면 설정 문제.
- Cache-Control 헤더를 의도적으로 써라. 기본값 의존은 재앙. SWR은 반드시 추가.
- Origin shield/tiered cache를 활용하라. 무료/저비용인데 origin 부하 10배 감소.
이 세 가지만 제대로면 CDN이 약속한 속도와 절감의 90%를 얻는다.
더 넓게 보면, 지난 세 글은 웹 요청의 여정을 라우팅부터 응답까지 추적했다:
- DNS: 이름 해결.
- TLS 1.3 + QUIC: 안전한 채널 수립.
- CDN (이 글): 바이트의 실제 전달.
HTTPS 요청 한 번을 1 ms부터 100 ms까지 바이트 단위로 설명할 수 있는 엔지니어는 장애 대응에서 30초 안에 원인을 짚어낸다.
다음 글은 Git 내부 구조 — 객체 모델, 참조, 팩 파일, rebase의 실제 동작을 다룬다. 매일 쓰지만 거의 아무도 내부를 모르는 도구. 바이트 수준에서 풀어낸다.
현재 단락 (1/437)
2026년 현재 주요 웹사이트에 접속하면, 당신이 받는 바이트의 거의 전부는 **original 서버**가 아니라 **edge 서버**에서 온다. Cloudflare는 전 세계 3...