[HTTP 완벽 가이드] 7장 캐시

Milk717·2022년 10월 2일
0

HTTP

목록 보기
5/7

2022년 7월 ~ 2022년 8월 동안 http 완벽 가이드 스터디를 진행하면서 노션에 정리해놨던 내용입니다.

💡 캐시는 불필요한 데이터 전송을 줄임.
캐시는 네트워크 병목을 줄여서 대역폭을 늘리지 않고도 데이터를 빠르게 전송할 수 있다.
캐시는 원 서버에 대한 요청을 줄여 서버 부하를 줄이고 더 빨리 응답할 수 있다.
캐시는 거리로 인한 지연을 줄여준다.

7.1 불필요한 데이터 전송

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

7.2 대역폭 병목

캐시는 네트워크 병목을 줄여준다. 많은 네트워크가 원격 서버보다 로컬 네트워크 클라이언트에 더 넓은 대역폭을 제공하기 때문에 클라이언트가 빠른 LAN에 있는 캐시로부터 사본을 가져온다면 성능을 개선할 수 있다.

7.3 갑작스런 요청 쇄도

캐싱을 사용하면 갑작스런 요청 쇄도에 대처하기 좋다.

7.4 거리로 인한 지연

모든 네트워크 라우터는 인터넷 트래픽을 지연시키고, 라우터를 많이 거치지 않더라도 빛의 속도로 인한 지연이 생길 수 있다. 캐싱을 사용하면 클라이언트와 서버 사이의 거리를 줄여 지연을 줄일 수 있다.

7.5 적중과 부적중

  • 캐시 적중 ⇒ 캐시에 요청이 도착했을 때 그에 대응하는 사본이 있다면 캐시를 이용해 요청이 처리됨
  • 캐시 부적중 ⇒ 캐시에 대응하는 사본이 없어 원 서버로 전달됨.

7.5.1 재검사

  • HTTP 재검사 ⇒ 원 서버 콘텐츠가 변경될 수 있기 때문에, 캐시는 사본이 최신 상태인지 서버를 통해 점검해야 한다.

재검사 적중

  • 서버객체 변경 x → 서버가 클라이언트에게 작은 http 304 Not modified 응답을 보냄.

재검사 부적중

  • 서버 객체가 캐시된 사본이랑 다름 → 서버가 클라이언트에게 콘텐츠 전체와 http 200 ok 응답을 보냄

객체 삭제

  • 서버 객체가 삭제됨 → 404 Not Found 응답을 돌려보내고, 캐시는 사본을 삭제함.

7.5.2 적중률

  • 0 ~ 1 or 퍼센트로 표현
  • 모든 요청중에 캐시 적중으로 가져온 문서의 퍼센트를 나타내는 것.

7.5.2 바이트 적중률

  • 문서의 사이즈까지 고려해서 바이트 단위로 캐시 적중률을 계산

7.5.4 적중과 부적중의 구별

클라이언트는 응답이 캐시 적중이었는지 원 서버 접근이었는지 구별할 수 없음.

Date 헤더를 이용해 응답의 date와 현재 date를 배교하여, 응답의 생성일이 더 오래된 것이라면 캐싱된 것이라고 알 수 있음.

응답이 얼마나 오래되었는지 알려주는 Age 헤더를 사용하기도함.

7.6 캐시 토폴로지

  • 개인 전용 캐시 ⇒ 한 명에게만 할당된 캐시
  • 공용 캐시 ⇒ 공유된 캐시

7.6.1 개인 전용 캐시

  • 많은 저장공간을 필요로 하지 않음.
  • 저렴함.
  • 대부분의 브라우저는 개인 전용 캐시를 내장하고 있음.

7.6.2 공용 프락시 캐시

로컬 캐시에서 문서를 제공하거나, 사용자 입장에서 서버에 접근한다.

7.6.3 프락시 캐시 계층들

작은 캐시에서 캐시 부적중이 발생 → 부모 캐시가 걸러 남겨진 트래픽을 처리함.

캐시 계층이 깊어지면 요청이 캐시의 긴 연쇄를 따라가서 성능 저하가 발생함.

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

  • URL에 근거하여, 부모 캐시와 원 서버중 하나를 동적으로 선택
  • URL에 근거하여 특정 부모 캐시를 동적으로 선택
  • 부모 캐시에 가기 전에, 캐시된 사본을 로컬에서 찾아본다.
  • 다른 캐시들이 캐시된 콘텐츠에 부분적으로 접근하도록 허용하되, 인터넷 트랜짓(트래픽이 다른 네트워크로 건너가는 것)은 허용하지 않는다.

7.7 캐시 처리 단계

  1. 요청 받기 ⇒ 캐시는 네트워크로부터 도착한 요청 메시지를 읽는다.
  2. 파싱 ⇒ 캐시는 메시지를 파싱하여 URL과 헤더들을 추출한다.
    1. 헤더 부분을 조작하기 쉬운 자료 구조에 담는다.
  3. 검색 ⇒ 캐시는 로컬 복사본이 있는지 검사하고, 사본이 없다면 사본을 받아와 로컬에 저장
  4. 신선도 검사 ⇒ 캐시된 사본이 충분히 신선한지 검사하고, 신선하지 않다면 변경사항이 있는지 서버에게 물어봄
  5. 응답 생성 ⇒ 새로운 헤더와 캐시된 본문으로 응답 메시지를 만든다.
    1. 캐시는 Date 헤더를 조정하면 안됨.
  6. 발송 ⇒ 응답을 클라이언트에게 돌려줌
  7. 로깅 ⇒ 선택적으로 로그파일에 트랙잭션에 대해 서술한 로그 하나를 남긴다.

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

  • 문서만료, 서버 재검사 ⇒ HTTP는 어떤 캐시가 사본을 갖고 있는지 서버가 기억하지 않더라고, 캐시된 사본이 서버와 일치하도록 유지할 수 있게 해주는 매커니즘을 갖고 있다.

7.8.1 문서 만료

  • Cache-Control, Expires 헤더 ⇒ 원 서버가 각 문서에 유효기간을 붙일 수 있게 해줌.
  • 캐시된 문서가 만료되면 캐시는 반드시 서버와 문서에 변경된 것이 있는지 검사해야 하고, 변경되었다면 새 유효기간과 함께 신선한 사본을 얻어와야 한다

7.8.2 유효기간과 나이

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

7.8.3 서버 재검사

  • 캐시 문서 만료 ≠ 사본이 신선하지 않다.
  • 캐시 문서가 만료되었다는 것은 검사할 시간이 되었다는 것이다. 이 때 하는 검사를 서버 재검사 라고 한다.

서버 재검사

  • 콘텐츠가 변경됨
    • 새로운 사본을 가져와 오래된 데이터 대신 저장한 뒤 클라이언트에게도 보내줌
  • 콘텐츠가 변경되지 않음.
    • 새 만료일을 포함한 새로운 헤더들만 가져와 캐시 안의 헤더를 갱신한다.

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

  • HTTP는 조건부 GET 이라는 요청을 보낼 수 있도록 해줌.
  • GET 메시지에 조건부 헤더를 추가해서 조건이 참인 경우에만 객체를 반환한다.

캐시 재검사에 사용되는 조건부 헤더

  • If-Modified-Sincs: ⇒ 날짜 재검사
    • 만약 문서가 주어진 날짜 이후로 수정됨
      • 조건은 참이 되고 일반적인 GET 메소드로 동작함.
    • 문서가 주어진 날짜 이후에 변경되지 않음.
      • 조건은 거짓이고 서버는 작은 304 Not Modified 응답 메시지를 클라이언트에게 돌려줌.
      • 효율을 위해 본문은 보내지 않는다.
  • If-None-Match: ⇒ 엔터티 태그 재검사
    • 최근 변경 일시 재검사가 어려운 경우
      - 어떤 문서는 일정 시간 간격으로 다시 쓰여지지만 실제로는 같은 데이터를 포함하고 있다. 즉, 내용 변화는 없더라도 변경시각은 바뀔 수 있음.
      - 어떤 문서들의 변경은 전 세계의 캐시들이 그 데이터를 다시 읽어들이기엔 사소한 것일 수도 있다. (예: 철자, 주석 변경)
      - 서버들이 그들이 갖고 있는 페이지에 대한 최근 변경 일시를 정확하게 판별할 수 없음.
      - 1초보다 작은 시간 간격으로 갱신되는 문서를 제공하는 서버들에게는, 변경일에 대한 1초의 정밀도는 충분하지 않을 수 있다.

      만약 캐시가 엔터티 태그 v2.6인 문서를 갖고 있을 때, 캐시는 원 서버에게 태그가 v.2.6이 아닌 경우에만 새 객체를 달라고 요청하는 방법으로 유효한지 여부를 검사한다.

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

  • 강한 검사기
    • 콘텐츠가 바뀔 때 마다 엔터티 태그를 변경한다.
  • 약한 검사기
    • 어느정도 콘텐츠 변경은 허용하지만 콘텐츠의 중요한 의미가 변경되면 함께 변경된다.

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

  • 서버가 엔터티 태그를 반환 ⇒ 반드시 엔터티 태그 검사기를 사용해야 한다.
  • 서버가 Last-Modified 값만 반환 ⇒ 클라이언트는 If-Modified-Since 검사를 사용.
  • 둘 다 사용 가능하다면 두 가지 재검사 정책을 모두 사용해야한다.

7.9 캐시 제어

  • 케시 제어 우선순위
    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 응답 헤더

  • 캐시가 그 응답의 사본을 만드는 것을 금지한다.
  • 클라이언트에게 no-store 응답을 전달하고 나면 객체를 삭제한다.
💡 재검사 없이 캐시에서 제공하지 마라

7.9.2 Max-Age 응답 헤더

신선하다고 간주되었던 문서가 서버로부터 온 이후로 흐은 시간, 초로 나타냄

7.9.3 Expires 응답 헤더

  • 실제 만료 날짜를 정확하게 명시함.
  • 사용을 권장하지 않음.

7.9.4 Must-Revalidate 응답 헤더

캐시는 성능을 위해서 신선하지 않은 객체를 클라이언트에게 제공할 수도 있는데 이 응답 헤더를 사용한다면 캐시가 만료 정보를 엄격하게 따르게 된다.

7.9.5 휴리스틱 만료

응답이 캐시 관련 헤더를 어느 것도 포함하지 않는다면 경험적인 방법으로 최대 나이를 계산한다.

LM 인자 알고리즘

  • 문서가 최근 변경 일시를 포함하고 있다면 사용할 수 있다.
  • 만약 캐시된 문서가 변경지 상당히 오래되었다면 그것은 아마 안정적인 문서일 것이고, 갑자기 바뀔 가능성이 낮기 때문에 캐시에 더 오래 보관하고 있어도 안전하다고 판단한다.
  • 만약 캐시된 문서가 최근에 변경되었다면 그것은 아마 자주 변경될 것이고, 따라서 짧은 기간 동안만 캐시해야 한다고 판단한다.

7.9.6 클라이언트 신선도 제약

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

0개의 댓글