본문 바로가기

HTTP 완벽 가이드 책 정리

7장. 캐시

캐시 개념

자주 쓰이는 문서의 사본을 자동으로 보관하는 HTTP 장치.

웹 요청이 캐시에 도착했을 때, 캐시된 로컬 사본이 존재한다면, 해당 문서는 원 서버가 아닌 캐시로부터 제공됨

캐시 장점

  1. 불필요한 데이터 전송을 줄여 네트워크 요금으로 인한 비용을 줄여줌
  2. 네트워크 병목을 줄여줌. 대역폭을 늘리지 않고도 페이지를 빨리 불러올 수 있음
  3. 원 서버에 대한 요청을 줄여줌. 서버는 부하를 줄일 수 있으며 더 빨리 응답할 수 있음
  4. 거리로 인한 지연을 줄여줌

7.1. 불필요한 데이터 전송

여러 클라이언트가 원 서버에게 같은 문서를 요청하면 서버는 각 클라이언트들에게 한 번씩 전송해줌

👉 똑같은 바이트가 네트워크 통해 반복해서 이동하므로 네트워크 대역폭을 잡아먹고 전송 속도 저하됨

🔮 캐시를 사용하면 첫번쨰 응답은 캐시에 보관되고 캐시된 사본을 다음 요청의 응답으로 전송

👉 트래픽 전송 낭비 줄어듬

7.2. 대역폭 병목

캐시는 네트워크 병목을 줄여줌

병목(bottleneck): 전체 시스템의 성능이나 용량이 하나의 구성 요소로 인해 제한을 받는 현상

보통 네트워크는 원격 서버보다 로컬 네트워크 클라이언트에 더 넓은 대역폭을 제공

예) 미국 샌프란시스코 지사에 클라이언트가 있고 아틀랜타 본사에 원 서버가 있을 경우 샌프란시스코 클라이언트에서 아틀랜타 서버의 데이터를 가져오려면 30초가 걸린다고 가정. 하지만 데이터가 샌프란시스코의 사무실에 캐시되어 있으면 1초 내로 데이터 받아올 수 있음

대역폭은 문서가 클 수록 지연을 일으키며, 속도는 네트워크의 종류에 따라 달라진다

7.3. 갑작스런 요청 쇄도(Flash Crowds)

갑작스런 사건으로 인해 많은 사람이 동시에 웹 문서에 접근하는 경우 불필요한 트래픽 급증으로 네트워크와 웹 서버에 장애가 발생할 수 있다.

👉 캐시는 이러한 장애를 방지해준다.

7.4. 거리로 인한 지연

클라이언트와 서버 간의 거리가 멀어지게 되면 그에 따른 지연이 발생

(빛의 속도로 인한 지연도 발생)

👉 기계실 근처에 캐시를 설치해 문서가 전송되는 거리를 줄일 수 있음

7.5. 적중과 부적중

  1. 캐시 적중(cache hit): 캐시에 요청이 도착했을 때, 그에 대응하는 사본이 있어서 이를 이용해 요청을 처리하는 경우
  2. 캐시 부적중(cache miss): 캐시에 요청이 도착했을 때, 그에 대응하는 사본이 없어 그냥 원 서버로 전달되기만 하는 경우

7.5.1. 재검사(Revalidation)

  1. HTTP 재검사는 캐시가 자신의 컨텐츠 사본이 최신인지 서버를 통해 검사하는 것을 말함
  2. HTTP는 서버로부터 전체 객체 가져오지 않고도 컨텐츠의 신선도를 검사하는 요청 정의
  3. 캐시는 언제든지 원할 때 사본 재검사 가능, 하지만 문서가 많으면 네트워크 대역폭이 부족하기 때문에 대부분의 캐시는 클라이언트가 사본을 요청하고 그 사본이 오래된 경우에만 재검사를 시행함
  4. 캐시는 캐시된 사본의 재검사가 필요할 때 원 서버에 작은 재검사 요청 보냄. 
    • 컨텐츠가 변경되지 않았으면 서버는 304 Not Modified로 응답
    • 사본이 유효함을 확인한 캐시는 사본이 신선하다고 임시로 표시한 뒤 그 사본을 다시 클라이언트에게 제공
    • 이를 재검사 적중 or 느린 적중이라 함
    • 서버와 검사해야되서 순수 캐시 적중보다는 느리고 서버로부터 객체 데이터를 받아올 필요가 없기에 캐시 부적중보다는 빠름 
  5. HTTP는 캐시된 객체 재확인 위해 여러 도구 제공 
    • If-Modified-Since 헤더 👉 서버에게 보내는 GET요청에 추가할 경우 캐시된 시간 이후에 변경된 경우에만 사본을 보내달라는 의미
    • If-Modified-Since 요청이 서버에 도착하면 발생할 수 있는 상황들
      • 서버 컨텐츠가 변경되지 않은 경우👉 재검사 적중: 서버는 클라이언트에게 HTTP 304 Not Modified 보냄
      • 서버 컨텐츠가 변경된 경우👉 서버는 컨텐츠 전체와 HTTP 200 OK 응답 보냄 
      • 객체가 삭제된 경우👉 서버는 404 Not Found를 보내고 캐시는 사본을 삭제

7.5.2. 적중률

캐시 적중률(or 캐시 적중비) or 문서 적중률(or 문서 적중비): 캐시가 요청을 처리하는 비율

👉 얼마나 많은 웹 트랜잭션을 외부로 내보내지 않았는지 보여줌

0% -> 모든 요청이 캐시 부적중, 100% -> 모든 요청이 캐시 적중

7.5.3. 바이트 적중률

바이트 단위 적중률: 캐시를 통해 제공된 모든 바이트의 비율

👉 트래픽이 절감된 정도를 포착할 수 있음

👉 얼마나 많은 바이트가 인터넷으로 나가지 않았는지 보여줌

100% -> 모든 바이트가 캐시에서 왔으며 어떤 트래픽도 인터넷으로 나가지 않음

데역폭 절약 최적화가 적중률 개선 방법

7.5.4. 적중과 부적중의 구별

적중과 부적중의 경우 모두 응답이 200 OK이므로 클라이언트는 이 둘을 구별하는 것이 쉽지 않음

적중과 부적중을 구별하는 방법

  1. Date 헤더 이용: 응답의 Date 헤더 값을 현재 시각과 비교해 응답의 생성일이 더 오래됐다면 클라이언트는 응답이 캐시된 것임을 알 수 있음
  2. Age 헤더 이용

7.6. 캐시 토폴로지

7.6.1. 개인 전용 캐시

  1. 사용자 한 명에게만 할당된 캐시를 말함 👉 한 명의 사용자가 자주 찾는 페이지를 담음
  2. 에너지나 저장 공간이 많이 필요하지 않음
  3. 대부분의 브라우저는 자주 쓰이는 문서를 컴퓨터의 디스크와 메모리에 캐시해 놓고 사용자가 캐시 사이즈와 설정을 수정할 수 있도록 허용
  4. 사용자가 브라우저 안을 들여다보는 것도 가능

7.6.2. 공용 프락시 캐시

  1. 공용 캐시는 공유된 프락시 서버를 말한다.
  2. 프락시 캐시는 로컬 케시에서 문서를 제공하거나 사용자의 입장에서 서버에 접근
  3. 여러 사용자가 접근하기 때문에 불필요한 트래픽을 줄일 수 있음
  4. 공용 캐시는 자주 찾는 객체를 한 번만 가져와 모든 요청에 대해 공유된 사본을 제공해 네트워크 트래픽을 줄임

7.6.3. 프락시 캐시 계층들

프락시 캐시 계층에서는 자식 캐시에서 캐시 부적중이 발생하면 부모 캐시가 '걸러 남겨진' 트래픽을 처리하도록 한다.

👉 클라이언트 주위에는 작은 캐시 사용, 계층 상단에는 더 크고 강력한 캐시를 사용한다

캐시 계층이 깊을 경우 요청은 캐시의 긴 연쇄를 따라가게 됨

👉 프락시 연쇄가 깊어질수록 중간 프락시는 현저한 성능 저하가 발생

 

7.6.4. 캐시망, 컨텐츠, 라우팅, 피어링

캐시망의 프락시 캐시

👉 캐시끼리 대화하여 어떤 부모 캐시와 대화할 것인지, 아니면 요청이 캐시를 완전히 우회해서 원 서버로 가도록 만들 것인지에 대한 캐시 커뮤니케이션 결정을 동적으로 내림

캐시망 내 콘텐츠 라우팅을 위해 설계된 케시들이 할 수 있는 일 

  1. URL에 근거해 부모 캐시와 원 서버 중 하나를 동적으로 선택
  2. URL에 근거해 특정 부모 캐시를 동적으로 선택
  3. 부모 캐시에게 가기 전에 캐시된 사본을 로컬에서 찾아봄
  4. 다른 캐시들이 캐시된 컨텐츠에 부분적으로 접근하는 것을 허용하되, 그들의 캐시를 통한 인터넷 트랜짓(Internet transit)은 허용하지 않음

복잡해진 캐시간 관계는 서로 다른 조직들이 상호 이득을 위해 그들의 캐시를 연결해 서로를 찾아볼 수 있도록 해줌

형제 캐시: 선택적인 피어링을 지원하는 캐시

피어링: 인터넷 서비스 제공자끼리 서로 네트워크를 연결하고 트래픽을 교환하는 것

HTTP는 형제 캐시를 지원하지 않기 때문에 캐시 프로토콜(ICP)이나 하이퍼텍스트 캐시 프로토콜(HTCP) 같은 프로토콜을 사용해 HTTP 확장함

 

7.7. 캐시 처리 단계

HTTP GET 메시지를 처리하는 캐시 절차

  1. 요청 받기 - 캐시는 네트워크로부터 도착한 요청 메시지 읽음
  2. 파싱 - 캐시는 메시지 파싱해 URL과 헤더 추출
  3. 검색 - 캐시는 로컬 복사본이 있는지 검사하고, 사본이 없으면 사본을 받아와서 로컬에 저장
  4. 신선도 검사 - 캐시는 캐시된 사본이 신선한지 검사하고, 신선하지 않다면 변경사항이 있는지 서버에게 물어봄
  5. 응답 생성 - 캐시는 새로운 헤더와 캐시된 본문으로 응답 메시지 만듬
  6. 발송 - 캐시는 네트워크 통해 응답을 클라이언트에게 보냄
  7. 로깅 - 캐시는 로그파일에 트랜잭션에 대해 로그를 남김

7.7.1. 단계 1: 요청 받기

캐시는 네트워크 커넥션에서의 활동을 감지하고 들어오는 데이터를 읽어들임

고성능 캐시는 여러 개의 커넥션들로부터 데이터를 동시에 읽어오고 메시지 전체가 도착하기 전에 트랜잭션 처리 시작함

7.7.2. 단계 2: 파싱

캐시는 요청 메시지를 파싱해 헤더 부분을 조작하기 쉬운 자료 구조에 담음

👉 캐싱 소프트웨어가 헤더 필드를 처리하고 조작하기 쉽게 만들어줌

7.7.3. 단계 3: 검색

캐시는 URL을 알아내고 이에 해당하는 로컬 사본 있는지 검사

💡 로컬 복사본은 메모리나 디스크, 근처의 다른 컴퓨터에 있을 수 있음

문서를 로컬에서 가져올 수 없다면, 캐시는 원 서버나 부모 프락시에서 문서를 가져오거나 실패를 반환한다.

캐시된 객체는 서버 응답 본문과 원 서버 응답 헤더를 포함하고 있음, 객체가 얼마나 캐시에 머무르고 있었는지 알려주는 기록이나 얼마나 자주 사용됐는지 등에 대한 메타데이터를 포함

7.7.4. 단계 4: 신선도 검사

캐시된 사본을 너무 오랫동안 가지고 있으면 이는 '신선하지 않은'것으로 간주된다.

👉 캐시는 문서 변경여부를 검사하기 위해 서버와 재검사를 진행해야 함

7.7.5. 단계 5: 응답 생성

캐시는 캐시된 서버 응답 헤더를 토대로 응답 헤더 생성

👉 캐시된 응답이 원 서버에서 온 것처럼 보이게 하려고

캐시는 클라이언트에 맞게 헤더를 조정

  1. 클라이언트가 HTTP/1.1 응답 기대하는데 서버가 HTTP/1.0 응답 보내면, 캐시는 이를 번역해야함
  2. 캐시 신선도 정보(Cache-Control, Age, Expires 헤더)를 삽입
  3. 종종 요청이 프락시 캐시를 거쳐갔음을 알려주기 위한 Via 헤더도 포함
  4. 하지만 Date 헤더를 조정해서는 절대 안됨

7.7.6. 단계 6: 전송

캐시는 응답을 클라이언트에게 돌려준다.

프락시 캐시는 클라이언트와의 커넥션을 유지할 필요가 있음

7.7.7. 단계 7: 로깅

캐시 트랜잭션이 완료된 후, 캐시는 통계 캐시 적중과 부적중 횟수에 대한 통계를 갱신하고 로그 파일에 요청 종류, URL, 일어난 일에 대한 정보를 추가.

가장 많이 쓰이는 캐시 로그 포맷은 스퀴드 로그 포맷(Squid Log Format)과 넷스케이프 확장 공용 로그 포맷(Netscape Extended Common Log Format)이지만, 많은 캐시 제품이 커스텀 로그 파일을 허용함

7.7.8. 캐시 처리 폴로 차트

7.8. 사본을 신선하게 유지하기

캐시된 데이터는 서버의 데이터와 일치하도록 관리해야 함

HTTP는 캐시된 사본이 서버와 일치하도록 유지하는 매커니즘을 갖고 있음

👉 문서 만료, 서버 재검사

7.8.1. 문서 만료

HTTP는 Cache-Control과 Expires 헤더를 이용해 원 서버가 각 문서에 유효기간을 붙일 수 있게 해줌

캐시된 문서가 만료되면, 캐시는 서버와 문서에 변경된 것이 있는지 검사

👉 변경 있으면 새 유효기간과 함께 신선한 사본을 새로 얻어와야 함

7.8.2. 유효기간과 나이

서버는 응답 본문과 함께 HTTP/1.0+ Expires나 HTTP/1.1 Cache-Control:max-age 응답 헤더를 이용해 유효기간 명시

Cache-Control:max-age
max-age는 문서의 최대 나이를 정의. 최대 나이는 문서가 처음 생성된 이후부터 더 이상 신선하지 않다고 간주될 때까지 경과한 시간의 최댓값
ex) Cache-Control: max-age=484200
Expires
절대 유효기간을 명시. 유효기간 경과하면 그 문서는 더이상 신선하지 않음을 의미
ex) Expires: Fri, 05 Jul 2002, 05:00:00 GMT

7.8.3. 서버 재검사

서버 재검사: 캐시가 원 서버에게 만료된 문서가 변경되었는지 물어보는 것

  1. 재검사 결과 컨텐츠가 변경 👉 캐시는 문서의 새로운 사본을 가져와 저장한 뒤 클라이언트에게도 전송
  2. 재검사 결과 컨텐츠 변경되지 않음 👉 캐시는 새 만료일을 포함한 새 헤더들만 가져와 캐시 내 헤더들 갱신

HTTP는 캐시가 다음 중 하나를 반환할 것을 요구

  1. '충분히 신선한' 캐시된 사본
  2. 에러 메시지 (재검사해야 하는 원 서버가 다운된 경우)
  3. 경고 메시지가 부착된 캐시된 사본 (부정확하다면)

7.8.4. 조건부 메서드와의 재검사

HTTP의 조건부 메서드는 재검사를 효율적으로 만들어줌

HTTP는 캐시가 서버에게 '조건부 GET' 요청을 보낼 수 있도록 함

👉 서버가 갖고 있는 문서가 캐시가 갖고 있는 것과 다를 때만 객체 본문을 보내달라고 하는 것

조건부 GET은 GET 요청 메시지에 특별한 조건부 헤더를 추가해서 시작됨 (모든 조건부 헤더는 'If-'로 시작)

캐시 재검사를 위해 사용되는 조건부 응답 헤더

  1.  If-Modified-Since: <date>
    • 문서가 주어진 날짜 이후로 수정됐다면 요청 메서드 처리
    • 캐시된 버전으로부터 컨텐츠가 변경된 경우에만 컨텐츠를 가져오므로 Last-Modified 서버 응답 헤더와 함께 사용
  2. If-None-Match: <tags>
    • 서버는 문서에 대한 특별한 태그를 제공
    • 캐시된 태그가 서버에 있는 문서의 태그와 다를 때만 요청 처리

7.8.5. If-Modified-Since: 날짜 재검사

흔히 'IMS' 요청으로 불림.

IMS 요청은 서버에게 리소스가 특정 날짜 이후로 변경된 경우에만 요청한 본문 보내달라 함

  1. 문서가 주어진 날짜 이후에 변경됐다면, If-Modified-Since 조건은 참이고 GET 요청은 성공. 새 문서가 새로운 만료 날짜와 다른 정보들이 담긴 헤더들과 함께 캐시에게 반환됨
  2. 변경되지 않았다면 If-Modified-Since 조건은 거짓이고, 서버는 304 Not Modified 응답 메시지 클라이언트에게 보냄. 효율을 위해 본문은 보내지 않음. 응답에는 헤더들을 포함하되 갱신이 필요한 것만 보낸다

If-Modified-Since 헤더는 서버 응답 헤더의 Last-Modified 헤더와 함께 동작.

원 서버는 제공하는 문서에 최근 변경 일시를 붙임. 캐시가 캐시된 문서를 재검사 할 때, 캐시된 사본이 마지막으로 수정된 날짜가 담긴 If-Modified-Since헤더 포함

If-Modified-Since: <캐시된 마지막 수정일>

몇몇 웹 서버는 IMS 날짜와 최근 변경일 간의 문자열 비교를 수행

👉 "정확히 이 날짜에 마지막 변경이 일어난 것이 아니라면"이라는 의미로 동작

7.8.6. If-None-Match: 엔터티 태그 재검사

최근 변경 일시 재검사가 일어나기 어려운 상황

  1. 일정 시간 간격으로 다시 쓰이지만 내용에는 아무런 변화가 없는 경우
  2. 캐시들이 다시 읽어들이기엔 다소 사소한 변경일 경우
  3. 어떤 서버들은 그들이 갖고 있는 페이지에 대한 최근 변경 일시를 정확하게 판별할 수 없음
  4. 1초보다 작은 간격으로 갱신되는 문서를 제공하는 서버에게는 변경일에 대한 1초의 정밀도는 충분치 않을 수 있음

퍼블리셔가 문서를 변경하면, 그는 문서의 엔터티 태그를 새로운 버전으로 표현한다

엔터티 태그 변경되면 캐시는 새 문서의 사본 얻으려고 If-None-Match 조건부 헤더 사용

요청 메시지에 If-None-Match: "v2.6" 포함되어 있을 경우
👉 서버의 태그가 v2.6일 경우 서버는 304 Not Modified 응답 반환
👉 서버의 태그가 v2.6이 아닐 경우 200 OK 응답으로 새 컨텐츠를 새 ETag와 함께 반환

❗️ 캐시가 객체에 대한 사본을 여러 개 갖고 있을 경우, 하나의 If-None-Match 헤더에 여러 개의 엔터티 태그를 포함시킬 수 있음

If-None-Match: "v2.4", "v2.6", "v2.8"

7.8.7. 약한 검사기와 강한 검사기

캐시는 캐시된 버전이 최신인지 확인하기 위해 엔터티 태그 사용(최근 변경일시 사용하는 것과 비슷)

캐시 검사기 👉 엔터티 태그최근 변경일시

  1. 약한 검사기
    • 서버가 모든 캐시된 사본을 무효화시키지 않고 문서를 살짝 고치는데 사용
    • 컨텐츠가 조금 변경됐어도 '그 정도면 같은 것'이라고 서버가 주장할 수 있도록 해줌
    • HTTP/1.1이 지원
    • 서버는 'W/' 접두사로 약한 검사기 구분
  2. 강한 검사기
    • 컨텐츠가 바뀔 때마다 바뀌도록 함

강한 엔터티 태그는 대응하는 엔터티 값이 바뀌면 같이 바뀜

약한 엔터티 태그는 대응하는 엔터티에 유의미한 변경이 있을 때마다 같이 바뀜

원 서버는 다른 두 엔터티에 대해 엔터티 태그 값을 재활용해서는 안 됨

7.8.8. 언제 엔터티 태그와 Last-Modified 일시를 사용하는가

서버가 엔터티 태그 반환

👉 HTTP/1.1 클라이언트는 반드시 엔터티 태그 검사기 사용

서버가 Last-Modified 값만 반환

👉 클라이언트는 If-Modified-Since 검사 사용할 수 있음

만약 엔터티 태그와 최근 변경 일시가 모두 사용 가능

👉 HTTP/1.0, HTTP/1.1 캐시 모두 응답할 수 있도록 클라이언트는 두 가지의 재검사 정책을 사용해야 함

HTTP/1.1 원 서버는 가능하면 엔터티태그 검사기를 보내야 함

만일 HTTP/1.1 캐시나 서버가 If-Modified-Since와 엔터티 태그 조건부 헤더를 모두 받았다면,

요청의 모든 조건부 헤더 필드의 조건에 부합될때만 304 Not Modified 응답 반환

7.9. 캐시 제어

HTTP는 문서가 만료되기 전까지 얼마나 오랫동안 캐시될 수 있는지 서버가 설정하는 여러가지 방법을 정의

  1. Cache-Control: no-store 헤더를 응답에 첨부
  2. Cache-Control: no-cache 헤더를 응답에 첨부
  3. Cache-Control: must-revalidate 헤더를 응답에 첨부
  4. Cache-Control: max-age 헤더를 응답에 첨부
  5. Expires 날짜 헤더를 응답에 첨부
  6. 아무 만료 정보도 주지 않고, 캐시가 스스로 체험적인(휴리스틱) 방법으로 결정할 수 있게 함

7.9.1. no-cache와 no-store 응답 헤더

HTTP/1.1은 신선도 관리 위해 객체를 캐시하는 것을 제한하거나 캐시된 객체를 제공하는 여러 방법 제공

no-cache와 no-store 헤더는 캐시가 검증되지 않은 캐시된 객체로 응답하는 것을 막음

  1. 'no-store'로 표시된 응답
    • 캐시가 해당 응답의 사본을 만드는 것을 금지
    • 캐시는 클라이언트에게 해당 응답 전달한 뒤에 객체 삭제함 
  2. 'no-cache'로 표시된 응답
    • 로컬 캐시 저장소에 저장될 수 있음
    • 하지만 서버와 재검사를 하지 않고서는 캐시에서 클라이언트로 제공될 수 없음
  3. Pragma: no-cache 헤더
    • HTTP/1.0+와의 하위호환성을 위해 HTTP/1.1에 포함되어 있음
    • HTTP/1.1 앱은 Pragma: no-cache만 이해할 수 있는 HTTP/1.0 앱에 대응해야 하는 경우가 아니라면 Cache-Control: no-cache를 사용해야 함

7.9.2. Max-Age 응답 헤더

Cache-Control: max-age 헤더는 문서가 서버로부터 온 이후로 흐른 시간을 나타낸다. (단위는 초)

s-maxage 헤더는 max-age처럼 행동하지만 공용 캐시에만 적용된다.

7.9.3. Expires 응답 헤더

Expires 헤더는 실제 만료 날짜를 명시

👉 많은 서버가 동기화되어 있지 않거나 부정확한 시계를 가지고 있기 때문에 만료를 절대시각으로 표현하는 것은 더 이상 권장되지 않음

7.9.4. Must-Revalidate 응답 헤더

Cache-Control: must-revalidate 응답 헤더는 캐시가 이 객체의 만료된 사본을 원 서버와의 재검사 없이는 제공해서는 안 됨을 의미 

캐시가 must-revalidate 신선도 검사를 했을 때 원 서버가 사용할 수 없는 상태면, 캐시는 504 Gateway Timeout error를 반환

7.9.5. 휴리스틱 만료

만약 응답이 Cache-Control: max-age 헤더나 Expires 헤더를 모두 포함하고 있지 않다면, 캐시는 경험적인 방법으로(heuristic) 최대 나이를 계산한다.

계산 결과 얻은 최대 나이 값이 24시간보다 크면, Heuristic Expiration 경고헤더가 응답 헤더에 추가되어야 함

 

LM 인자 알고리즘

  1. 휴리스틱 만료 알고리즘
  2. 문서가 최근 변경 일시를 포함할 경우 사용 가능
  3. 최근 변경 일시를 문서가 얼마나 자주 바뀌는지에 대한 추정에 사용
  4. 로직
    • 캐시된 문서가 마지막으로 변경된 것이 예전이면, 이 문서는 안정적인 문서일 것이고 변경될 가능성이 적기 때문에 캐시에 오래 보관하고 있어도 안전하다
    • 캐시된 문서가 최근에 변경됐으면 해당 문서는 자주 변경될 것이기에 서버와 재검사하기 전까지 짧은 기간 동안만 캐시해야 함
  5. 캐시가 서버와 대화했을 때와 서버가 문서의 최근 변경 일시를 말해줬을 때의 시간차를 계산하고, 이 차의 일부분을 취해, 이 일부분을 캐시의 신선도 지속기간으로 사용

보통 휴리스틱 신선도 유지기간에 상한을 설정해서 값이 커지는 것을 막음

최근 변경일이 없을 경우에는 기본 신선도 유지기간을 설정

아직 많은 서버들이 Expiresmax-age 헤더를 생성하지 못한다는 것을 유의

7.9.6. 클라이언트 신선도 제약

웹브라우저는 신선하지 않은 컨텐츠를 갱신시켜주는 리프레시나 리로드 버튼을 갖고 있음

리프레시 버튼은 Cache-control 요청 헤더가 추가된 GET 요청을 발생시켜 강제로 재검사하거나 서버로부터 컨텐츠를 가져옴

클라이언트는 Cache-control 요청 헤더를 사용해 만료 제약을 설정한다

7.9.7. 주의할 점

문서 만료는 완벽한 시스템이 아니라는 것을 명심.

퍼블리셔가 유효기간을 잘못 설정하면 문서의 변경이 캐시에 반영되지 않음.

때로는 퍼블리셔가 유효기간을 사용하지 않아 문서의 신선도를 캐시가 파악하지 못하는 경우도 있음

7.10. 캐시 제어 설정

웹 서버들은 캐시 제어와 만료 HTTP 헤더들을 설정하는 메커니즘을 제공

이 장에서는 아파치 웹 서버가 캐시 제어를 어떻게 지원하는지 설명

(자세하게 쓰지는 않음 책 읽자)

7.11. 자세한 알고리즘

HTTP 신선도 계산 알고리즘에 대해 설명

7.11.1. 나이와 신선도 수명

캐시된 사본의 나이신선도 수명을 알면 문서가 얼마나 신선한지 계산할 수 있음

캐시된 사본의 나이가 신선도 수명보다 작으면 사본은 신선한 것

문서의 나이는 서버가 문서를 보낸(or 서버가 마지막으로 재검사한) 후 그 문서가 '나이를 먹은' 시간의 총합

문서의 신선도 수명은 아직 문서가 신선하다고 볼 수 있는 수명

신선도 수명의 계산에는 문서의 유효기간과 신선도에 영향을 주는 클라이언트의 모든 요청을 고려

캐시는 서버 만료 정보와 클라이언트 신선도 요구사항을 조합해 최대 신선도 수명을 판별

7.11.2. 나이 계산

응답의 나이는 응답이 서버에서 생성되었을 때부터 지금까지의 총 시간

👉 응답이 인터넷상의 라우터들과 게이트웨이들 사이를 떠돌아다닌 시간과 응답이 캐시에 머물렀던 시간을 포함

캐시는 응답 캐시의 Date나 Age 헤더를 분석해 얼마나 오래된 것인지 알 수 있음

또한, 그 문서가 로컬 캐시에 얼마나 오래 머물렀는지도 알 수 있음

👉 이 둘을 합한 것이 응답의 전체 나이

캐시에서 온 응답의 나이를 알아내는 것은 어려움 

👉 모든 서버가 동기화된 시계를 갖고 있지 않으며 응답이 어디에서 왔는지 알 수 없음

 

나이 계산 알고리즘

  1. 겉보기 나이는 Date 헤더에 기반
    • 모든 컴퓨터가 똑같이 정확한 시계를 갖고 있으면 현재 시간에서 서버가 문서를 보낸 시간을 뺀 것이 캐시된 문서의 '겉보기 나이'
    • 하지만, 모든 시계가 동기화되어 있지 않음
    • 두 컴퓨터의 시계 설정 차이로 인해 발생하는 문제를 클록 스큐라 함
    • 프락시와 캐시는 Date 헤더를 절대 변경해서는 안 됨
  2. 점층적 나이 계산
    • HTTP/1.1은 문서가 프락시나 캐시를 통과할 때마다 Age 헤더에 상대적인 나이를 누적해서 더함
    • 비 HTTP/1.1 장치는 Age 헤더를 인식하지 못하고 헤더를 변경하거나 삭제함
    • 해당 방식은 완벽하지 못함
  3. 네트워크 지연에 대한 보상
    • 문서가 교통 혼잡에 긴 시간동안 네트워크나 서버에 갇혀있게 되면 상대 나이를 계산하는 방식은 맞지 않음
    • Date 헤더는 언제 문서가 원 서버를 떠났는지만 알려주고 문서가 캐시로 옮겨가는 도중에 얼마나 시간을 소비했는지는 말해주지 않음
    • 서버와 캐시 사이의 왕복 지연 계산은 쉬운 편
    • 캐시는 언제 문서를 요청했고 도착했는지 알고 있음
    • HTTP/1.1은 이를 이용해 계산한 전체 왕복 시간을 더함으로써 네트워크 지연을 보수적(더 큰 것)으로 교정

 

 

 

'HTTP 완벽 가이드 책 정리' 카테고리의 다른 글

9장. 웹 로봇  (0) 2021.07.09
8장. 통합점: 게이트웨이, 터널, 릴레이  (0) 2021.07.04
6장. 프락시  (0) 2021.07.02