더 빠른 콘텐츠 전송을 위한 CDN 활용 팁

NAVER CLOUD PLATFORM
NAVER CLOUD PLATFORM
9 min readApr 25, 2019

대용량의 모바일 게임 다운로드, VOD 영상 재생, Live 시청 등 대부분의 트렌디한 웹 서비스 콘텐츠 제공에서 빠질 수 없는 것이 바로 ‘CDN(Content Delivery Network)’입니다. 다양한 콘텐츠를 사용자에게 원활하게 전달하기 위해서는 CDN이 필수인데요. CDN을 적용하면 모든 서비스가 빨라지고 안정적으로 처리될 수 있는 걸까요? CDN을 보다 잘 활용하여 콘텐츠를 빠르게 전송하고 안정적인 서비스 구조를 만들기 위한 몇 가지 팁을 공유합니다.

CDN을 적용하면 효과적인 콘텐츠는 어떤 콘텐츠인가요?

CDN을 사용하기에 적합한 콘텐츠가 있는지 고민한 적이 있으실 텐데요! 콘텐츠는 캐싱 여부에 따라 2가지 타입으로 구분될 수 있는데요. 각 타입별로 전송 방안을 다르게 가져가는 것이 효과적입니다.

① 정적 콘텐츠
한번 만들어진 후 변경되거나 수정되지 않고 사용자에게 전달되는 모든 콘텐츠를 정적 콘텐츠라고 합니다. 예를 들면, 웹의 레이아웃을 구성하는 css, js, jpg 등의 이미지가 정적 콘텐츠라고 할 수 있죠.

[그림1. 정적 콘텐츠 CDN 전송]

② 동적 콘텐츠
그렇다면, 동적 콘텐츠는 어떤 걸까요? 사용자 요청에 따라 가공하거나 개인의 정보를 포함하여 요청 별로 내용이 달라지는 콘텐츠를 동적 콘텐츠라고 합니다. 예를 들면, 로그인에 따라 사용자 정보가 포함되는 asp, jsp 등의 웹페이지를 동적 콘텐츠라고 할 수 있습니다.

[그림2. 동적 콘텐츠 CDN 전송]

정적 콘텐츠는 모든 사용자에게 동일한 콘텐츠를 제공하므로 가장 단순하고 효율적으로 전송할 수 있습니다. 따라서, 가장 좋은 방법은 웹 서비스 내의 정적/동적 콘텐츠를 분리하여 동적 콘텐츠는 웹 서버를 활용하여 전송하고, 정적 콘텐츠는 CDN을 적용하여 사용자에게 전송하면 효율적으로 웹 콘텐츠를 제공할 수 있습니다.

CDN의 핵심 : 캐싱(Caching) 로직과 콘텐츠 유효성 검증(Re-validation)에 대하여

‘캐시(Cache)’란 용어는 CDN 외에도 서버의 하드웨어와 같이 범용적으로 사용되는 단어인데요. 하드웨어 혹은 소프트웨어에 데이터를 저장하여 추후 요청의 데이터를 더 빠르게 제공하는 기술 용어입니다. CDN에서는 사용자가 요청하는 데이터를 빠르게 제공하기 위해 콘텐츠를 캐싱하는 캐시 서버를 활용합니다.
CDN의 캐시 서버가 어떻게 원본 서버와 통신하여 콘텐츠를 저장하고 사용자에게 전송하는지, CDN의 핵심인 ‘캐싱(Caching)’에 대하여 먼저 살펴보겠습니다.

[캐싱 상태]

‘캐싱’은 캐시가 됐는지의 여부에 따라 ‘캐시 미스(Cache Miss)’와 ‘캐시 힛(Cache Hit)’으로 상태를 나눌 수 있습니다.

① Cache Miss
캐시 서버에 콘텐츠가 없는 상태로, 최초의 콘텐츠 요청이나 Cache가 삭제된 이후 요청이 인입된 상태입니다. Cache Miss의 경우 원본 서버로부터 콘텐츠를 가져와 캐싱 후 요청에 대해 응답합니다.

[그림 3. Cache Miss]

② Cache Hit
캐시 서버에 콘텐츠가 저장된 상태로 요청에 대해 원본을 거치지 않고 캐시 서버가 응답합니다. Cache Hit율이 높을 수록 원본 서버의 요청과 부하를 줄이고, 사용자에게 빠르게 콘텐츠를 응답할 수 있어 효율적으로 CDN을 사용할 수 있습니다.

[그림 4. Cache Hit ]

[Cache Re-validation (캐시 유효성 검증)]

캐싱이 되었는지, 되지 않았는지 확인 할 수 있는 ‘캐시 유효성 검증’ 을 통해 크게 두가지 결과를 확인 할 수 있습니다. 콘텐츠 최신 여부 확인을 통해 변경된 콘텐츠가 아니라면 ‘Cache Refresh Hit’ , 콘텐츠가 변경 되어 캐싱 되지 않았다면 ‘Cache Refresh Miss’ 응답을 확인 할 수 있습니다.

① Cache Refresh Hit
캐시 서버에 저장된 콘텐츠가 만료되어 원본 서버로부터 유효성 검증(If-Modified-Since 혹은 If-Non-Match 요청) 절차 시 HTTP 304 응답(Not Modified)을 받은 상태입니다. 캐싱으로 저장된 콘텐츠를 수정하지 않고 Cache TTL만 갱신하여 요청에 대해 응답합니다.

[그림 5. Cache Refresh Hit]

② Cache Refresh Miss
캐시 서버에 저장된 콘텐츠가 만료되어 원본 서버로부터 유효성 검증 절차 시 HTTP 200응답(OK)을 받은 상태입니다. 원본으로부터 새로 응답받은 콘텐츠로 캐싱을 갱신하고 요청에 대해 응답합니다.

[그림 6. Cache Refresh Miss]

콘텐츠를 교체할 때에 주의해야 할 점이 있어요!

원본 서버에 콘텐츠를 업로드하면 간단하게 CDN 전송이 가능하지만 유의해서 챙겨야 할 점이 있습니다. 서비스 운영 상의 편의로 파일명이 변경되지 않고 파일의 교체나 내용이 갱신되는 경우가 있습니다. 캐싱의 기준이 서비스 URL이기에 파일명이 변경되지 않고 파일이 교체되는 경우, 캐시 서버에서는 구 파일 내용의 유효하지 않은 파일을 전송할 수 있습니다.

이렇게 동일한 파일명을 사용하여 CDN의 콘텐츠를 갱신하고 싶다면 ‘Purge’를 활용할 수 있습니다. Purge는 캐시 서버에 캐싱된 콘텐츠를 강제로 삭제하여 원본 서버로부터 갱신된 콘텐츠를 가져와서 서비스할 수 있습니다.

Purge를 통해 빠르게 갱신할 수 있지만 전체 콘텐츠 대상 혹은 사용량이 많은 콘텐츠에 대한 Purge를 수행하면 원본 서버로 요청이 증가하여 부하를 유발하므로 사용에 주의가 필요합니다. 또한, Purge는 캐시 서버의 콘텐츠 갱신이므로 사용자(App, Web Browser 등)단의 Local Cache된 콘텐츠 갱신을 보장하지 않을 수 있습니다.

사용자 단까지 파일의 최신성 보장을 위해서는 파일명과 서비스 링크(URL)을 변경하여 새롭게 캐싱하는 것이 좋습니다.

원본 서버의 중요성 : 뿌리 깊은 나무는 강한 바람에도 잘 흔들리지 않아요.

CDN의 뿌리인 원본 서버(origin)에 따라 CDN의 가용성과 효율이 달라질 수 있습니다. 안정성과 캐싱 효율을 높일 수 있는 원본 서버와 서비스의 구성 팁에 대하여 간략히 설명드리겠습니다.

① 서비스 URL과 원본 서버의 콘텐츠 통일하기
첫 번째로, 캐싱 조건에 따른 서비스 URL과 원본 서버의 콘텐츠 통일성입니다. 캐싱의 기준은 콘텐츠가 아닌 URL 기반입니다. URL에는 쿼리스트링이 포함될 수 있는데요. 동일 콘텐츠이더라도 요청마다 서비스 URL에 쿼리스트링 다르다면 캐시 서버에서 개별 콘텐츠로 캐싱합니다.

cdn.example.ntruss.com/file.png
cdn.example.ntruss.com/file.png?query=12345

→ 파일은 동일하나, ‘query=12345’의 쿼리스트링에 따라 캐시 서버는 개별 콘텐츠로 캐시하여 Cache Hit율이 하락합니다.

따라서, 원본 서버에서 쿼리스트링에 따라 콘텐츠를 다르게 응답하지 않는다면 Cache Hit률을 높이기 위해 캐싱 설정에서 ‘쿼리스트링 무시(Ignore Query String)’ 설정을 적용하는 것이 좋습니다.

네이버 클라우드 플랫폼 CDN+에서는 캐싱 설정 내 쿼리스트링을 무시하도록 기본값들이 최적화되어 있습니다.

그리고 2대 이상의 원본 서버를 운영할 경우 파일의 수정일, 용량 등의 속성이 모두 동일해야 합니다. 원본 서버 별로 동일한 파일명에 대하여 수정일(Last-Modified)이 달라진다면 요청에 따라 Cache Refresh Miss가 증가하여 Cache Hit률이 하락할 수 있습니다.

② WAS 설정 최적화 하기
두 번째로, Apache나 Nginx와 같은 WAS(Web Application Service) 설정을 최적화하는 것입니다. 원본에서 HTTP Header와 콘텐츠 응답에 따라 Cache Hit률을 높이고 사용자 응답 시간을 줄일 수 있습니다.

■ gzip 압축 적용 : 압축을 하면 원본 서버의 트래픽을 줄이고 응답 시간을 개선할 수 있어 사용하는 것이 좋습니다.

■ Cache-Control 헤더 사용 시 주의 : 원본 서버에서 응답 헤더의 ‘Cache-Control’ 헤더 값 내에 ‘private, no-cache, max-age=0, must-revalidate, no-store’가 포함되면 캐싱을 활용하지 않고 사용자 요청이 모두 원본으로 유입됩니다. 원본 서버 응답 시 이 값들이 포함되지 않는 것이 좋습니다.

■ Etag, Vary 헤더 사용 시 주의 : 원본 서버에서 응답 헤더의 ‘Vary’ 헤더 값에 ‘User-Agent’가 포함되면 요청의 User-Agent에 따라 동일한 콘텐츠이더라도 개별 콘텐츠로 캐싱될 수 있습니다. Browser나 사용자 환경 별로 다른 콘텐츠를 서비스하지 않는다면 원본 서버 응답 시 이 값이 포함되지 않는 것이 좋습니다. 그러나 ‘Vary: Accept-Encoding’ 헤더는 압축 여부에 대한 사항으로 포함되어도 영향이 없습니다.
ETag 사용 시 inode가 포함되면 서버 별로 속성값이 달라지므로 캐시 갱신 여부를 확인 시 Cache Refresh Miss로 Cache Hit률이 하락할 수 있습니다. 따라서, 원본 응답 시에 ETag를 제거하거나 inode 속성값을 포함하지 않는 것이 좋습니다.



③ 원본 서버 이중화 하기
마지막으로는 원본서버를 이중화하는 것이 좋습니다. WAS Application이 다운되거나 물리적으로 서버는 다운되면 CDN에서도 정상적으로 서비스가 어렵습니다. 따라서 이중화를 하여 1대의 원본서버가 죽더라도 다른 원본서버들을 통해 24시간 365일 서비스를 할 수 있도록 권고 합니다.

마무리하며..

CDN을 사용하는 것은 쉽지만 효율적으로 사용하려면 위에서 이야기한 바처럼 고려해야 할 사항이 많습니다. CDN을 사용하고 싶거나, 이미 사용하고 있지만 비용은 줄이고 효율적인 콘텐츠 서비스 전송을 활용하고 싶은 분들에게 도움이 되었으면 합니다. 관련하여 궁금한 사항은 언제든지 네이버 클라우드 플랫폼에 문의주시기 바랍니다. 감사합니다.

--

--

NAVER CLOUD PLATFORM
NAVER CLOUD PLATFORM

We provide cloud-based information technology services for industry leaders from startups to enterprises.