Post

캐시

7. 캐시

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

  • 캐시는 불필요한 데이터 전송을 줄여서, 네트워크 요금으로 인한 비용을 줄여준다.
  • 캐시는 네트워크 병목을 줄여준다.
  • 캐시는 원 서버에 대한 요청을 줄여준다.
  • 페이지를 먼 곳에서 불러올수록 시간이 많이 걸리는데, 캐시는 거리로 인한 지연을 줄여준다.

7.1 불필요한 데이터 전송

복수의 클라이언트가 자주 쓰이는 원 서버 페이지에 접근할 때, 서버는 클라이언트들에게 해당 문서를 각각 한 번씩 전송

캐시를 이용하면, 서버 응답은 캐시에 보관됨

캐시된 사본이 뒤이은 요청들에 대한 응답으로 사용될 수 있기 때문에, 원 서버가 중복해서 트래픽을 주고받는 낭비가 줄어듬

7.2 대역폭 병목

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

만약 클라이언트가 빠른 LAN에 있는 캐시로부터 사본을 가져온다면, 캐싱은 성능을 대폭 개선 가능

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

대처 가능

7.4 거리로 인한 지연

7.5 적중과 부적중

캐시가 세상 모든 문서의 사본을 저장 X

캐시에 요청이 도착했을 때, 만약 그에 대응하는 사본이 있다면 -> 캐시 적중

대응하는 사본이 없다면 -> 캐시 부적중 -> 원 서버로 전달

7.5.1 재검사

원 서버 콘텐츠는 변경될 수 있기 때문에, 캐시는 반드시 그들이 갖고 있는 사본이 여전히 최신인지 서버를 통해 때때로 점검해야 함 -> 재검사

캐시는 스스로 원한다면 언제든지 사본 재검사 가능

하지만, 네트워크 대역폭이 부족하기 때문에 대부분의 캐시는 클라이언트가 사본을 요청하였으며 그 사본이 검사를 할 필요가 있을 정도로 오래된 경우에만 재검사

캐시는 캐시된 사본의 재검사가 필요할 때, 원 서버에 작은 재검사 요청을 보냄

콘텐츠가 변경되지 않았다면, 304 Not Modified 응답 -> 느린 적중 혹은 재검사 적중

순수 캐시 적중보다 느리고, 캐시 부적중 보다 빠름

HTTP는 캐시된 객체를 재확인하기 위한 몇가지 도구 제공

그중에서 가장 많이 쓰이는 것은 If-Modified-Since

캐시된 시간 이후에 변경된 경우에만 사본을 보내달라는 의미

재검사 적중

304 Not Modified

재검사 부적중

콘텐츠 전체와 함께 평범한 200 응답

객체 삭제

404 Not Found

7.5.2 적중률

캐시가 요청을 처리하는 비율 -> 캐시 적중률

적중률 40%정도면 괜찮은 편

보통 크기의 캐시라도 충분한 분량의 자주 쓰이는 문서들을 보관하여 상단히 트래픽을 줄이고 성능을 개선할 수 있음

7.5.3 바이트 적중률

몇몇 큰 객체는 덜 접근되지만 그 크기 때문에 전체 트래픽에는 더 크게 기여할 수 있음

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

문서 적중률은 얼마나 많은 웹 트랜잭션을 외부로 내보내지 않았는지 보여줌

문서 적중률을 개선하면 전체 대기시간(지연)이 줄어듬

바이트 단위 적중률은 얼마나 많은 바이틀가 인터넷으로 나가지 않았는지 보여줌

바이트 단위 적중률의 개선은 대역폭 절약을 최적화

7.5.4 적중과 부적중의 구별

HTTP는 클라이언트에게 응답이 캐시 적중이었는지 아니면 원 서버 접근인지 말해줄 수 있는 방법을 제공하지 않음

Date헤더를 이용하여 캐시된 것인지 확인 가능

7.6 캐시 토폴로지

캐시는 한 명의 사용자에게만 할당될 수도 있고 반대로 수천 명의 사용자들 간에 공유될 수 있음

7.6.1 개인 전용 캐시

작고 저렴

웹 브라우저는 개인 전용 캐시 내장

7.6.2 공용 프락시 캐시

프락시 캐시는 로컬 캐시에서 문서를 제공하거나, 혹은 사용자의 입장에서 서버에 접근

자주 찾는 객체를 단 한 번만 가져와 모든 요청에 대해 공유된 사본을 제공함으로써 네트워크 트래픽을 줄임

프락시 캐시는 프락시를 위한 규칙을 따름

7.6.3 프락시 캐시 계층들

작은 캐시에서 캐시 부적중이 발생했을 때 더 큰 부모 캐시가 그 트래픽을 처라하도록 하는 계층을 만드는 방식이 합리적인 경우 많음

클라이언트 주위에는 작고 저렴한 캐시를 사용하고, 계층 상단에는 많은 사용자들에 의해 공유되는 문서를 유지하기 위해 더 크고 강력한 캐시 사용

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

몇몇 네트워크 아키텍처는 단순한 캐시 계층 대신 복잡한 캐시망을 만든다.

캐시 커뮤니케이션 결정을 동적으로 내림

캐시망 안에서의 콘텐츠 라우팅을 위해 설계된 캐시들의 일

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

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

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

7.7 캐시 처리 단계

웹 캐시의 기본적인 동작은 대개 단순

  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: 신선도 검사

HTTP는 캐시가 일정 기간 동안 서버 문서의 사본을 보유할 수 있도록 해준다.

7.7.5 단계 5: 응답 생성

캐시는 클라이언트에 맞게 이 헤더를 조정해야 하는 책임

DATE 헤더 조정하면 안 됨

7.7.6 단계 6: 전송

7.7.7 단계 7: 로깅

대부분의 캐시는 로그 파일과 캐시 사용에 대한 통계를 유지

통계 캐시 적중과 부적중 횟수에 대한 통계를 갱신하고 로그 파일에 요청 종류, URL 그리고 무엇이 일어났는지를 알려주는 항목 추가

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

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 는 최대 나이 정의

Expires는 유효기간 명시

7.8.3 서버 재검사

캐시가 원 서버에게 문서가 변경되었는지의 여부를 물어봄

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

문서가 만료되었을 때 한번만 서버와 재검사

신선하지 않은 콘텐츠는 재공하지 않으면서도, 서버 트래픽을 절약하고 사용자 응답 시간을 개선

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

서버가 갖고 있는 문서가 캐시가 갖고 있는 것과 다른 경우에만 객체 본문을 보내달라고 하는 것

If-Modified-Since 와 If-None-Match

  • If-Modified-Since: - 주어진 날짜 이후로 수정되었다면 요청 메서드를 처리
  • If-None-Match: - 일련번호와 같이 동작하는 특별한 태그 제공/ 캐시된 테그가 서버에 있는 문서의 태그와 다를 때만 요청 처리

7.8.5 If-Modified-Since(IMS): 날짜 재검사

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

  • 만약 문서가 주어진 날짜 이후에 변경되었다면, GET 요청 성공 -> 새 문서가, 새로운 만료 날짜와 그 외 다른 정보들이 담긴 헤더들과 함께 캐시에게 반환

  • 만약 문서가 주어진 날짜 이후에 변경되지 않았다면 -> 304 Not Modified 응답

    효율을 위해 본문은 보내지 않음

    새 만료 날짜 보내줌

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

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

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

  • 어떤 문서는 일정 시간 간격으로 다시 쓰여지지만 실제로는 같은 데이터(내용 변화 X, 변경시각 바뀜)
  • 어떤 문서들의 변경은 전 세계의 캐시들이 그 데이터를 다시 읽어들기이겐 사소한 것(ex. 주석)
  • 어떤 서버들은 그들이 갖고 있는 페이지에 대한 최근 변경 일시를 정확하게 판별 불가능
  • 1초의 정밀도가 충분하지 않은 경우

캐시는 원 서버에게 태그가 요청과 다른 경우에만 새 객체를 달라고 요청하는 방법

여러 개의 엔티티 태그 포함 가능

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

엔티티 태그와 최근 변경일시 둘 다 사용 가능

콘첸츠가 조금 변경되었더라도 “그 정도면 같은 것”이라고 서버가 주장할 수 있도록 해주는 약한 검사기 지원

강한 검사기는 콘텐츠가 바뀔 때마다 바뀐다.

서버는 “W/” 접두사로 약한 겁사기 구분

강한 엔티티 태그는 대응하는 엔터티 값이 어떻게 바뀌든 매번 반드시 같이 바뀌어야 한다.

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

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

만약 서버가 엔터티 태그를 반환했다면, 반드시 엔터티 태그 검사기를 사용해야 한다.

모두 사용 가능하다면 두 가지의 재검사 정책을 모두 사용해야 한다.

7.9 캐시 제어

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

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

객체를 캐시하는 것을 제한하거나 캐시된 객체를 제공하는 여러 가지 방법을 제공

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

‘no-store’가 표시된 응답은 캐시가 그 응답의 사본을 만드는 것을 금지한다.

‘no-cache’로 표시된 응답은 사실 로컬 캐시 저장소에 저장될 수 있다.

다만 먼저 서버와 재검사를 하지 않고서는 캐시에서 클라이언트로 제공될 수 없을 뿐이다.

7.9.2 Max-Age 응답 헤더

max-age 헤더는 신선하다고 간주되었던 문서가 서버로부터 온 이후로 흐른 시간이고, 초로 나타낸다.

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

7.9.3 Expires 응답 헤더

초 단위의 시간 대신 실제 만료 날짜를 명시

몇몇 허버는 문서를 항상 만료되도록 하기 위해 Expires: 0 응답 헤더를 돌려보내지만, 이는 문법 위반이며 몇몇 소프트웨어와 문제를 일으킬 수 있다.

7.9.4 Must-Revalidate 응답 헤더

만약 캐시가 만료 정보를 엄격하게 따르길 원한다면, 원 서버는 다음과 같은 Cache-Control을 붙일 수 있다.

이 객채의 신선하지 않은 사본을 원 서버와의 최초의 재검사 없이는 제공해서는 안 됨을 의미

7.9.5 휴리스틱 만료

만약 응답이 max-age 헤더나 Expires 해더 중 어느 것도 포함하지 않고 있다면, 캐시는 경험적인 방법으로 최대 나이를 계산할 것이다.

유명항 휴리스틱 알고리즘의 하나인 LM 알고리즘은 문서가 최근 변경 일시를 포함하고 있다면 사용 가능

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

7.9.6 클라이언트 신선도 제약

클라이언트는 문서를 최신으로 유지할 필요가 있는 애플리키ㅔ이션을 위해 Cache-Control 헤더를 사용해 만료를 더 엄격하게 할 수 있다.

7.9.7 주의할 점

퍼블리셔가 잘못해서 유효기간을 까마득한 미래로 설정할 수도 있음

7.10 캐시 제어 설정

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

7.10.1 아파치로 HTTP 헤더 제어하기

디폴트로는 가능하지 않게 되어 있어서 사요앟려면 일단 활성화시킬 필요가 있다.

mod_headers

개별 헤더들을 설정할 수 있게 해줌

1
2
3
<Files *.html>
	Header set Cache-Control no-cache
</Files>

ex. html파일을 캐시 안 되게함

mod_expires

Expires 헤더를 자동으로 생성하는 프로그램 로직 제공

이 모듈은 문서에 마지막으로 접근한 날 혹은 수정한 날 이후의 일정 시한으로 유효기간을 설정할 수 있게 해줌

mod_cern_meta

HTTP 헤더들의 파일을 특정 객체와 연결시켜줌

7.10.2 HTTP-EQUIV를 통한 HTML 캐시 제어

HTTP 서버 응답 헤더는 문서의 만료와 캐시 제어 정보를 돌려주기 위해 사용

웹 서버는 제공할 문서에 올바른 캐시 제어 헤더들을 부여하기 위해 설정 파일들과 상호작용함

HTML 2.0은 저자가 웹 서버 설정 파일과의 상호작용 없이도 쉽게 HTML 문서에 HTTP 헤더 정보를 부여할 수 있도록 하기 위해 태그 정의

불행히도 이 기능을 지원하는 웹 서버나 프락시는 거의 없다.

참조

  1. HTTP 완벽 가이드
This post is licensed under CC BY 4.0 by the author.