캐시

DevSeong2·2021년 8월 10일
1

HTTP

목록 보기
7/7
post-thumbnail
『HTTP 완벽 가이드』 교재와 다른 레퍼런스를 참고하여 작성하였습니다.

캐시

웹 캐시는 자주 쓰이는 문서의 사본을 자동으로 보관하는 HTTP 장치입니다. 복수의 클라이언트가 자주 쓰이는 원 서버 페이지에 접근할 때, 서버는 같은 문서를 클라이언트에게 각각 한 번씩 전송하게 됩니다. 똑같은 바이트들이 네트워크를 통해 계속 반복해서 이동합니다. 이 불필요한 데이터 전송은 값비싼 네트워크 대역폭을 잡아먹고, 전송을 느리게 만들며, 웹 서버에 부하를 줍니다. 캐시를 이용하면, 첫 번째 서버 응답은 캐시에 보관됩니다. 캐시된 사본이 뒤이은 요청들에 대한 응답으로 사용될 수 있기 때문에, 원 서버가 중복해서 트래픽을 주고받는 낭비가 줄어들게 됩니다.

대역폭 병목

많은네트워크가 원격 서버보다 로컬 네트워크 클라이언트에 더 넓은 대역폭을 제공합니다. 클라이언트들이 서버에 접근할 때의 속도는, 그 경로에 있는 가장 느린 네트워크의 속도와 같습니다. 만약 클라이언트가 빠른 LAN 에 있는 캐시로부터 사본을 가져온다면, 캐싱은 성능을 대폭 개선할 수 있을 것입니다.

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

캐싱은 갑작스런 요청 쇄도에 대처하기 위해 특히 중요합니다. 갑작스런 사건으로 인해 많은 사람이 거의 동시에 웹 문서에 접근할 때 이런 일이 발생합니다. 이 결과로 초래된 불필요한 트래픽 급증은 네트워크와 웹 서버의 심각한 장애를 야기시킵니다.

거리로 인한 지연

모든 네트워크 라우터는 제각각 인터넷 트래픽을 지연시킵니다. 그리고 클라이언트와 서버 사이에 라우터가 그다지 많지 않더라도, 빛의 속도 그 자체가 유의미한 지연을 유발합니다.

적중과 부적중🎯

캐시에 요청이 도착했을 때, 만약 그에 대응하는 사본이 있다면 그를 이용해 요청이 처리될 수 있습니다[캐시 적중(cache hit)]. 만약 대응하는 사본이 없다면 그냥 원 서버로 적중되기만 할 뿐입니다[캐시 부적중(cache miss)].

재검사(Revalidation)

원 서버 콘텐츠는 변경될 수 있기 때문에, 캐시는 반드시 그들이 갖고 있는 사본이 여전히 최신인짖 서버를 통해 때때로 점검해야 합니다. 이러한 '신선도 검사'를 HTTP 재검사라 부릅니다. 캐시는 스스로 원한다면 언제든지 사본을 재검사할 수 있습니다. 그러나 캐시가 문서를 수백만 개씩 갖고 있는 경우가 흔한데 비해 네트워크 대역폭은 부족하기 때문에, 대부분의 캐시는 클라이언트가 사본을 요청하였으며 그 사본이 검사를 할 필요가 있을 정도로 충분히 오래된 경우에만 재검사를 합니다.

캐시는 캐시된 사본의 재검사가 필요할 때, 원 서버에 작은 재검사 요청을 보냅니다. 콘텐츠가 변경되지 않았다면, 서버는 아주 작은 Not Modified 응답을 보냅니다. 그 사본이 유효함을 알게 된 캐시는 즉각 사본이 신선하다고 임시로 다시 표시한 뒤 그 사본을 클라이언트에 제공합니다. 이를 재검사 적중 혹은 느린 적중이라고 부릅니다.
속도: 순수 캐시 적중 > 재검사 적중 > 캐시 부적중

HTTP는 캐시된 객체를 재확인하기 위한 몇 가지 도구를 제공하는데, 그중에 가장 많이 쓰이는 것은 If-Modified-Since 헤더입니다. 서버에게 보내는 GET 요청에 이 헤더를 추가하면 캐시된 시간 이후에 변경된 경우에만 사본을 보내달라는 의미입니다.

재검사 적중: 서버 객체가 변경되지 않았다면, 서버➡클라이언트 HTTP 304 Not Modified
재검사 부적중: 서버 객체가 캐시된 사본과 다르다면, HTTP 200 OK
객체 삭제: 서버 객체가 삭제되었다면, 404 Not Found

적중률

캐시가 요청을 처리하는 비율을 캐시 적중률(혹은 캐시 적중비), 혹은 문서 적중률(혹은 문서 적중비)이라고 부르기도 합니다.
0% (모두캐시 부적중) ~ 100% (모두 캐시 적중)
오늘날 적중률 40%면 웹 캐시로 괜찮은 편이며 보통 크기의 캐시라도 충분한 분량의 자주 쓰이는 문서들을 보관하여 상당히 트래픽을 줄이고 성능을 개선할 수 있다는 점입니다.

바이트 적중률

문서들이 모두 같은 크기인 것은 아니기 때문에 문서 적중률이 모든 것을 말해주지는 않습니다. 몇몇 큰 객체는 덜 접근되지만 그 크기 때문에 전체 트래픽에는 더 크게 기여합니다.
바이트 단위 적중률은 캐시를 통해 제공된 모든 바이트의 비율을 표현합니다. 이 측정값은 트래픽이 절감된 정도를 포착해냅니다.

문서 적중률은 얼마나 많은 웹 트랜잭션을 외부로 내보내지 않았는지 보여줍니다. - 전체 대기시간(지연) 감소
바이트 단위적중률은 얼마나 많은 바이트가 인터넷으로 나가지 않았는지보여줍니다. - 대역폭 절약을 최적화

적중과 부적중의 구별

HTTP는 클라이언트에게 응답이 캐시 적중이었는지 아니면 원 서버 접근인지 말해줄 수 있는 방법을 제공하지 않습니다. 두 경우 모두 응답 코드는 응답이 본문을 갖고 있음을 의미하는 200 OK가 될 것입니다.

클라이언트가 응답이 캐시에서 왔는지 알아내는 한 가지 방법은 Date 헤더를 이용하는 것입니다. 응답의 Date 헤더 값을 현재 시각과 비교하여, 응답의 생성일이 더 오래되었다면 클라이언트는 응답이 캐시된 것임을 알아낼 수있습니다. 또 다른 방법은, 응답이 얼마나 오래되었는지 말해주는 Age 헤더를 이용하는 것입니다.

캐시 토폴로지

캐시는 한 명의 사용자에게만 할당할 수도 있고(개인 전용 캐시) 반대로 수천 명의 사용자들 간에 공유될 수도 있습니다(공용 캐시).

개인 전용 캐시

개인 전용 캐시는 많은 에너지나 저장 공간을 필요로 하지 않으므로, 작고 저렴할 수 있습니다. 웹브라우저는 개인 전용 캐시를 내장하고 있습니다. 대부분의 브라우저는 자주 쓰이는 문서를 개인용 컴퓨터의 디스크와 메모리에 캐시해 놓고, 사용자가 캐시 사이즈와 설정을 수정할 수 있도록 허용하며 확인할 수 있습니다.

공용 프락시 캐시

공용 캐시는 캐시 프락시 서버 혹은 더 흔히 프락시 캐시라고 불리는 특별한 종류의 공유된 프락시 서버입니다. 프락시 캐시는 로컬 캐시에서 문서를 제공하거나, 혹은 사용자의 입장에서 서버에 접근합니다. 공용 캐시에는 여러 사용자가 접근하기 때문에, 불필요한 트래픽을 줄일 수 있는 더 많은 기회가 있습니다.
공유 캐시에서, 캐시는 자주 찾는 객체를 단 한 번만 가져와 모든 요청에 대해 공유된 사본을 제공함으로써 네트워크 트래픽을 줄입니다.

프락시 캐시 계층들

작은 캐시에서 캐시 부적중이 발생했을 때 더 큰 부모 캐시가 그 '걸러 남겨진' 트래픽을 처리하도록 하는 계층을 만드는 방식이 합리적인 경우가 많습니다. 클라이언트 주위에는 작고 저렴한 캐시를 사용하고, 계층 상단에는 많은 사용자들에 의해 공유되는 문서를 유지하기 위해 더 크고 강력한 캐시를 사용하자는 것입니다. 캐시 계층이 깊다면 요청은 캐시의 긴 연쇄를 따라가게ㅔ 될 것이며 프락시 연쇄가 길어질수록 각 중간 프락시는 현저한 성능 저하가 발생할 것입니다.

캐시망, 콘텐츠 라우팅, 피어링

캐시망의 프락시 캐시는 복잡한 방법으로 서로 대화하여, 어떤 부모 캐시와 대화할 것인지, 아니면 요청이 캐시를 완전히 우회해서 원 서버로 바로 가도록 할 것인지에 대한 캐시 커뮤니케이션 결정을 동적으로 내립니다.

  • URL에 근거하여, 부모 캐시와 원 서버 중 하나를 동적으로 선택합니다.
  • URL에 근거하여 특정 부모 캐시를 동적으로 선택합니다.
  • 부모 캐시에게 가기 전에, 캐시된 사본을 로컬에서 찾아봅니다.
  • 다른 캐시들이 그들의 캐시된 콘텐츠에 부분적으로 접근할 수 있도록 허용하되, 그들의 캐시를 통한 인터넷 트랜짓은 허용하지 않습니다.

더 복잡한 캐시 사이의 관계는, 서로 다른 조직들이 상호 이득을 위해 그들의 캐시를 연결하여 서로를 찾아볼 수 있도록 해줍니다. 선택적인 피어링을 지원하는 캐시는 형제 캐시라고 불립니다. HTTP는 형제 캐시를 지원하지 않기 때문에, 사람들은 인터넷 캐시 프로토콜(ICP)이나 하이퍼텍스트 캐시 프로토콜(HTCP) 같은 프로토콜을 이용해 HTTP를 확장했습니다.

캐시 처리 단계

HTTP GET 메시지 하나를 처리하는 기본적인 캐시 처리 절차는 일곱 단계로 이루어져 있습니다.
1. 요청 받기 - 캐시는 네트워크로부터 도착한 요청 메시지를 읽습니다.
2. 파싱 - 캐시는 메시지를 파싱하여 URL과 헤더들을 추출합니다.
3. 검색 - 캐시는 로컬 복사본이 있는지 검사하고, 사본이 없다면 사본을 받아옵니다.
4. 신선도 검사 - 캐시는 캐시된 사본이 충분히 신선한지 검사하고, 신선하지 않다면 변경사항이 있는지 서버에게 물어봅니다.
5. 응답 생성 - 캐시는 새로운 헤더와 본문으로 응답 메시지를 만듭니다.
6. 발송 - 캐시는 네트워크를 통해 응답을 클라이언트에게 돌려줍니다.
7. 로깅 - 선택적으로, 캐시는 로그파일에 트랜잭션에 대해 서술한 로그 하나를 남깁니다.

단계 1: 요청 받기

캐시는 네트워크 커넥션에서의 활동을 감지하고, 들어오는 데이터를 읽어들입니다. 고성능 캐시는 여러 개의 들어오는 커넥션들로부터 데이터를 동시에 읽어들이고 메시지 전체가 도착하기 전에 트랜잭션 처리를 시작합니다.

단계 2: 파싱

캐시는 요청 메시지를 여러 부분으로 파싱하여 헤더 부분을 조작하기 쉬운 자료 구조에 담습니다. 이는 캐싱 소프트웨어가 헤더 필드를 처리하고 조작하기 쉽게 만들어줍니다.

단계 3: 검색

캐시는 URL을 알아내고 그에 해당하는 로컬 사본이 있는지 검사합니다. 로컬 복사본은 메모리에 저장되어 있을 수도 있고, 아니면 디스크나 심지어 근처의 다른 컴퓨터에 있을 수도 있습니다. 문서를 로컬에서 가져올 수 없다면, 캐시는 상황이나 설정에 따라서 그것을 원 서버나 부모 프락시에서 가져오거나 혹은 실패를 반환합니다

단계 4: 신선도 검사

HTTP는 캐시가 일정 기간 동안 서버 문서의 사본을 보유할 수 있도록 해줍니다. 캐시된 사본을 신선도 한계를 넘을 정도로 너무 오래 갖고 있었다면 그 객체는 '신선하지 않은' 것으로 간주되며, 캐시는 그 문서를 제공하기 전에 문서에 어떤 변경이 있었는지 검사하기 위해 서버와 재검사를 해야 합니다.

단계 5: 응답 생성

우리는 캐시된 응답을 원 서버에서 온 것처럼 보이게 하고 싶기 때문에, 캐시는 캐시된 서버 응답 헤더를 토대로 응답 헤더를 생성합니다. 캐시는 클라이언트에 맞게 헤더를 조정해야 하는 책임이 있습니다. 캐시는 헤더를 적절하게 번역해야 하고 캐시 신선도 정보를 삽입하며, 또 요청이 프락시 캐시를 거쳐갔음을 알려주기 위해 종종 Via 헤더를 포함시킵니다.

단계 6: 전송

응답 헤더가 준비되면, 캐시는 응답을 클라이언트에게 돌려줍니다. 모든 프락시 서버들과 마찬가지로, 프락시 캐시는 클라이언트와의 커넥션을 유지할 필요가 있습니다.

단계 7: 로깅

대부분의 캐시는 로그 파일과 캐시 사용에 대한 통계를 유지합니다. 각 캐시 트랜잭션이 완료된 후, 캐시는 통계 캐시 적중과 부적중 횟수에 대한 통계를 갱신하고 로그 파일에 요청 종류, URL 그리고 무엇이 일어났는지를 알려주는 항목을 추가합니다.

캐시 처리 플로 차트

사본을 신선하게 유지하기

캐시된 사본 모두가 서버의 문서와 항상 일치하는 것은 아닙니다. 결국 문서들은 시간에 따라 변경되기 때문에 캐시된 데이터는 서버의 데이터와 일치하도록 관리되어야 합니다.
HTTP는 어떤 캐시가 사본을 갖고 있는지 서버가 기억하지 않더라도, 캐시된 사본이 서버와 충분히 일치하도록 유지할 수 있게 해주는 서버 재검사라고 불리는 단순한 메커니즘을 갖고 있습니다.

문서 만료

HTTP는 Cache-ControlExpires라는 특별한 헤더들을 이용해서 원 서버가 각 문서에 유효기간을 붙일 수 있게 해줍니다. 캐시 문서가 만료되기 전에, 캐시는 필요하다면 서버와의 접촉 없이 사본을 제공할 수 있습니다. 그러나 캐시된 문서가 만료되면, 캐시는 반드시 서버와 문서에 변경된 것이 있는지 검사해야 하며, 그렇다면 신선한 사본을 얻어 와야 합니다.

유효기간과 나이

서버는 응답 본문과 함께 하는, HTTP/1.0+ ExpiresHTTP/1.1 Cache-Control: max-age 응답 헤더를 이용해서 유효기간을 명시합니다.

헤더설명
Cache-Control: max-age문서의 최대 나이를 정의합니다. 최대 나이는 문서가 처음 생성된 이후부터, 신선하지 않다고 간주될 때까지 경과한 시간의 합법적인 최댓값(초 단위)입니다.
Cache-Control: max-age=484200
Expires절대 유효기간을 명시합니다. 만약 유효기간이 경과했다면, 그 문서는 더 이상 신선하지 않음을 뜻합니다.
Expires: Fri, 05 Jul 2002, 05:0:00 GMT

서버 재검사

캐시된 문서가 만료되었다는 것은, 그 문서가 원 서버에 현재 존재하는 것과 실제로 다르다는 것을 의미하지는 않으며, 다만 이제 검사할 시간이 되었음을 뜻합니다. 캐시가 원 서버에게 문서가 변경되었는지의 여부를 물어볼 필요가 있음을 의미하는 이 검사를 서버 재검사 라고 부릅니다.

  • 재검사 결과 콘텐츠가 변경되었다면, 캐시는 그 문서의 새로운 사본을 가져와 오래된 데이터 대신 저장한 뒤 클라이언트에게도 보내줍니다.
  • 재검사 결과 콘텐츠가 변경되지 않았다면, 캐시는 새 만료일을 포함한 새 헤더들만 가져와서 캐시 안의 헤더들을 갱신합니다.

캐시는 문서의 신선도를 매 요청마다 검증할 필요가 없이 문서가 만료되었을 때 한번만 서버와 재검사하면 됩니다.

HTTP 프로토콜은 캐시가 다음 중 하나를 반환하는 적절한 행동을 할 것을 요구합니다.

  • '충분히 신선한' 캐시된 사본
  • 원 서버와 재검사되었기 때문에, 충분히 신선하다고 확신할 수 있는 캐시된 사본
  • 에러 메시지(재검사해야 하는 원 서버가 다운된 경우)
  • 경고 메시지가 부착된 캐시된 사본(부정확하다면)

조건부 메서드와의 검사

HTTP는 캐시가 서버에게 '조건부 GET'이라는 요청을 보낼 수 있도록 해줍니다. 이 요청은 서버가 갖고 있는 문서가 캐시가 갖고 있는 것과 다른 경우에만 객체 본문을 보내달라고 하는 것입니다. 조건부 GET은 GET 요청 메시지에 특별한 조건부 헤더를 추가함으로써 시작됩니다.

헤더설명
If-Modified-Since: <date>만약 문서가 주어진 날짜 이후로 수정되었다면 요청 메서드를 처리. 이것은 캐시된 버전으로부터 콘텐츠가 변경된 경우에만 콘텐츠를 가져오기 위해 Last-Modified 서버 응답 헤더와 함께 사용됩니다.
If-None-Match: <tags>마지막 변경된 날짜를 맞춰보는 대신, 서버는 문서에 대한 일련번호와 같이 동작하는 특별한 태그를 제공할 수 있습니다.
캐시된 태그가 서버에 있는 문서의 태그와 다를 때만 요청을 처리합니다.

If-Modified-Since: 날짜 재검사

If-Modified-Since 재검사 요청은 'IMS' 요청으로 불립니다.

  • 만약 문서가 주어진 날짜 이후에 변경되었다면, If-Modified-Since 조건은 참이고, 따라서 GET 요청은 평범하게 성공합니다. 새 문서가, 새로운 만료 날짜와 그 외 다른 정보들이 담긴 헤더들과 함께 캐시에게 반환됩니다.
  • 만약 주어진 날짜 이후에 변경되지 않았다면 조건은 거짓이고, 서버는 작은 304 Not Modified응답 메시지를 클라이언트에게 돌려줍니다. 효율을 위해 본문은 보내지 않고 갱신이 필요한 것만을 보내줍니다.

몇몇 웹 서버는 If-Modified-Since를 실제 날짜 비교로 구현하지 않습니다. 대신 그들은 IMS 날짜와 최근 변경일 간의 문자열 비교를 수행합니다. 즉 "이 날짜 이후로 변경되었다면"이 아니라 "정확히 이 날짜에 마지막 변경이 일어난 것이 아니라면"이라는 의미로 동작

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

최근 변경 일시 재검사가 적절히 행해지기 어려운 상황이 몇 가지 있습니다.

  • 어떤 문서는 일정시간 간격으로 다시 쓰여지지만 실제로는 같은 데이터를 포함하고 있습니다. 내용에는 아무 변화가 없더라도 변경시각은 바뀔 수 있습니다.
  • 어떤 문서들의 변경은 전 세계의 캐시 들이 그 데이터를 읽어들이기엔 사소한 것일 수도 있습니다. (ex. 철자나 주석 변경)
  • 어떤 서버들은 그들이 갖고 있는 페이지에 대한 최근 변경 일시를 정확하게 판별할 수 없습니다.
  • 1초보다 작은 간격으로 갱신되는 문서를 제공하는 서버들에게는, 변경일에 대한 1초의 정밀도는 충분하지 않을 수 있습니다.

문서를 변경했을 때, 문서의 엔터티 태그를 새로운 버전으로 표현할 수있습니다. 엔터티 태그가 변경되었다면, 캐시는 새 문서의 사본을 얻기(GET) 위해 If-None-Match 조건부 헤더를 사용할 수 있습니다. 만약 서버의 엔터티 태그가 변경되었다면 서버는 200 OK 응답으로 새 콘텐츠를 새 ETag와 함께 반환할 것입니다.

약한 검사기와 강한 검사기

캐시는 캐시된 버전이 서버가 갖고있는 것에 대해 최신인지 확인하기 위해 엔터티 태그를 사용합니다. 이 경우, 엔터티 태그와 최근 변경일시는 둘 다 캐시 검사기입니다.
서버는 때때로 모든 캐시된 사본을 무효화시키지 않고 문서를 살짝 고칠 수 있도록 허용하고 싶은 경우가 있습니다. HTTP/1.1은, 비록 코넨츠가 조금 변경되었더라도 "그 정도면 같은 것"이라고 서버가 주장할 수 있도록 해주는 약한 검사기(week validator)를 지원합니다.
강한 검사기(strong validator)는 콘텐츠가 바뀔 때마다 바뀝니다. 조건부 특정범위 가져오기 같은 몇몇 동작은 약한 검사기로는 불가능하기 때문에, 서버는 W/ 접두사로 약한 검사기를 구분합니다.

ETag: W/"v2.6"
If-None-Match: W/"v2.6"

강한 엔터티 태그는 대응하는 엔터티 값이 어떻게 바뀌든 매번 반드시같이 바뀌어야 합니다. 약한 엔터티 태그는 대응하는 엔터티에 유의미한 변경이 있을 때마다 같이 변경되어야 합니다.

언제 엔터티 태그를 사용하고 언제 Last-Modified 일시를 사용하는지

HTTP/1.1 클라이언트는 만약 서버가 엔터티 태그를 반환했다면, 반드시 엔터티 태그 검사기를 사용해야 합니다. 만약 서버가 Last-Modified 값만을 반환했다면, 클라이언트는 If-Modified-Since 검사를 사용할 수 있습니다. 만약 엔터티 태그와 최근 변경일시가 모두 사용 가능하다면, HTTP/1.0과 HTTP/1.1 캐시 모두 적절히 응답할 수 있도록 클라이언트는 각각을 위해 두 가지의 재검사 정책을 모두 사용해야 합니다.

캐시 제어

HTTP는 문서가 만료되기 전까지 얼마나 오랫동안 캐시될 수 있게 할 것인지 서버가 설정할 수 있는 여러 가지 방법을 정의합니다.

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

no-cache와 no-store 응답 헤더

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

Cache-Control: no-store
Cache-Control: no-cache
Pragma: no-cache

'no-store'가 표시된 응답은 캐시가 그 응답의 사본을 만드는 것을 금지합니다.
'no-cache'로 표시된 응답은 먼저 서버와 재검사를 하지 않고서는 캐시에서 클라이언트로 제공할 수 없습니다.
Pragma: no-cache는 캐시가 검증을 위해 원래 서버에 요청을 보내도록 강제한다는 점에서 Cache-Control: no-cache와 유사합니다. Cache-Control HTTP/1.1 헤더가 없는 HTTP/1.0 클라이언트와의 하위 호환성을 위한 경우에만 사용하여야 합니다.

Max-Age 응답 헤더

신선한다고 간주되었던 문서가 서버로부터 온 이후로 흐른 시간이고, 초로 나타냅니다. 또한 s-maxage 헤더는 max-age처럼 행동하지만 공유된(공용) 캐시에만 적용됩니다.

Expires 응답 헤더

더 이상 사용하지 않기를 권하는 Expires 헤더는 초 단위의 시간 대신 실제 만료 날짜를 명시합니다.

Must-Revalidate 응답 헤더

캐시는 성능을 개선하기 위해 신선하지 않은(만료된) 객체를 제공하도록 설정될 수 있습니다. 만약 캐시가 만료 정보를 엄
Cache-Control: must-revalidate 응답 헤더는 캐시가 이 객체의 신선하지 않은 사본을 원 서버와의 최초의 재검사 없이는 제공해서는 안 됨을 의미합니다.

휴리스틱 만료

만약 응답이 Cache-Control: max-age 헤더나 Expires 헤더 중 어느 것도 포함하지 않고 있다면, 캐시는 경험적인 방법으로(heuristic) 유효 기간을 추정합니다.

유명한 휴리스틱 만료 알고리즘의 하나인 LM 인자 알고리즘은 문서가 최근 변경 일시를 포함하고 있다면 사용할 수 있습니다. LM 인자 알고리즘은 최근 변경 일시를 문서가 얼마나 자주 바뀌는지에 대한 추정에 사용합니다.

  • 만약 캐시된 문서가 마지막으로 변경된 것이 상당히 예전이라면, 그것은 아마 안정적인 문서일 것이고 갑자기 바뀔 가능성은 크지 않을 것이므로, 캐시에 더 오래 보관하고 있어도 안전
  • 만약 캐시된 문서가 최근에 변경되었다면, 그것은 아마 자주 변경될 것이고, 따라서 그것을 서버와 재검사하기 전까지 짧은 기간 동안만 캐시

만약 최근 변경일조차 없다면, 캐시는 판단 근거가 될 정보를 그다지 갖지 못한 것이 됩니다. 캐시는 일반적으로 신선도에 대한 아무런 단서가 없는 문서에 대해 기본 신선도 유지기간을 설정합니다.

클라이언트 신선도 제약

웹브라우저는 브라우저나 프락시 캐시의 신선하지 않은 콘텐츠를 강제로 갱신시켜 주는 리프레시나 리로드 버튼을 갖고 있습니다. 이 리프레시 버튼은 Cache-Control 요청 헤더가 추가된 GET 요청을 발생시켜서, 강제로 재검사하거나 서버로부터 콘텐츠를 무조건 가져옵니다.
클라이언트는 Cache-Control 요청 헤더를 사용하여 만료 제약을 엄격하게 하거나 느슨하게 할 수 있습니다.

Cache-Control 요청 지시어

지시어목적
Cache-Control: max-stale
Cache-Control: max-stale = <s>
캐시는 신선하지 않은 문서라도 자유롭게 제공할 수 있습니다. 만약 <s> 매개변수가 지정되면, 클라이언트는 만료시간이 그 매개변수의 값만큼 지닌 문서도 받아들입니다.
Cache-Control: min-fresh = 클라이언트는 지금으로부터 적어도 <s> 초 후까지 신선한 문서만을 받아들입니다.
Cache-Control: max-age = <s>캐시는 <s> 초보다 오랫동안 캐시된 문서를 반환할 수 없습니다.
Cache-Control: no-cache
Pragma: no-cache
이 클라이언트는 캐시된 리소스는 재검사하기 전에는 받아들이지 않을 것입니다.
Cache-Control: no-store이 캐시는 저장소에서 문서의 흔적을 최대한 빨리 삭제해야 합니다.
Cache-Control: only-if-cached클라이언트는 캐시에 들어있는 사본만을 원합니다.

주의할 점

문서 완료는 완벽한 시스템이 아닙니다. 유효기간을 까마득한 미래로 설정해버린다면, 만료되기 전까지는 그 문서에 대한 어떤 변경도 캐시에 반영되지 않을 것입니다.

캐시와 광고

캐시는 성능을 개선하고 트래픽을 줄입니다. 캐시는 사용자를 도와 더 좋은 경험을 제공하고, 또한 네트워크 사업자들이 트래픽을 줄일 수 있도록 도와줍니다.

광고 회사의 딜레마

만약 캐시가 모든 곳에 있다면 콘텐츠 제공자들은 수요를 견디기 위해 대용량 멀티프로세서 우베 서버를 살 필요가 없을 것이며, 같은 데이터를 방문자들에게 몇 번이고 반복해서 보여주기 위해 터무니없는 네트워크 서비스 요금을 지불할 필요도 없을 것입니다.
많은 콘텐츠 제공자가 (사용자가 광고를 볼 때마다)광고를 통해 돈을 법니다. 그것이 캐시와 관련되면 문제가 되는데 캐싱이 완벽하게 동작한다면 원 서버는 HTTP 접근을 전혀 수신하지 않게 됩니다. 인터넷 캐시가 그 접근들을 모두 흡수하기 때문입니다.

퍼블리셔의 응답

오늘날 광고회사들은 캐시가 광고 시청 수를 가로채지 못하도록 모든 종류의 '캐시 무력화' 기법을 사용합니다.
이 캐시 무력화 기법은 단지 프락시 캐시만에 대한 것이 아니라 웹브라우저에서 켜져 있는 캐시를 주요 대상으로 하고 있습니다. 광고의 시청 수를 관리하려는 과하게 의욕적인 시도는, 몇몇 콘텐츠 제공자가 그들의 사이트에 대한 캐싱의 긍정적인 효과를 감소시키고 있습니다.
이상적으로는, 콘텐츠 제공자는 캐시가 그들의 트래픽을 흡수하도록 내버려 두어야 하며, 캐시는 그들에게 적중이 얼마나 많이 일어났는지 알려주어야 합니다.

로그 마이그레이션

이상적인 해결책 하나는 서버로 요청이 가지 않도록 하는 것입니다. 결국 캐시는 모든 적중의 로그를 유지할 수 있습니다. 캐시는 이 로그를 서버에게 나누어 줄 수 있을 것입니다.
불행히도,적중 로그는 그 크기 때문에 옮기기 어렵고 캐시 로그는 개별 콘텐츠 제공자별로 분리될 수 있도록 표준화되어 있지도 조직되어 있지도 않습니다. 뿐만 아니라 인증과 프라이버시 이슈도 있습니다.

적중 측정과 사용량 제한

HTTP에 때때로 특정 URL에 대한 캐시 적중 횟수를 정기적으로 서버에게 돌려주는 Meter라고 하는 새 헤더 하나를 추가합니다. 이 방법은, 서버가 캐시된 문서가 적중한 횟수의 정기적인 업데이트를 캐시로부터 받습니다.

RFC2227

Reference

📗 HTTP caching
📗 HTTP 완벽 가이드

profile
차근차근

0개의 댓글