오리진 오프로드 늘리기
개요
CloudFront로 캐시 적중률(CHR)을 높이면 웹 애플리케이션의 성능이 향상되고 오리진의 로드가 줄어듭니다. CHR은 총 요청 수에 대한 CloudFront 캐시에서 제공되는 HTTP 요청의 비율입니다. CloudFront 캐시에서 제공되는 요청은 지연 시간(예: 마지막 바이트까지 걸리는 시간)이 길어지기 때문에 CHR은 오리진 오프로드와 애플리케이션 성능을 나타내는 좋은 지표가 됩니다. CloudFront 배포의 CHR은 캐시 적중률 CloudWatch 지표를 사용하여 모니터링할 수 있습니다. CHR을 높이려면 CloudFront에서 캐싱 구성을 최적화하고 Origin Shield를 활성화하고 애플리케이션 동작을 최적화할 수 있습니다.
캐시 TTL(Time To Live) 늘리기
오리진에서 보낸 Cache-Control 헤더를 사용하여 CloudFront에 객체가 캐시되는 기간을 제어할 수 있으며, 캐시 정책의 구성된 TTL(Time To Live) 설정에 따라 제한됩니다. TTL을 늘리면 CHR에 긍정적인 영향을 미치므로 다음을 수행하는 것이 좋습니다.
- 오리진에 Cache-Control 헤더를 구성하여 CloudFront에서 TTL을 더 효과적으로 제어하고 브라우저 캐싱을 활용하세요.
- 정적 자산을 변경 불가능한 객체로 캐시하고(예: Cache-Control: max-age=31536000, 변경 불가능) URL 경로에 버전을 지정합니다(예: /static/app.1be87a.js).
- 객체에 ETAG를 구현하여 오리진에 대한 조건부 HTTP 요청을 활용하세요.
- HTML과 같은 보다 동적인 콘텐츠의 경우 캐싱(높은 TTL)과 애플리케이션이 오래된 콘텐츠를 허용하는 정도(낮은 TTL) 사이에 적절한 균형을 유지하세요.
캐시 키 설정 최적화
캐시 정책을 사용하는 캐시 키 설정은 CloudFront가 HTTP 요청에 캐시된 객체를 재사용할지 여부를 결정합니다. 최적화된 캐시 키 설정을 통해 고유 캐시 키와 고유 객체 간의 관계가 1:1로 유지됩니다. 추가된 쿼리 파라미터(예: /about.html?utm_medium=social)에 관계없이 동일한 /about.html을 제공하는 애플리케이션을 고려해 보세요. 캐시 키가 utm_medium 쿼리 파라미터를 포함하도록 구성된 경우 CloudFront는 다른 두 개의 캐시 키를 사용하여 서로 다른 URL을 캐시합니다(예: /about.html?utm_medium=social 및 /about.html?utm_medium=email). 이렇게 하면 두 요청 모두 오리진에서 정확히 동일한 파일에 대한 요청이지만 오리진에 캐시 미스(cache miss)가 두 번 발생하며, 이는 최적이 아닙니다.
캐시 키 설정을 최적화하는 첫 번째 모범 사례는 오리진 응답을 다르게 하는 캐시 키 요청 속성만 포함하는 것입니다. 이를 위해서는 다음을 수행하는 것이 좋습니다.
- 다른 캐시 키 설정이 필요한 객체에 대해 별도의 캐시 동작을 구성합니다.
- 쿼리 파라미터, 헤더 또는 쿠키가 원본에서 응답을 다르게 하는 경우, 실제로 수행되는 것만 포함합니다(예: 모든 쿠키 대신 cookie user_id).
- 캐시 키에 CORS 헤더(예: Origin, Access-Control-Request-Method, Access-Control-Request-Headers)를 추가하고 오리진 수준에서 CORS를 관리하는 대신 CloudFront의 응답 헤더 정책을 사용하여 CORS를 관리합니다.
- 캐시 키에 인증 헤더를 추가하는 대신 서명된 URL, CloudFront Functions 또는 Lambda@Edge를 사용하여 CloudFront에 액세스 제어를 오프로드하고 오리진 수준에서 관리합니다.
- HTTP 속성을 캐시 키에 추가하는 대신 CloudFront의 오리진 요청 정책을 사용하여 오리진에 전달합니다.
두 번째 모범 사례는 요청 속성을 캐시 키에 추가하기 전에 정규화해 가능한 값의 카디널리티를 줄여 각각 고유한 캐시 키를 생성하는 것입니다. 이를 위해서는 다음을 수행하는 것이 좋습니다.
- 쿼리 파라미터 사용 시 동일한 순서와 대/소문자로 전송합니다.
- User-agent 헤더를 캐시 키에 추가하는 대신 CloudFront-Is-Mobile-Viewer와 같이 CloudFront에서 생성한 헤더를 사용하여 디바이스 유형을 식별합니다.
- CloudFront Functions를 사용하여 쿼리 파라미터 재정렬 및 대/소문자 구분, 캐시 키에 쿠키를 추가하는 대신 쿠키의 존재 여부에 따라 다른 버전의 웹 페이지 제공, 국가 그룹에 대해 동일한 응답을 보낼 수 있는 경우 국가에 따라 달라지는 응답의 차이 줄이기, 압축이 필요한 경우 Accept-Encoding의 카디널리티를 더 줄이거나 여러 헤더가 사용되는 경우 CloudFront 디바이스 탐지 헤더의 카디널리티 줄이기와 같은 고급 정규화를 적용합니다.
Origin Shield 활성화
기본적으로 CloudFront는 PoP 수준의 계층과 리전 엣지 캐시(REC) 수준의 계층의 두 개의 높은 수준의 캐싱 계층을 사용하여 오리진에 대한 캐시 미스(cache miss) 수를 줄입니다. CloudFront PoP는 명목상 전 세계 10개 이상의 REC 중 하나와 연결되어 있습니다. 요청으로 인해 PoP 수준에서 캐시 미스가 발생하면 CloudFront는 요청을 이행하기 위해 관련 REC의 캐시를 확인하고, 요청이 해당 REC에 캐시되지 않은 경우에만 요청을 오리진에 전달합니다. REC는 고가용성을 유지하기 위해 서로 격리되므로 캐시를 공유하지 않습니다. 결과적으로, 전 세계 여러 위치에서 인기 있는 객체가 요청되면 CloudFront는 여러 REC에서 동일한 객체에 대한 여러 요청을 오리진으로 보냅니다.
오리진에 전달되는 요청 수를 줄이려면 CloudFront에서 REC와 오리진 간의 세 번째 상위 수준 캐싱 계층인 Origin Shield를 활성화할 수 있습니다. REC는 오리진에서 직접 객체를 요청하는 대신 먼저 Origin Shield 캐시에서 요청을 이행하려고 합니다.
애플리케이션 동작 최적화
캐시 적중률에 긍정적인 영향을 줄 수 있는 애플리케이션 수준 변경을 고려해 보세요. 다음을 예로 들 수 있습니다.
- 애플리케이션에서 제공하는 카디널리티 객체를 줄입니다. 애플리케이션에서 동일한 자산의 여러 변환을 생성하는 경우(예: 다양한 화면에 맞게 다양한 이미지 크기) 너비와 높이에 대한 가능한 값의 수를 제한하는 것을 고려해 보세요.
- 브라우저 캐싱을 활용합니다. 오리진에서 전송한 Cache-Control 헤더를 사용하여 이를 수행할 수 있습니다. Cache-Control 헤더에서 s-maxage 지시어와 함께 max-age를 사용하거나, 브라우저에 대해 Cache-Control 헤더를 사용하고 캐시 정책을 사용하여 CloudFront TTL을 제어함으로써 CloudFront와 브라우저 간의 TTL을 구분할 수 있습니다.
- 클라이언트에서 바이트 범위 요청을 사용하여 필요한 항목만 다운로드하세요.