본문 바로가기

IT/papers

HTTP 1.1 캐시 관련 헤더

작성자 : joanne*
    * 1 Cache의 개념
                + 1.1.1 HTTP Cache란?
    * 2 HTTP1.1의 cache field
                + 2.1.1 Request header
                      # 2.1.1.1 Request header의 general-header 중 cache 관련 항목
                      # 2.1.1.2 Request header의 request header 중 cache 관련 항목
                + 2.1.2 Response header
                      # 2.1.2.1 Response header의 general-header 중 cache 관련 항목
                      # 2.1.2.2 Response header의 Entity-Header 중 cache 관련 항목
                      # 2.1.2.3 Response header의 Vary Header
    * 3 Cache의 동작 방식
          o 3.1 Expiration & Validation
                + 3.1.1 Expiration
                      # 3.1.1.1 Expiration의 계산
                            * 3.1.1.1.1 current_age의 계산
                + 3.1.2 Validation
                      # 3.1.2.1 E-tag, Last-Modified를 사용할 때의 규칙
    * 4 사례
                + 4.1.1 nocache
                + 4.1.2 Etag, max-age
                + 4.1.3 Expires
                      # 4.1.3.1 Vary와 Accept-Encoding

Cache의 개념

HTTP Cache란?

  1. 브라우져가 웹 페이지 구성요소를 PC의 hard disk에 저장했다가 같은 요소가 다시 불릴 때 서버에 요청하지 않고 저장된 것을 보여주는 것
  2. cache는 client와 svr 사이에 위치하여 기능을 수행함으로써 데이터의 전송을 줄여 양측의 부하를 줄이고, 보다 빨리 리소스를 얻을 수 있도록 한다.

HTTP1.1의 cache field

Request header

            Request-Line
headers : general-header, request-header, Entity-Header, ...
CRLF
message-body

Request header의 general-header 중 cache 관련 항목

  • General-header 안에 Cache Control이라는 지시자로 cache의 제어가 가능하다.
Cahce-Control : 
cache-request-directive=
"no-cache" 캐시 하지 않는다.
"no-store" 신속히 넘긴 후에 정보를 제거한다.
"max-age = seconds" seconds에 지정한 것보다 오래된 entry는 캐시하지 않는다.
"max-stale [=seconds]" 만료된 데이터를 보낸다. 만약 seconds가 지정되어 있다면 지정한 숫자보다 적은 만료된 데이터를 보낸다.
"min-fresh [=seconds]" 명시된 seconds의 수 이후의 변경된 새 데이터만 보낸다.
"only-if-cached" 새로운 데이터를 검색하지 않고 캐시에 있는 데이터만 반환한다.

Request header의 request header 중 cache 관련 항목

   "If-Match" 이미 이전에 캐시되었던 entity는 연관된 entity tag(이하 E-tag)를 포함하여 이 entity과 현재의 것임을 증명할 수 있다. 
사용형식 - If-Match: E-tag
"If-None-Match" 조건적으로 요청하는 것으로 주어진 엔티티 태그와 어떠한 것도 매치되지 않아야 요청 계속

Response header

            Status-Line
headers : general-header, request-header, Entity-Header, ...
CRLF
message-body

Response header의 general-header 중 cache 관련 항목

  • General-header 안에 Cache Control이라는 지시자로 cache의 제어가 가능하다.
Cahce-Control : 
cache-response-directive=
"public" 어떠한 캐쉬라도 캐싱할 수 있다.
"private" 공유된 캐쉬는 캐시하지 않는다.
"no-cache" 캐쉬하지 않는다.
"no-transform" 데이터를 변환하지 않는다.
"must-revalidate" 클라이언트는 데이터를 재확인 해야 한다.
"proxy-revalidate" 개인적인 클라이언트 캐시를 제외하고 데이터를 재확인 해야한다.
"max-age"="delta-seconds" 문서는 지정된 seconds만큼 변화가 없는 상태라고 생각

Response header의 Entity-Header 중 cache 관련 항목

   "E-tag" Data 고유의 entity tag. INode, MTime, Size값을 나타내는 것으로 파일의 갱신 여부를 확인하기 위해 사용된다.
"Last-Modified" : Tue, 15 Nov 1994 12:45:26 GMT 의 형식으로 사용되며 origin svr에서의 최종 수정시간을 뜻한다.
웹 페이지 전송시간을 기록해 뒀다가 Last-Modified이 값과 비교한 다음 페이지가 수정되었을 때만 Data를 가져가도록 작동한다.
"Expires" date의 형식으로 문서가 변경될 수도 있을 때의 시간 또는 그것의 정보가 유효하지 않을 때의 시간을명시한다.
그 시간 이후, 문서는 변경 또는 삭제되거나 그렇지 않을 수 있다.

Response header의 Vary Header

  • Vary : 캐시된 entity가 다중 자원을 가지고 있으므로 요청한 헤더를 지정한 목록이 상황에 따라 변할 수 있다는 것을 지정한다. 여러 개의 헤더는 세미콜론으로 구분하여 나열한다.Vary 헤더를 포함하여 캐시가 해당 자원에 대한 향후 요구를 적절하게 해석할 수 있도록 한다.
  • Accept-encoding : Request header의 Accept-encoding은 compress 또는 gzip과 같은 클라이언트가 받아들일 수 있는 인코딩 방식을 지정한다. 여러 개의 인코딩 방식을 쉼표로 구분하여 나열한다. 만약 인코딩 형태를 지정하지 않으면 어떤 형태도 클라이언트에게 받아들여지지 않는다.
  • Accept-encoding: gzip 가 수신되는 경우 미리 압축된 내용을 서비스하도록 구성된 디렉토리의 파일에 대한 모든 요청이 해당 디렉토리의 상응하는 압축 파일에 대한 요청으로 리다이렉션됩니다(해당 파일이 존재하는 경우).웹 서버가 myfile.html에 대한 요청을 수신하고 myfile.html 및 myfile.html.gz가 모두 존재하는 경우 적절한 Accept-encoding 헤더를 가진 이러한 요청에서 압축된 파일을 수신하게 된다.
  • Vary : 서버는 자신이 캐쉬한 응답을 적절한 Accept-Encoding 요청 헤더를 보낸 클라이언트에게만 보내도록 Vary: Accept-Encoding으로 설정할 수 있다.

Cache의 동작 방식

Expiration & Validation

HTTP/1.1의 캐시의 목적은 response, request의 round-trip을 줄이고, 또 full response의 발송을 줄여 대역폭을 절약하는 것이다. 이를 위해 expiration, validation 두 가지 방법을 사용한다.

  • Expiration : response-request의 roundtrip 줄이기 위해 expiration(만기일)방식을 사용한다.
  • Validation : full response의 발송을 줄여 network bandwith를 절약한다.

Expiration

  • http 캐시는 origin SVR로 request를 보내고, response를 받는 round-trip 과정을 최소화할 때 최상으로 작동한다
  • roundtrip 과정을 최소화하기 위해 User-Agent(브라우져)가 웹 문서를 요구할 때 캐시에 저장되어있는 만기일 을 확인하여 만기일이 지나지 않았을 경우에 캐시된 문서를 브라우져로 응답하는 매커니즘을 사용한다.
  • 서버는 Expires header 또는 Cache-Control header의 max-age 지시자를 사용하여 만기일을 선정한다.
  • Expires header나 Cache-Control header에 지정값이 없으면 heuristic Expiration을 사용한다.
  • Expires Header
    헤당 오브젝트가 얼마동안 유효한지를 표시해주는 항목

Expiration의 계산

  • 서버는 Expires header 또는 Cache-Control header의 max-age 지시자를 사용하여 만기일을 선정한다.

    expires_value : expires 헤더 값을 표시
    max_age_value : cache control 헤더에 max-age 지시자가 가지고 있는 값

  • 만기일을 선정하는 과정은 Expires header보다 Max Age가 우선이다. 즉 Expires header가 설정되어 있어도 Max Age가 설정되어있다면 그 값이 우선이 된다.
  • 만기일에대한 별다른 설정이 없다면 heuristic expiration time(자동설정 만기시간)을 할당한다.
  • Data가 만기일을 지나지 않았다면 이 자료는 fresh하다고 표현한다. 이 때, fresh한 지의 여부는 다음과 같은 방법으로 결정된다.

    freshness_lifetime = max_age_value
    freshness_lifetime = expires_value - date_value
    response is fresh = ( freshness_lifetime > current_age)

current_age의 계산
  • fresh 여부를 판단할 때 사용되는 current_age는 다음과같이 계산된다.
    • date_value(Date head) : 응답이 생성된 시간
    • age_value : 캐쉬 잔류시간 + 네트워크 이동시간
    • corrected_received_age = max(now-date_value, age_value)
    • request_time : 요청이 생성된 시간
    • response_time : 캐쉬가 응답을 받은 시간
    • now : 현재 시간
    • corrected_initial_age = connected_received_age + (now - request_time)
    • apparent_age = max(0, response_time - date_value)
    • corrected_received_age = max(apparent_age, age_value)
    • response_dalya = response_time - request time
    • corrected initial age = corrected_received_age + response_delay
    • resident_time = now - response time
    • current_age = corrected_initial_age + resident_time

Validation

  • http SVR는 캐시된 엔트리를 아직도 사용할 수 있는지 알아보는 Validation 작업을 수행한다.
  • full response를 주고 받는 것은 BW overhead가 크고, 이런 overhead를 줄이기 위해 Cache Validator를 사용한다.
  • Cache Validator를 비교하여 변화가 없는 경우는 304(Not Modified), 변화가 있을 경우 200(OK)를 리턴하고 문서를 전송한다.
  • Cache Validator로 E-tag와 Last-modified header가 사용된다.
  • E-tag의 값이 Last-Modifed 값보다 우선적으로 Validating된다.

E-tag, Last-Modified를 사용할 때의 규칙

  • HTTP/1.1 origin sever:
    새로운 것을 생성하는 것이 불가능하지 않는 한 E-tag validator를 발송해야 함.
    성능에 대해 고려했을 때 weak E-tag를 사용해도 될 때 또는 E-tag를 발송하는 것이 효과적이지 못할 때 강한 엔터티 태그 대신 weak entity 태그를 발송할 수도 있음.
    (달리 표현하면 HTTP/1.1 원서버의 바람직한 행태는 Stroing E-tag와 Last-Modified 값 모두를 발송해야함)
  • HTTP/1.1 client:
    서버가 E-tag를 제공하였으면 클라이언트는 If-Match 또는 If-None-Match를 사용하여 그 E-tag를 반드시 사용해야 함.

    strong entity : 검증자가 동일한 entity인지를 검증하는 과정에서 entity가 어떤 식으로든 변경이 되었다면 그에 해당하는 validator도 변경되었을 것이다. 이런 경우 validator를 strong validator라고 부른다.
    weak entity : entity의 변화가 상대적으로 중요한 의미를 갖지 않는다면 validator를 일일이 변경하지 않는 경우가 있을 수 있다. 이런 validator는 weak 태그를 붙여 weak validator로 설정 가능하다.

 

사례

 

nocache

  • ctrl+F5로 새로고침 했을 때 Cache-Control : no-cache(캐쉬하지 않음)가 설정이 되는 것을 알 수 있다.

 

Etag, max-age

  • 동일 파일에 대해 새로고침 했을 때 response로 304(not-modified)status를 받았다.
  • Validation을 위해 요청 해더에 If-None-Match값이 삽입되었고, 응답헤더의 Etag값과 동일함을 알 수 있다.
  • Etag값으로 파일이 동일함을 확인하였고, 캐시의 자료를 사용한다.
  • max-age=0을 설정하여 매번 expire 캐시 엔트리를 재검증한다.

 

Expires

  • max-age가 지정되지 않았으므로 Expires를 확인한다.
  • Expires값을 과거로 설정되어 무조건 revalidating 하도록 하였다.
  • Cache-Control 지시자에 no-cache, must-revalidate를 설정하여 캐시를 지나지 않고 무조건 origin서버에서 revalidate한 이후 response를 받는다.

 

Vary와 Accept-Encoding

  • Accept Encoding에 giz, deflate를 주어 모든 요청을 gzip, deflate에 대한 요청으로 redirect한다.
  • 캐쉬한 응답이 적절한 Accept-Encoding 요청 헤더를 보낸 클라이언트에게만 보내지도록 Vary: Accept-Encoding가 설정되었다.