HTTP 완벽가이드 7장 캐시

어겐어갠·2022년 5월 25일
0

7장 캐시

캐시는 자주 쓰이는 문서의 사본을 자동으로 저장하는 http 장치이다.

  • 불필요한 전송을 줄여서 비용을 줄인다.
  • 네트워크 병목을 줄인다.
  • 원 서버에 대한 요청을 줄인다.
  • 거리로 인한 지연을 줄인다.

7.1 불필요한 데이터 전송

서버는 똑같은 데이터 전송을 계속해서 보내면서 대역폭을 잡아먹고, 전송을 느리게만들며, 웹 서버에 부하를 준다.
캐시를 사용하면 첫 번째 서버 응답은 캐시에 보관되고, 그 이후 사본들이 응답으로 사용되어 트래픽 낭비를 줄인다.

7.2 대역폭 병목

원격 서버보다 로컬 네트워크 클라이언트가 더 넓은 대역폭을 가진다.
가까운 거리의 서버에 캐시가 저장된다면 넓은 대역폭의 환경에서 통신할 수 있다.

7.3 갑작스런 요청 쇄도

캐싱은 갑작스런 요청 쇄도에 대처하는데 매우 중요하다.

7.4 거리로 인한 지연

빛 역시 속도를 가지므로 대역폭을 제외하더라도 거리가 문제가 도리 수 있다.
캐시는 이러한 문제를 해결할 수 있다.

7.5 적중과 부적중

캐시는 위와 같은 장점이 있으나, 모든 문서의 사본을 저장하지는 않는다.
요청이 도착했을 때, 대응하는 사본이 있으면 그를 이용해 요청이 처리될 수 있고 이를 캐시 적중이라고 한다.

7.5.1 재검사

캐시는 사본이 최신인지 점검한다 = http 재검사
캐시는 원한다면 언제든 재검사 할 수 있으나, 보통 사본이 검사를 할 필요가 있을 정도로 오래되었을 때 재검사를 한다.
캐시가 서버에 재검사 요청을 보냈을 때
: 만약 변경되지 않았다면 = 304 Not Modified 응답을 보낸다 = 재검사 적중(느린 적중)

재검사 적중
만약 서버 객체가 변경되지 않았다면, 서버는 클라이언트에게 작은 HTTP 304 Not Modified 응답을 보낸다.

재검사 부적중
만약 서버 객체가 캐시된 사본과 다르다면 HTTP 200 OK 응답을 보낸다

객체 삭제
만약 서버 객체가 삭제되었다면, 404 Not Found 응답을 보내고, 캐시는 사본을 삭제한다.

7.5.2 적중률

적중률이 높을수록 캐시의 활용도가 높은 것.
대충 40%면 괜찮은 편이다.

7.5.3 바이트 적중률

문서들이 모두 같은 크기임은 아니다.
크기가 작은 문서 10개의 적중보다 매우 큰 문서 1개의 적중이 트래픽일 높일 수 있다.
이것이 몇몇은 바이트 단위 적중률 측정값을 선호하는 이유이다.
문서 적중률을 개선하면 전체 대기 시간이 줄어들고 바이트 단위 적중률의 개선은 대역폭 절약을 최적화한다.

7.5.4 적중과 부저중의 구별

http는 클라이언트에게 응답이 캐시 적중이엇는지 아닌지 제공하지 않는다.
응답이 캐시에서 왔는지 알아내는 방법 중 하나는 Date 헤더를 이용해 응답의 생성일을 비교해보면 된다.

7.6 캐시 토폴로지

개인 전용 캐시 = 한 명에게만 할당된 캐시(익스플로러의 '임시 파일')
공용 캐시 = 공유된 캐시

7.6.3 프락시 캐시 계층들

캐시를 계층화시켜서 적중되지 않을 경우 계층을 올라가면서 확인하는 것.

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

몇몇 네트워크 아키텍처는 복잡한 캐시망을 만든다.
캐시망 안의 콘텐츠 라우팅을 위해 설계된 캐시들은

  • (URL 근거로)부모 캐시와 원 서버 중 하나를 동적으로 선택한다.
  • (URL 근거로)특정 부모 캐시를 동적으로 선택한다.
  • 캐시된 사본을 로컬에서 찾아본다
  • 캐시들이 캐시된 콘텐츠에 부분적 접근을 허용한다.(트랜짓은 금지)

7.7 캐시 처리 단계

  1. 요청 받기
  2. 파싱
  3. 검색
  4. 신선도 검사
  5. 응답 생성
  6. 발송
  7. 로깅

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

7.8.1 문서 만료

http는 Cash-Contrl과 Expires 헤더를 이용해 원 서버가 각 문서에 유효기간을 붙일 수 있게한다.
캐시된 문서가 만료되면 캐시는 서버와 문서에 변경된 것이 있는지 검사해야한다. 변경되었다면 신선한 사본을 얻어와야 한다.

7.8.2 유효기간과 나이

  • Cash-Control:max-age
    : 문서의 최대 나이를 정한다.
  • Expires
    : 절대 유효기간을 명시한다.

7.8.3 서버 재검사

캐시된 문서가 만료됬다는 것이 원 문서와 달라졌다는 것을 의미하는 것은 아니다.
다만, 검사할 시간이 되었을을의미한다.
서버 재검사를

  • 변경되었다면 새 사본을 가져오고, 클라이언테에게도 보내준다.
  • 변경되지 않았다면, 새 만료일을 포함한 새 헤더만 가져와서 갱신한다.

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

http의 조건무 메서드는 재검사를 효율적으로 만들어준다.
서버에게 조건부 GET 요청을 보내면 웹 서버는 참인 경우에만 객체를 반환한다.

  • If-Modified-Since : < date >
    : 만약 문서가 주어진 날짜 이후로 수정되었다면 요청 메서드를 처리한다.
  • If-None-Match: < tags >
    : 문서의 일련번호(ETage)를 비교하고 태그가 다를때만 요청을 처리한다.

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

흔히 IMS 요청으로 불린다

  • 만약 주어진 날짜 이후에 변경되었다면, IMS = true 이고, GET 요청은 성공한다(새 문서를 보내준다).
  • 주어진 날짜 이후에 변경되지 않았다면, IMS = false 이고, 304 Not Modified 응답을 한다. + 문서에 갱신이 필요한 정보들(주로 새 만료 날짜 등)을 보내준다.

If-Modified-Sinse 헤더는 (서버 응답 헤더의) Last-Modified 헤더와 함께 동작한다.

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

최근 변경 일시 재검사가 비 효율적인 상황 4가지 이다.

  • 어떤 문서는 갱신되었지만, 내용이 완전히 동일할 수 있다.
  • 변경이 다소 사소한 경우(철자, 주석 변경 등)
  • 어떤 서버들은 페이지의 최근 변경 이시를 정확하게 판별할 수 없다.
  • 1초보다 적은 간격으로 갱신되는 문서들에 대해서는, 1초의 정밀도는 충분히지 않다.

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

캐시는 가지고 있는 버전이 서버가 갖고 있는 것에 대해 최신인지 확인하기 위해 엔터티 태그를 사용한다.
IMS 는 약한 검사기이고 (다소의 변경은 묵인)
INM(ETag 비교) 는 강한 검사기 이다.
강한검사기에 'W/'을 붙여 약한 검사기처럼 동작시킬 수 있다.

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

만약 서버가 엔터티 태그를 반환했다면, 반드시 엔터티 태그 검사기를 사용해야 한다.
만약 서버가 Last-Modifid 값만을 반환했다면, 클라이언트는 If-Modifided-Since 검사를 사용할 수 있다.

7.9 캐시 제어

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

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

캐시가 검증되지 않은 캐시된 객체로 응답하는 것을 막는다.
no-store : 캐시가 그 응답의 사본을 만드는 것을 금지한다.
no-cache : 로컬 캐시 저장소에 저장될 수 있다. 다만 먼저 서버와 재검사를 해야한다.

7.9.2 Max-Age 응답 헤더

캐시의 나이를 정의한다.

7.9.3 Expires 응답 헤더

실제 만료 날짜를 명시한다.

7.9.4 Must-Revalidate 응답 헤더

캐시는 성능을 개선하기 위해 만료된 객체를 제공하도록 설정할 수 있다.
이것이 싫다면
Cache-Control: must-revalidate 를 사용하여 반드시 신선한 사본을 제공하도록 해야한다.

7.9.5 휴리스틱 만료

응답에 캐시의 나이나 만료에 관련된 헤더가 없을 경우,
캐시는 경험적인 방법으로 최대 나이를 계산하는데, 계산 결과 얻은 최대 나이값이 24시간보다 크다면, Heuristic Expiration 경고 헤더가 응답 헤더에 추가되어야 한다.

LM인자 알고리즘
: 마지막 변경이 오래되었을 수록 -> 앞으로도 변경이 일어나지 않을 확률이 높다.

7.9.6 클라이언트 신선도 제약

웹브라우저는 프락시 캐시의 신선하지 않은 콘텐츠를 강제로 갱신시켜주는 버튼을 가지고 있다.
이 버튼은 Cache-Control 요청 헤더가 추가된 GET 요청을 발생시켜 강제로 재검사하거나 콘텐츠를 무조건 가져온다.

7.9.7 주의할 점

문서 만료는 완벽한 시스템이 아니다.

7.10 캐시 제어 설정

웹 서버들은 만료 http 헤더들을 설정하는 서로 다른 메커니즘을 제공한다.

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

웹 서버는 http 캐시 제어 헤더를 설정할 수 있는 여러 가지 메커니즘을 제공한다.

  • mod_headers
    : 개별 헤더들을 설정할 수 있게 해준다.
  • mod_expires
    : 적절한 만료 날짜가 담긴 Expires 헤더를 자동으로 생성하는 프로그램 로직을 제공한다.
  • mod_cern_meta
    : http 헤더들의 파일을 특정 객체와 연결시켜준다.

7.10 자세한 알고리즘

7.11.1 나이와 신선도 수명

캐시된 문서가 제공하기에 충분히 신선한지 알려주려면 캐시는 캐시된 사본의 나이와 신선도 수명만 계산하면 된다.
나이가 신선도 수명보다 적으면 신선한 문서이다.

7.11.2 나이 계산

캐시에서 온 응답의 나이를 알아내는 것은 어려운데, 왜냐하면 모든 서버가 동기화된 시계를 갖고 있지는 않으며, 응답이 어디에서 왔는지도 모르기 때문이다.

  • 겉보기 나이는 Date 헤더에 기반한다
    :그러나 모든 시계가 잘 동기화되진 않아, 정확하지 않을 수 있다.
    만약 나이가 음수가 되는 일이 있다면 0으로 만들어야한다.
  • 점층적 나이 계산
  • 네트워크 지연에 대한 보상
    : 네트워크에 지연이 걸렸을 때, 나이 계산이 더 힘들어진다.

7.11.3 완전한 나이 계산 알고리즘

$나이 = $문서가 우리의 캐시에 도착했을 때의 나이 + $사본이 얼마나 오래 우리의 캐시에 있었는지

7.11.4 신선도 수명 계산

신선도 수명은 클라이언트의 제약조건에 의존한다.
캐시는 사용자를 위해 봉사하므로, 그들의 요구에 출실히 따라야 한다.

7.11.5 완전한 서버 신선도 알고리즘

p.222

7.12 캐시와 광고

7.12.1 광고 회사의 딜레마

캐시는 원 서버가 실제 접근 횟수를 알 수 없게 숨길 수 있다.
이는 접근 횟수를 알아야하는 광고 회사에게는 딜레마가 된다.

7.12.2 퍼블리셔의 응답

광고회사들은 캐시가 광고 시청 수를 가로채지 못하도록 모든 종류의 '캐시 무력화' 기법을 사용한다.
이는 트랜잭션을 느리게 만든다.

7.12.3 로그 마이그레이션

이상적인 해결책은 서버로 요청이 가지 않도록 하는 것이다. 캐시는 모든 적중의 로그를 유지할 수 있다.
다만, 적중 로그는 그 크기 때문에 옮기기 ㅓ렵다.

7.12.4 적중 측정과 사용량 제한

캐시 적중 횟수를 정기적으로 서버에 돌려주는 Meter 헤더를 추가하면 적중 횟수를 측정할 수 있다.

profile
음그래

0개의 댓글