본문 바로가기

카테고리 없음

CDN 캐시키 설계: 쿠키/쿼리스트링/디바이스별 분기 베스트프랙티스

CDN 성능은 “얼마나 잘 캐시하느냐”에서 갈립니다. 그리고 캐시의 성패는 캐시키(Cache Key) 설계가 80%를 좌우해요. 같은 리소스인데 쿠키, 쿼리스트링, 디바이스 구분 때문에 키가 쓸데없이 달라지면 히트가 쪼개지고 비용만 늘어납니다. 오늘은 운영자 입장에서 안전하게 히트를 키우는 설계법을 정리해드릴게요.

1) 캐시키의 기본 원리: “동일한 건 동일하게”

캐시키는 CDN이 “이 요청은 어떤 오브젝트와 같냐”를 판단하는 기준입니다.
기본 구성 요소는 보통 스킴(https), 호스트, 경로, 쿼리스트링, 헤더, 쿠키, 디바이스 시그널이에요.
원칙은 간단합니다.

  • 동일 콘텐츠는 동일 키 → 캐시 적중률↑, 오리진 부하↓
  • 컨텍스트가 달라 콘텐츠가 달라지면 그때만 키를 다르게

즉, 최소 키(minimal key) 철학을 가져가면 불필요한 미스가 크게 줄어듭니다.

2) 쿼리스트링: 화이트리스트 방식이 정답

대부분의 페이지/정적 리소스는 쿼리스트링이 달라도 내용이 같거나, 일부만 의미가 있어요. 그래서:

  • 화이트리스트: ?v=, ?id=처럼 콘텐츠에 실제 영향을 주는 파라미터만 키에 포함
  • 블랙리스트: utm_*, gclid, fbclid, ref 등 트래킹 파라미터는 무시
  • 정렬·페이지네이션: 목록 API처럼 결과가 달라지는 파라미터(page, sort)는 포함하되 표준 순서로 정렬하여 키 안정화
  • 중복·순서: 파라미터 정렬/중복 제거/소문자화로 키 일관성 확보

예시(개념):

  • 포함: ?v, lang, size
  • 제외: utm_*, nid, vercel-cache, timestamp(노이즈)

3) 쿠키: 기본은 “완전 배제”, 꼭 필요할 때만 선택 포함

쿠키는 키 폭발의 주범입니다. 원칙은 세 가지:

  1. 기본 배제: 로그인 세션, A/B 실험, 분석 쿠키는 키에서 제외
  2. 스코프 쿠키만 포함: 콘텐츠를 실제로 바꾸는 소수의 쿠키(예: theme=dark, region=KR)만 선택 포함
  3. 정규화: 포함하는 쿠키도 서브셋과 순서를 고정(없는 건 공백 처리)

주의: 개인화 페이지는 오브젝트 캐시가 아니라 에지 동적(ESI/RSC/서버사이드 캐시) 로 분리하는 게 안전합니다.

4) 디바이스별 분기: UA 파싱 대신 Client Hints

모바일/데스크톱, 고밀도 디스플레이, 이미지 포맷(AVIF/WebP) 등은 변형 콘텐츠가 필요하죠. 예전엔 User-Agent 파싱을 썼지만 불안정합니다. 이제는 Client Hints로 간결하게:

  • Sec-CH-UA, Sec-CH-UA-Platform, Sec-CH-UA-Model
  • 이미지 최적화: Accept(AVIF/WEBP), DPR, Width
  • 캐시키는 실제 변형에 필요한 힌트만 포함: 예) Accept + DPR + Width(버킷화)
  • Vary 헤더 관리: Vary: Accept, DPR, Width (남용 금지, 꼭 필요한 항목만)

팁: Width/DPR는 버킷(예: 320/640/960/1280) 으로 그룹화해 키 폭발을 막으세요.

5) 퍼스널라이제이션과 캐시의 공존

개인화가 필요하면 오브젝트 캐시를 포기할 게 아니라 레이어를 분리합니다.

  • ESI/Fragments: 공통 레이아웃은 장기 캐시, 개인화 조각만 짧게/미캐시
  • 캐시 키에 토큰 포함 금지: Authorization, Cookie 전면 포함은 최후의 수단
  • A/B 테스트: 실험 배정은 서버에서 결정→캐시 무관 파라미터/쿠키로 전달, 콘텐츠가 달라지지 않으면 키에 포함하지 않기

6) 이미지/정적 자원 베스트프랙티스

  • 파일명에 해시(fingerprint) → 캐시 무효화 문제 원천 차단
  • 쿼리 버저닝은 최소화: ?v=123 대신 파일명 해시가 적중률에 유리
  • 포맷 협상: Accept 기반으로 AVIF/WebP 전송 시 그 헤더만 Vary
  • 리사이즈 파라미터 정규화: w/h/q 값은 표준 그리드로 제한

7) API 캐시키: 아이템포턴트는 키 최소화, 상태 변경은 미캐시

  • GET API: 의미 있는 파라미터만 포함(필터, 페이징, 정렬). utm_*는 제외
  • POST/PUT: 보통 오브젝트 캐시 제외(대신 프록시 캐시/서킷브레이커 고려)
  • 인증 헤더: Authorization이 있어도 공통 응답이면 키에서 제외하고, 사용자별이면 캐시하지 않기가 원칙

8) 캐시 중복/폭발을 줄이는 정규화 규칙

  • 파라미터 소문자화 + 정렬
  • 빈 값/디폴트 값 제거: ?page=1은 파라미터 제거하여 동일 키
  • Trailing Slash/Index 통일: /about 과 /about/ 같은 경로는 하나로
  • HTTP→HTTPS 리디렉션 고정: 스킴 혼용으로 다른 키가 생기지 않도록

9) 운영 체크리스트(현업용)

  1. 키 정의 문서화: “경로/쿼리/헤더/쿠키/디바이스 중 무엇을 포함/제외하는지”를 표로 고정
  2. 쿼리 화이트리스트 배포: 트래킹 파라미터는 전부 제거
  3. 쿠키 선택 포함: 실제 콘텐츠를 바꾸는 1~3개만
  4. Client Hints 기반 디바이스 분기: Accept, DPR, Width 중심, 버킷화 필수
  5. Vary 최소화: 꼭 필요한 헤더만 남기고 정기 점검
  6. 히트/미스/에이지 모니터링: p50/90 TTFB, 오리진 QPS, 캐시 스토리지 사용량
  7. 스키마 테스트: 키 변경 전 카나리로 5~10% 트래픽만 전환해 히트율·에러율 확인
  8. 무효화 전략: 가능하면 파일명 해시로 “무효화 없이” 운영, 꼭 필요할 때만 패턴 무효화

10) 흔한 실수와 대처

  • 문제 1: 히트율이 낮다
    → 쿼리/쿠키 포함 항목을 과하게 잡았을 가능성. 로그 샘플링으로 서로 다른 키 개수를 집계해 상위 원인을 제거하세요.
  • 문제 2: 개인화가 섞여 캐시 오염
    → 개인화 조각을 분리(ESI/서버사이드 분할), Set-Cookie 전송 조건을 조정.
  • 문제 3: 이미지 키 폭발
    → Width/DPR 버킷화 + 허용 파라미터 화이트리스트로 한정.
  • 문제 4: Vary 남용
    → Vary: * 수준의 과잉 설정은 캐시 무력화. 꼭 필요한 헤더만 남기고 주기 점검.

11) 간단 예시(개념)

  • 페이지: 경로 + lang만 포함, utm_*/gclid 제외, 쿠키 전부 제외
  • 이미지: 경로 + w(320/640/960/1280만 허용) + q(=75/85) + Accept
  • API(GET): 경로 + page, sort, filter만 포함, 파라미터 정렬/소문자화

마무리

캐시키 설계는 “필요한 것만 포함하고, 나머지는 지워 일관성을 높이는 작업”입니다.
쿼리 화이트리스트, 쿠키 선택 포함, Client Hints 기반 디바이스 분기, Vary 최소화—이 네 가지만 지켜도 히트율이 눈에 띄게 올라가고, 오리진 비용과 지연이 동시에 내려갑니다.
운영은 문서화+모니터링+카나리 배포로 반복적으로 다듬어 주세요. 캐시는 한 번에 완성되는 게 아니라 지속적으로 학습되는 설계입니다.

추천 키워드: CDN, 캐시키, 캐시 설계, 쿠키, 쿼리스트링, Client Hints,