Cloudflare Tiered Cache, 캐시를 캐싱해서 CDN 응답 속도 최적화하기
많은 개발자이 오리진 서버의 부하를 감소시키고, 정적 파일 또는 캐싱 가능한 응답을 고객에게 빠르게 제공하기 위해서 CDN 서비스를 이용합니다. 개발자들이 선호하는 AWS Cloudfront의 경우 성능과 안정성은 의심의 여지가 없지만 단점은 요청당 비용, 데이터 전송료라는 예측할 수 없는 요소들이 존재한다는 것입니다.
이러한 AWS의 과금 체계에 맞서 Cloudflare는 Bandwidth Alliance를 결성했습니다. 이 연합은 Cloudflare와 구글 클라우드, Azure 등 주요 클라우드 인프라 회원사 간의 오리진 데이터 전송(Data Transfer Out) 비용을 면제하거나 대폭 할인해 주는 협정입니다.
특히 원본 서버로 Cloudflare의 객체 스토리지인 R2를 사용할 경우, 데이터 전송료(egress) 비용이 완전히 면제됩니다. 오직 스토리지 용량과 API 요청에 대해서만 과금하며, CDN 엣지 서버에 캐싱된 요청에 대해서는 R2 스토리지까지 도달하지 않고 엣지에서 바로 반환되므로 사용자 트래픽 증가에 따른 API 과금 리스크를 최소화할 수 있습니다.”
S3 API 호환성을 제공하면서 트래픽 비용은 무제한 무료, 전 세계 트래픽의 상당 부분을 처리하는 Cloudflare의 Tiered Cache(계층형 캐시)를 이용해서 원본 서버의 응답을 상위 엣지에서 캐싱, 이를 다시 지역별 하위 엣지에서 캐싱하는 방식으로 오리진 서버 부하를 낮추면서 유의미한 네트워크 성능 향상을 만드는 방법을 소개합니다.
CDN 캐싱
CDN 캐싱의 본질은 자주 요청되는 리소스를 사용자와 가까운 곳에 복사, 요청시 빠르게 응답해주며 원본 서버를 최대한 여유있게 만들어 웹사이트 성능을 높이는 기술입니다.
이를 위해서는
- 물리적인 캐시 서버가 사용자와 지리적으로 가까운 곳에 위치해야 하고
- 네트워크 경로의 혼잡을 제어해서 사용자 요청을 최대한 분산 후
- 분산된 사용자와 원본 서버 사이에 최대한 캐싱 계층을 많이 배치해서 최대한 원본까지 요청이 가는 일이 없어야 합니다.
사용자 요청을 가장 가까운 위치에서 받아내기 위해서 Cloudflare는, 전 세계 330개의 지역에 CDN 서버(POP)를 배치해놨다고 합니다.
Edge Cache
엣지 캐시(Edge Cache)란 말 그대로 최종 사용자와 가장 가까운 CDN 서버를 지칭합니다. 한국을 기준으로 생각하면 서울, 부산, 광주 등 지역별 사용자의 요청을 가장 먼저 받아서 처리해주는 서버를 생각하면 되는데요, 현재 클라우드플레어는 한국 통신사의 망 사용료가 비싸다고 주장하는 입장이여서 무료 사용자들에게는 한국 데이터센터가 아닌 해외로(보통 일본, 홍콩, 싱가포르) 트래픽을 우회시켜서 CDN 서비스를 제공 중입니다.
Edge 서버 응답 헤더는 보통 이렇게 표시되는데요, 저희는 이걸 엣지 캐시로 생각하면 됩니다.
- Fukuoka, Japan - (FUK)
- Tokyo, Japan - (NRT)
- Osaka, Japan - (KIX)
- Hong Kong - (HKG)
- Singapore, Singapore - (SIN)
오리진 서버로 Cloudflare의 객체 스토리지 서비스인 R2를 사용하고, 사용자 지정 도메인을 연결하면 특정 HTTP 응답 코드마다 TTL이 적용되어서 엣지 서버에 콘텐츠가 캐싱 됩니다.

Tiered Cache Topology
curl 명령어를 이용해서 이미지 요청 헤더를 확인해 보면, 사용자의 요청은 클라우드플에어 측의 네트워크 상황에 따라서 여러 엣지 서버로 동적으로 라우팅 되는 것을 보실 수 있습니다.
# request 1
curl https://static.hello-cdn.com/image.webp
HTTP/2 200
,..
cf-cache-status: MISS
cf-ray: 970f1f1e398ad1be-KIX # Osaka - Japan
# request 2
curl https://static.hello-cdn.com/image.webp
HTTP/2 200
...
cf-cache-status: MISS
cf-ray: 970f1f0d9fa9fcce-FUK # Fukuoka - Japan
이렇게 여러 엣지 서버로 요청이 분산된다는 것은 가용성이 높아지고, 병목 지점이 분산되는 장점이 있지만, 엣지 서버에 콘텐츠가 캐시 되어있지 않을 때는(Cache Miss) 물리적인 스토리지(SSD, HDD)로 이루어진 원본 서버(여기서는 R2)에 접근하는 빈도가 증가하게 되면서 레이턴시가 증가하는 문제점도 가지고 있습니다.
레이턴시가 증가 문제를 해결하기 위해서 클라우드플레어는 계층형 캐시(Tiered Cache) 사용을 권장하는데요, Tiered Cache란 클라우드플레어 데이터센터와 오리진 서버가 통신하는 계층을 사용자가 직접 지정할 수 있는 옵션입니다.

오리진 서버와 가까울수록 Upper Tier, 사용자와 가까울수록 Lower Tier라고 부르는데요, 각 계층 먼저 가볍게 알아보겠습니다.
- Smart Tiered Cache: Argo Smart Routing 기반으로 오리진과 가까운 가장 성능 좋은 POP 단 하나을 Upper Tier로 선택
- Generic Global Tiered Cache: 지역별로 큰 POP을 Upper Tier로 선택
- Regional Tiered Cache: 지역 단위로 묶인 중간 캐싱 계층. Smart Tiered Cache와 같이 사용함. (ex. 서울 사용자 요청 → 도쿄 Regional Tier → (Smart Tier) 싱가포르 Upper Tier → AWS 싱가포르 오리진)
- Custom Tiered Cache: Upper Tier, Lower Tier 수동 설정 가능
이렇게 여러 옵션들이 존재하지만 무료 사용자는 Smart Tiered Cache 옵션만 설정 가능하니 이것만 알아보겠습니다.
Smart Tiered Cache
Smart Tiered Cache는 병렬성을 어느정도 희생하고 오리진 접근 지점을 단일화해서 캐시 HIT 효율을 끌어올리는 구조인데요, 옵션을 활성화하면 클라우드플레어가 내부적으로 오리진 서버의 레이턴시를 측정해서 오리진 서버 앞에다 동적으로 가장 성능 좋은 단 하나의 상위 캐시 계층(Upper Tier)를 지정하게 됩니다.
이제 엣지 서버들은 이 상위 캐시 계층을 통해서만 오리진 서버(R2)에 접근하게 되니 사용자 A의 첫 요청에 의해 Upper Tier에 한번 캐싱 되면, 사용자 B가 다른 엣지 서버를 통해서 요청을 보내도 R2에 직접 요청하는 게 아닌, Upper Tier에서 캐싱된 콘텐츠를 바로 가져올 수 있어서 응답 속도가 더 빨라지게 됩니다. (DB 서버 앞에 Redis를 이용해서 API 응답 캐싱하는 원리와 동일합니다.)
비교하기
curl 명령어 이용해서 Smart Tiered Cache 적용 전 응답 처리 시간 확인해 보겠습니다.
# reqeust 1
curl -w "@curl-format.txt" -o /dev/null -s -D - https://static.hello-cdn.com/image.webp
HTTP/2 200
...
cf-cache-status: MISS
cf-ray: 9710a04eaaa4fccb-FUK
== curl timing ==
dns: 0.002411s
tcp: 0.146601s
ssl: 0.293156s
start: 0.590000s
total: 0.631238s
# reqeust 2
curl -w "@curl-format.txt" -o /dev/null -s -D - https://static.hello-cdn.com/image.webp
HTTP/2 200
...
cf-cache-status: HIT
cf-ray: 9710a066480afccf-FUK
== curl timing ==
dns: 0.001596s
tcp: 0.140970s
ssl: 0.281622s
start: 0.430657s
total: 0.436369s
캐시 적용 후 총 요청 시간이 약 30% 정도 감소(0.63 → 0.43초)한 것을 볼 수 있습니다. DNS/TCP/SSL 시간은 거의 차이가 없지만(네트워크 레벨은 변동 없음) start transfer 시간에서 차이가 발생한 것은 서버가 응답을 빠르게 돌려주기 시작했다는 의미입니다.