CDN 서버 캐시 최적화하기

동적 콘텐츠 분류에 따른 캐싱 미적용 현상

최근 게임 서버의 API 응답 속도를 분석하던 중, 정적 파일과 달리 JSON 데이터가 캐싱되지 않는 현상을 발견했다. 원인은 Cloudflare의 기본 정책상 HTML이나 JSON과 같은 텍스트 기반 데이터가 동적 콘텐츠로 분류되기 때문이었다. 응답 헤더의 CF-Cache-Status: DYNAMIC 상태는 사용자의 요청이 CDN을 바이패스하여 Origin 서버로 직결됨을 의미하며, 결과적으로 Origin 서버의 부하를 가중시키는 요인이 된다.

https://developers.cloudflare.com/cache/concepts/default-cache-behavior Default cached file extensions "Cloudflare only caches based on file extension and not by MIME type. The Cloudflare CDN does not cache HTML or JSON by default. Additionally, by default Cloudflare caches a website's robots.txt."

sequenceDiagram participant U as Client participant CF as Cloudflare Edge participant O as Origin Server Note over CF: 기본 정책: JSON 캐싱 미지원 (DYNAMIC) U->>CF: GET /char.json 요청 CF->>O: 요청 바이패스 O-->>CF: JSON 데이터 반환 CF-->>U: JSON 데이터 응답 (Cache-Status: DYNAMIC)

1차 방안: Cache Rules를 활용한 강제 캐싱 도입

정적 자산(CSS, JS)은 파일명 해시를 통해 버전을 관리(Cache Busting)하기 쉽지만, API 엔드포인트는 리소스의 고유 식별자로서 URL이 고정되어야 하므로 파일명을 변경하는 방식을 적용하기 어렵다.

Cache Busting 사용자 브라우저가 최신 버전의 파일을 다운로드하도록 강제하는 방법

상기 문제를 해결하기 위한 일차적 접근으로 Cloudflare의 Cache Rules 설정을 활용한다. 이는 특정 확장자(*.json)를 가진 요청에 대해 Edge 캐시 TTL을 강제 적용하여 Origin 요청 빈도를 줄인다.

  • s-maxage (Edge TTL): 중간 서버의 캐시 유효 시간
  • max-age (Browser TTL): 사용자 브라우저의 캐시 유효 시간

트레이드오프 - 데이터 정합성 문제

그러나 긴 TTL 설정은 필연적으로 데이터의 신선도 저하라는 부작용을 수반한다. 게임 밸런스 패치 등으로 원본 데이터가 수정되더라도, 고유 ID 기반의 URL 구조가 유지되는 한 CDN과 브라우저는 파일의 변경 사실을 인지하지 못한다. 이는 기 설정된 긴 s-maxage 기간 동안 Stale 데이터가 사용자에게 지속적으로 전송되는 결과를 초래하며, 서비스 운영에 치명적인 정보 불일치 문제를 야기한다.

2차 방안: 자동화된 Cache Purge 전략

상기 문제를 근본적으로 해결하기 위해 배포 파이프라인에 캐시 삭제 로직을 통합한다.

sequenceDiagram autonumber actor User as Client participant CF_Edge as CDN participant O as Storage participant GA as Origin actor Dev as Developer rect rgba(235, 197, 145, 0.1) CF_Edge-->>User: GET /char.json Dev->>GA: 버전 업데이트 activate GA GA->>O: 최신 버전 배포 GA->>CF_Edge: purge_cache API 호출 GA->>User: 신호 전송 deactivate GA end rect rgba(82, 129, 172, 0.1) User->>CF_Edge: GET /char.json CF_Edge->>O: Revalidate O-->>CF_Edge: 최신 데이터 반환 CF_Edge-->>User: 최신 데이터 응답 end