Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[7장] 캐시 #8

Open
eunbc opened this issue Nov 29, 2023 · 7 comments
Open

[7장] 캐시 #8

eunbc opened this issue Nov 29, 2023 · 7 comments
Labels

Comments

@eunbc
Copy link

eunbc commented Nov 29, 2023

No description provided.

@eunbc eunbc added the 3주차 label Nov 29, 2023
@eunbc
Copy link
Author

eunbc commented Nov 29, 2023

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

캐시를 왜 사용하는가?

  1. 불필요한 데이터 전송

    1. 캐시를 사용하면, 같은 문서에 대한 요청을 캐시에서 가져올 수 있기 때문에 서버에서 중복으로 트래픽을 주고받는 낭비를 줄일 수 있음
  2. 대역폭 병목

    1. 많은 네트워크가 원격 서버보다 로컬 네트워크 클라이언트에 더 넓은 대역폭을 제공한다
    2. 클라이언트가 빠른 LAN 에 있는 캐시로부터 사본을 가져온다면, 성능을 대폭 개선할 수 있다
  3. 갑작스런 요청 쇄도

    1. 갑작스런 사건(뉴스 속보, 유명 인사와 관련된 사건)으로 인해 많은 사람이 동시에 웹 문서에 접근하면 트래픽이 급증하게 된다. 캐싱은 이런 갑작스런 요청 쇄도에 대처하기 위해 중요하다
  4. 거리로 인한 지연

    1. 대역폭이 문제가 되지 않더라도, 빛의 속도 그 자체가 유의미한 지연을 유발한다

  5. 적중과 부적중

    1. cache hit : 캐시에 요청이 도착했을 때, 그에 대응하는 사본이 있다면 요청이 처리됨
    2. cache miss : 대응하는 사본이 없다면 원 서버로 요청이 전달됨
    3. 재검사
      1. 원 서버 콘텐츠는 변경될 수 있기 때문에, 캐시는 사본이 여전히 최신 상태인지 서버를 통해 때때로 점검해야 한다.
      2. If-Modified-Since 헤더 : 서버에게 보내는 GET 요청에 이 헤더를 추가하여 캐시된 시간 이후에 변경된 경우에만 사본을 보내달라는 의미
        1. 서버 객체가 변경되지 않았다면, 304 Not Modified 응답을 보냄
        2. 서버 객체가 변경되었다면 콘텐츠 전체와 함께 200 OK 로 응답
        3. 서버 객체가 삭제되었다면 404 Not Found, 캐시에서는 사본 삭제
    4. 적중률
      1. 적중률 - 캐시가 요청을 처리하는 비율, 40%면 괜찮은 편
      2. 바이트 적중률 - 캐시를 통해 제공된 바이트의 비율로 계산
  6. 캐시 토폴로지

    1. 개인 전용 캐시 : ex. 웹 브라우저
    2. 공용 캐시 : ex. 공용 프락시 캐시, 계층화하기도 함
  7. 캐시 처리 단계

스크린샷 2023-11-29 오전 9 47 13

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

    1. 문서 만료의 유효기간을 나타내는 헤더
      1. Cache-Control : max-age = 484200
      2. Expires : Fri, 05 Jul 2002, 05:00:00 GMT → 절대 유효기간
    2. 서버 재검사
      1. If-Modified-Since : 원 서버에서 제공하는 응답 헤더의 Last-Modified와 캐시된 사본이 마지막으로 수정된 날짜가 담긴 If-Modified-Since 헤더를 비교하여 재검사
      2. If-None-Match : 서버 사본에 유의미한 변경이 일어났는지 확인하기 위해 문서의 엔티티 태그가 새로운 버전인지 확인 ( If-None-Match : “v2.6”)
      3. HTTP/1.1 클라이언트는 만약 서버가 엔터티 태그를 반환했다면 엔티티 태그 검사기를 사용해야 하고, 서버가 Last-Modified 값만을 반환했다면 If-Modified-Since 검사를 사용함
  2. 캐시 제어

    1. Cache-Control: no-store → 캐시가 응답의 사본을 만드는 것을 금지
    2. Cache-Control: no-cache → 캐시에는 저장되나 서버와 재검사 반드시 필요
    3. Cache-Control: must-revalidate → 신선하지 않다면 원서버와의 재검사 필요
    4. Cache-Control: max-age → 문서가 서버로부터 온 이후로 흐른 시간
    5. Expires → 만료 날짜 명시
    6. 휴리스틱 만료 → max-age나 Expires 중 어느 것도 포함하지 않는다면, 경험적인(휴리스틱) 방법으로 최대 나이 계산, 유명한 알고리즘으로는 LM 인자 알고리즘이 있음
  3. 캐시 제어 설정

    1. 아파치로 HTTP 헤더 제어하기
    2. HTTP-EQUIV를 통한 HTML 캐시 제어
  4. 자세한 알고리즘

    1. 캐시된 사본의 나이와 신선도 수명을 비교하기 위한 알고리즘
    2. 캐시된 사본의 나이 = 요청/응답 네트워크 지연 + 서버 처리 시간 + 캐시에 체류한 시간
  5. 캐시와 광고

    1. 캐싱이 완벽하게 동작한다면 원서버는 HTTP 접근을 전혀 수신하지 않는다는 의미이기도 하므로, 광고를 통해 이익을 얻는 콘텐츠 제공자는 딜레마에 빠짐
    2. 캐시가 광고 시청 수를 가로채지 못하도록 캐시 무력화 기법을 사용함
    3. 서버로 요청이 가지 않게 하되, 로그로 적중을 측정하기도 함

    구글 글로벌 캐시

출처 - 나무위키

배경

YouTube의 성장으로 인해 각국의 트래픽이 Google 데이터 센터로 쏠리는 상황이 발생하였고, 각국의 통신사가 확보한 해외망에 대한 가용량을 상당히 잡아먹는 요인이 되었다. 그로 인해 전세계 YouTube 이용자들이 버퍼링 문제를 하소연하였고 Google은 이에 대한 해결책을 마련하였다.

바로 각국의 통신사마다 캐시 서버를 설치하는 것이였다. Google은 각국의 통신사들이 사용하는 해외망을 구축하는데에 상당한 기여를 하였고, 각국의 통신사들이 사용하는 해외망 중 상당 부분은 Google이 직접 구축하고 소유하고 있는 자산이기도 하다. 게다가 YouTube를 통해 전세계의 트래픽을 독점하고 있는 Google의 요청을 통신사들이 거절하기 매우 어려웠다. 이러한 배경으로 인해 GGC의 확산은 상당히 빠르게 진행되었고 2017년을 기준으로 전세계 모든 통신사들이 자사 백본망에 GGC를 갖고 있다고 봐도 무방하다.

국내의 경우에는 해외망이 부족했던 LG U+가 2012년부터 국내 통신3사 중에서 가장 먼저 GGC를 설치했다. 그 뒤로 2013년에 SK텔레콤과 SK브로드밴드가 GGC를 도입했다. KT는 캐시서버에 돈을 들이는 데에 인색했던 나머지 2014년까지 자사의 막대한 해외망으로 버텼는데, 종종 KT의 해외망 속도가 개판오분전이 되는 상황이 발생하거나 해외망 점검할 때마다 KT 이용자들이 YouTube 동영상에 대한 버퍼링 문제에 빡치게 만들곤 했다. 2015년, KT는 기가 인터넷과 기가 와이파이를 상용화하면서 끝내 GGC를 도입하게 되었고, 더이상 예전처럼 해외망으로 장난질치지 않게되자 GGC에 저장되지 않은 YouTube 동영상들은 해외망의 규모가 열약한 LG U+나 대한민국 계열 통신사에 비해서 버퍼링없이 매끄럽게 재생되었다.

GGC 초창기에는 YouTube 영상을 임시 저장하고 해당 통신사의 고객에게 버퍼링이 없는 빠른 속도로 스트리밍을 하는 것이 목표였다. 그러나 지금은 GGC의 용도가 확장되어 Google Play, Gmail, Google 드라이브, Google 포토 등 Google의 다른 서비스를 제공하는 데에도 쓰이고 있다.

동작 원리

스크린샷 2023-11-29 오전 11 38 59

이용자가 유튜브 동영상을 감상할 때에 해당 통신사의 GGC에서 미리 캐싱해 둔 동영상이 존재한다면 구글 데이터 센터가 아닌 통신사에서 직접 동영상을 스트리밍 받는다. 이때 핑이 한자릿수대가 나오며 스트리밍 속도가 상당히 높게나오는데, 기가 인터넷 사용자의 경우에는 대체적으로 120 ~ 200 Mbps의 스트리밍 속도가 나온다.

통신사의 GGC에 이용자가 보고자 하는 동영상이 캐싱되어 있지 않다면, 구글 데이터 센터에서 직접 스트리밍을 받는다. 이때는 해외망을 많이 확보한 통신사의 회선에서 상당히 유리하다. 당장에 해외망의 규모가 열약한 LG U+나 SK그룹 계열사만 하더라도 GGC에 없는 유튜브 동영상을 재생하는 경우에 가끔씩 버퍼링이 걸리기도 하고 해외망 상태가 메롱인 경우에는 노답인 경우가 많다. 그러나 KT의 경우에는 GGC에 없는 동영상도 자사의 막대한 해외망이 뒷받침되기에 버퍼링이 없이 재생이 된다.

그러고 나서 해당 GGC에서는 캐싱되어 있지 않은 동영상을 구글 데이터 센터로부터 다운받아서 캐싱한다. 다음 이용자는 해당 GGC에서 스트리밍을 받게된다.

국내 이용자들이 덜 찾게되는 영상들은 GGC에 저장되어도 단기간 내에 지워지게 되며, 조회수가 장기적으로 꾸준히 나오는 동영상들이 GGC에 계속 남을 가능성이 높다.

한편, 유튜브 라이브 방송도 GGC를 이용한다. 다만, 방송하는 쪽에서는 싱가포르[1]등 해외의 구글 데이터 센터로 영상을 보게 된다. 유튜브 라이브 방송의 렉이나 버퍼링의 근원이 방송하는 사람 쪽에 있는 경우가 많다. 방송자가 해외망을 통해 영상을 보내야하니 핑이 만만치않게 오르게 되고 핑튐도 생길 수 있으며 이로인해 방송 상태가 엉망인 경우가 발생하게 되는 것이다. 딜레이 줄이려면 방송인은 '대시보드 → 스트림 옵션 → 매우 짧은 지연 시간' 변경하거나, 시청자는 '재생 속도' 빠르게 재생하면 지연시간이 줄어든다.

구글 플레이 스토어도 GGC를 이용한다. 국내 이용자들이 자주 다운받는 앱들을 GGC에 캐싱시켜서 빠른 속도의 다운로드를 제공한다.

@annahxxl
Copy link

서버 캐싱 vs HTTP 캐싱

서버 캐싱 HTTP 캐싱
목적 서버 부하 감소, 응답 속도 향상 페이지 로딩 시간 감소, 반복적인 네트워크 요청 감서
대상 API 응답, 데이터베이스 쿼리 결과, 계산된 데이터 등 정적 콘텐츠
관리 개발자에 의해 관리되며, 일정 시간 동안 유효하거나 특정 조건하에 갱신 브라우저에 의해 자동 관리되며, HTTP 헤더를 통해 제어

HTTP 캐싱 vs CDN(AWS CloudFront)

HTTP 캐싱 CDN
정의 주로 웹 브라우저에서 이루어지는 캐싱 프로세스 Content Delivery Network, 전 세계적으로 분산된 서버 ❗️네트워크❗️
방식 정적 콘텐츠를 로컬에 저장하여 재방문 시 빠르게 로드 정적 콘텐츠를 전 세계에 분산된 서버에 복제하여 사용자와 가장 가까운 서버에서 응답
목적 페이지 로딩 시간 감소, 반복적인 네트워크 요청 감소 전 세계적 콘텐츠 배포 최적화, 사용자에게 빠른 콘텐츠 제공

→ 완전 관리형인 CloudFront 서비스는 캐싱 및 콘텐츠 전달에 이미 최적화 되어있다고 하는데, 자세한 내용은 아래 문서에서 확인하면 될 듯 하다

Optimizing caching and availability - Amazon CloudFront

캐시 처리 단계

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

주요 헤더

유효기간과 나이

  • Cache-Control: max-age
    • 문서의 최대 나이
  • Expires (deprecated)
    • 절대 유효기간

조건부 메서드와의 재검사

  • If-Modified-Since:
    • 서버는 문서가 주어진 날짜 이후로 수정되었다면 요청 메서드 처리
  • If-None-Match:
    • 서버는 캐시된 태그가 서버에 있는 문서의 태그와 다를때만 요청을 처리

캐시 제어

  • Cache-Control: no-store
    • 캐시가 그 응답의 사본을 만드는 것을 금지
  • Cache-Control: no-cache
    • 로컬 캐시 저장소에 저장 가능, 다만 먼저 서버와 재검사를 하지 않고서는 클라이언트로 제공될 수 없음
  • Pragma: no-cahce
    • HTTP/1.0+와의 하위호환성을 위한 헤더

참고

IMG_9722 중간

HTTP Cache Headers - A Complete Guide - KeyCDN

@park0jae
Copy link
Member

park0jae commented Nov 29, 2023

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

캐시를 사용하는 이유


  • 불필요한 데이터 전송을 줄임 → 네트워크 요금으로 인한 비용 절감
  • 네트워크 병목을 줄임 → 대역폭 안늘려도 페이지 로딩 빠름
  • 원 서버에 대한 요청 줄임 → 부하 줄이고 응답이 빠름
  • 거리로 인한 지연 줄임

적중과 부적중


캐시에 요청 도착 -> 사본 있으면 사본으로 요청 처리 (캐시 적중 : cache fit)
캐시에 요청 도착 -> 사본 없으면 원서버로 전달 (캐시 부적중 : cache miss)

재검사 (Revalidation)


  • 원 서버의 콘텐츠 변경 가능성 존재 → 캐시는 사본의 최신화를 항상 점검함 (’신선도 검사’)
  • 성공적인 재검사 → 캐시 부적중보다 빠름
  • 실패한 재검사 → 캐시 부적중과 거의 동일
  • 재검사 시 If-Modified-Since 헤더 사용
  • 서버 객체가 캐시된 사본과 다름 → 서버는 콘텐츠 전체와 함께 200 OK 응답을 전달
  • 서버 객체가 삭제됨 → 서버는 404 Not Found 응답을 돌려보내고, 캐시 사본을 삭제

적중률


  • 캐시가 요청을 처리하는 비율 ( = 문서 적중률 )
  • 0 ~ 1 사이 값 or 퍼센트라고 부름
  • 0%는 모든 요청이 네트워크 너머로 문서를 가져오는 경우 ( = 캐시 부적중 )
  • 100%는 모든 요청이 캐시에서 사본을 가져오는 경우 ( = 캐시 적중 )

바이트 적중률


  • 바이트 단위 적중률 → 캐시를 통해 제공된 모든 바이트의 비율
  • 100%는 모든 바이트가 캐시에서 왔고 어떤 트래픽도 인터넷으로 나가지 않았음을 의미
  • 40%면 괜찮은 편이라고 함

적중과 부적중의 구별


  • 클라이언트는 캐시 적중 or 원 서버 접근을 구별할 수 없음 ( = 200 OK 응답만 받기 때문에 )
  • 응답의 Date 헤더나 Age 헤더를 통해 응답이 캐시 or 서버로부터 온 것인지 구별 가능

캐시 토폴로지


  1. 개인 전용 캐시 (private cache)
    • 한명에게 할당
    • 작고 저렴하며 웹 브라우저에 내장
  2. 공용 프락시 캐시 (public cache)
    • 수천 명의 사용자들 간 공유된 캐시
    • 캐시 프락시 서버 or 프락시 캐시라고도 불림
  3. 프락시 캐시 계층들
    • 작은 캐시에서 캐시 부적중 → 큰 부모 캐시가 그것을 이어받도록 하는 구조 (= 합리적)
    • 계층이 깊다면, 요청은 캐시의 긴 연쇄를 따라가고 프락시 연쇄가 깊어질 수록 중간 프락시는 성능 저하

캐시 처리 단계


HTTP GET 요청일 때, 웹 캐시는 다음 단계들을 거쳐 처리될 것이다.

1. 요청 받기

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

2. 파싱

  • 메시지를 파싱하여 URL과 헤더들을 추출

3. 검색

  • URL에 해당하는 로컬 사본이 있는지 검사
  • 없으면 사본을 받아와 로컬에 저장

4. 신선도 검사

  • 사본의 유효기간(신선한 기간)을 체크
  • 신선도 기간이 지났을 경우 문서 변경을 서버와 재검사

5. 응답 생성

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

6. 발송

  • 네트워크를 통해 응답을 클라이언트에게 반환

7. 로깅 (선택)

  • 각 캐시 트랜잭션이 완료된 후, 캐시는 캐시 적중과 부적중 횟수 통계를 내고 요청 종류, URL 등 정보를 로깅할 수 있음

[ 캐시 처리 플로차트 ]

image

사본을 신선하게 유지하기


  • 캐시된 사본 / 서버의 문서 → 항상 일치할 수 없음
  • 따라서 캐시된 데이터와 서버의 데이터가 일치하도록 관리되어야 함

1. 문서 만료

  • HTTP는 Cache-Control과 Expires라는 헤더를 이용해 원 서버가 각 문서에 유효기간을 붙일 수 있음
  • 캐시 문서가 만료되기 전, 캐시가 필요하다면 서버와 접촉 없이 사본을 제공할 수 있음
  • 캐시된 문서가 만료되면, 반드시 서버와 문서에 변경점을 검사하고 사본을 얻어와야 함( 새 유효기간과 함께 )

[ Expires ]

Expires: Fri, 05 Jul 2002, 05:00:00 GMT

[ Cache-Control ]

Cache-Control: max-age=484200

2. 유효기간과 나이의 차이

  • Expires와 Cache-Control:max-age 헤더는 기본적으로 같은 일을 수행
  • Cache-control:max-age
    • max-age 값은 문서의 최대 나이를 정의 (단위는 초)
    • 제공하기 더 이상 신선하지 않다고 간주되는 시간 - 문서가 처음 생성된 시간 → 경과 시간 최대값
    • 즉, 신선한 문서가 서버로부터 온 이후로 흐른 시간이고 초로 나타냄
    • ex) Cache-Control:max-age=48200
  • Expires
    • 절대 유효기간을 명시한다.
    • 유효기간 경과 → 더 이상 문서가 신선하지 않음을 의미
    • Deprecated 되었다고 한다.
    • ex) Expires: fri, 05 jul 2002, 05:00:00 GMT

3. 서버 재검사

  • 캐시 문서 만료 → 다시 검사할 시간이 되었다는 뜻
  • 재검사 결과 콘텐츠 변경 → 그 문서의 새로운 사본을 가져와 저장하고, 클라이언트에게 반환
  • 재검사 결과 콘텐츠 변경 X → 새 만료일을 포함한 새 헤더들만 가져와 캐시 안의 헤더들을 갱신

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

  • 보통 문서를 가져오려고 하는 GET와 같은 safe 메서드들의 경우, 오직 연관되어 있는 경우에 조건부 요청이 회신하는데 사용될 수 있으므로 대역폭을 아끼게 됩니다.
  • 보통 문서를 업로드하는 PUT와 같은 unsafe 메서드들의 경우, 그 요청의 원본 문서가 서버에 저장되어 있는 것과 동일한 경우에만 조건부 요청이 문서 업로드에 사용될 수 있습니다.
  • If-Modified-Since:
    • 문서가 주어진 날짜 이후로 수정되었다면 요청 메서드를 처리
    • Last Modified 헤더와 함께 동작
    • 서버 문서 변경 → 원 서버는 새 문서를 준다.
    • 서버 문서 변경 X → 304 Not Modified 응답
  • If-None-Match:
    • 캐시된 문서와 서버에 있는 문서의 ETag 비교를 통해 처리
    • ETag(entity tag)는 웹 서버가 주어진 URL의 콘텐츠가 변경되었는지 알려주고 이를 반환하는 HTTP 응답 헤더이다.
    • ETag가 변경 → 200 OK 와 함께 새 콘텐츠를 새 ETag와 함께 반환
    • 요청 : If-None-Match : “v2.6”
    • 응답 : 304 Not Modified, ETag : “v2.6”
그럼 언제 ETag를 사용하고 언제 Last-Modified 일시를 사용할까 ?

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

[ ETag를 사용하지 않은 API vs 사용한 API ]

image
  • no-etag의 재요청 : 768B → 796B
  • etag의 재요청 : 820B → 145B
  • ETag를 사용하면, 같은 요청에 대해 변경된 리소스가 없다면 304 상태 코드와 ETag를 header에 담아 보내줄 뿐 요청에 대한 리소스를 또 보내지 않는다.

캐시 제어


: 문서가 만료되기 전까지 얼마나 오랫동안 캐시될 수 있게 할 것인지 ? HTTP는 이를 위한 여러 방법을 제시

no-cache , no-store 응답 헤더

  • no-cache : 재검사 없이는 캐시에서 클라이언트에게 사본을 제공하지 마라 (HTTP/1.1 이상)
  • no-store : 캐시가 응답의 사본을 만드는 것을 금지

Must-Revalidate 응답 헤더

  • 만약 캐시가 만료 정보를 엄격하게 따르길 원하면 다음과 같이 붙인다.
  • Cache-Control: must-revalidate
  • 캐시가 객체의 신선하지 않은 사본을 원 서버와 최초의 재검사 없이는 제공해서는 안됨을 의미
  • 그렇다면, no-cache와 다른점은 ?
    • Must-Revalidate 헤더는 캐시 사본이 신선한 경우 원 서버와 재검사 없이 바로 객체 반환 가능
    • no-cache의 경우 매번 원 서버와 재검사를 해야함
  • no-store 상태
    • must-revalidate 이며, max-age = 0인 경우와 동일하다고 볼 수 있음

광고와 캐시와의 관계


  • 광고는 사용자가 광고를 볼 때마다 수익이 나는 구조이다.

  • 그런데 캐시가 광고를 캐싱하여 원 서버의 광고화면 HTTP 요청을 먹어버리면, 수익이 안나는걸까?

    1. 캐시가 광고 시청 수를 가로채지 못하도록 모든 종류의 캐시 무력화 기법을 사용한다

    2. 매 접근마다 광고 URL을 고쳐씀으로써 원 서버로 요청이 가게한다

→ 이는 결국 광고를 위해 캐싱의 긍정적인 효과를 감소시키는 부작용을 불러온다 !

@byulcode
Copy link

캐시

HTTP 캐시란?

자주 쓰이는 문서의 사본을 자동으로 보관하는 HTTP 장치다. 웹 요청이 캐시에 도달했을 때, 캐시된 로컬 사본이 존재할 경우 그 문서는 원 서버가 아니라 그 캐시로부터 제공된다.

장점

  • 불필요한 데이터 전송을 줄여줌
  • 네트워크 병목을 줄여줌
  • 원 서버에 대한 요청을 줄여줌
  • 거리로 인한 지연을 줄여준다

적중과 부적중

  • 적중(cache hit) : 캐시에 요청이 도착했을 때, 요청에 대응하는 사본으로 요청을 처리
  • 부적중(cache miss) : 요청에 대응하는 사본이 없어 원 서버로 전달되는 것

캐시 토폴로지

  • 개인 전용 캐시 (private cache) : ex. 웹 브라우저 내장 캐시
  • 공용 캐시(public cache) : ex. 프락시 서버

캐시 처리 단계

  1. 요청
  2. 파싱 - URL과 헤더 추출
  3. 검색 - 로컬 사본이 없다면 사본을 받아온 후 로컬에 저장
  4. 신선도 검사 - 신선하지 않다면 변경사항이 있는지 서버에 확인
  5. 응답 생성
  6. 발송
  7. 로깅 - 선택적

사본을 신선하게 유지하기

: 캐시된 사본이 서버와 충분히 일치하도록 유지할 수 있게 해주는 메커니즘

유효기간과 나이

  • Cache-Control: max-age : 문서의 최대 나이
  • Expires : 절대 유효기간

조건부 메서드와 재검사

: 서버가 갖고 있는 문서가 캐시가 갖고 있는 것과 다른 경우에만 객체 본문을 보내달라고 하는 조건부 GET 요청을 보내는 것

  • If-Modified-Since: <date> : 문서가 주어진 날짜 이후로 수정되었다면 요청 메서드 처리
  • If-None-Match: <tags> : 캐시된 태그가 서버에 있는 문서의 태그와 다를 때만 요청을 처리

캐시 제어

  • Cache-Control : no-store : 캐시가 응답의 사본을 만드는 것을 금지
  • Cache-Control : no-cache : 로컬 캐시 저장소에 저장 가능. 하지만 서버와 재검사를 해야 클라이언트로 제공될 수 있음
  • Cache-Control : must-revalidate : 원 서버와의 최초의 재검사 없이 객체를 제공해서는 안 됨
  • Cache-Control : max-age : 서버로부터 온 이후로 흐른 시간을 초로 나타냄
  • 휴리스틱 만료 : 응답에 Cache-control: max-age 헤더나 Expires 헤더 중 어느 것도 포함하지 않고 있는 경우 경험적인 방법으로 최대 나이를 계산

@KarmaPol
Copy link
Member

캐시

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

캐시의 혜택

불필요한 데이터 전송

원 서버가 중복해서 다수의 클라이언트와 트래픽을 주고 받는 낭비를 줄일 수 있음

대역폭 병목

광역 대역폭의 특성 상 네트워크 속도 저하
-> 빠른 LAN에 있는 캐시로부터 사본을 가져오면, 성능 대폭 개선

갑작스런 요청 쇄도

갑작스러운 트래픽 증가에 의한 웹 서버 장애 방지 가능

거리로 인한 지연

빛의 속도 그 자체가 유의미한 지연 유발 (보스턴 - 샌프란시스코 1/4초 지연)
-> 근처 지역에 캐시를 설치하면 거리 지연 해결 가능

적중과 부적중

  • Cache Hit 캐시 적중
    캐시 요청에 대응하는 사본이 캐시에 있으면 적중
  • Cache Miss 캐시 부적중

재검사

  • 원 서버 콘텐츠는 변경될 수 있기 때문에 사본이 최신 버전인지 점검해야한다
    -> 이를 '신선도 검사'를 HTTP 재검사라고 한다
  • 캐시에 저장하는 사본의 개수는 매우 많기 때문에 사본이 검사할 정도로 충분히 오래되었을 때만 재검사를 진행한다
  • 재검사가 필요할때, 속도 = 캐시 히트 > 성공한 재검사 > 캐시 미스 = 실패한 재검사
  • 사본이 유효할 경우, 304 Not Modified 응답을 보낸다

적중률

캐시가 요청을 처리하는 비율, 0부터 1까지의 값
40% 정도면 괜찮다

바이트 적중률

모든 문서의 크기가 같지 않기 때문에 모든 바이트의 비율을 표기하기에 용이하다

적중과 부적중의 구별

HTTP 응답 코드 자체는 200 OK 로 동일하다
-> 응답 Date 헤더 값과 현재 시각을 비교하여 캐시된 값인지 알 수 있다

캐시 토폴로지

개인 전용 캐시

웹 브라우저 - 개인 전용 캐시 내장, 작고 저렴함

공용 프락시 캐시

특별한 종류의 프락시 서버

  • 로컬 캐시에서 문서를 제공하거나
  • 클라이언트 입장에서 서버에 접근
    => 불필요한 네트워크 트래픽을 줄일 수 있다

프락시 캐시 계층들

캐시를 계층으로 나누어

  • 클라이언트 주위에는 작고 저렴한 캐시
  • 서버 주위에는 비싸고 강력한 캐시

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

  • 네트워크 아키텍처에서 복잡한 캐시망 구성
    -> 요청을 원 서버로 보낼지 어떤 부모 캐시로 보낼지 동적으로 결정
  • 다른 캐시들 끼리 부분적인 접근만 허용,
    인터넷 트랜짓(트래픽이 다른 네트워크로 건너가는 것)은 허용 X
  • 서로 다른 조직들이 상호 이득을 위해 그들의 캐시를 연결하여(형제 캐시) 찾아볼 수 있게 해줌

캐시 처리 단계

1. 요청 받기

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

2. 파싱

요청 메시지를 헤더 부분을 조작하기 쉬운 자료 구조에 담는다

3. 검색

URL을 통해 로컬 사본이 있는지 검색한다
상황에 따라 원 서버나 부모 프락시에서 가져온다
얼마나 캐시에 머무르고 있었는지, 얼마나 자주 사용되는지 등 메타 데이터 포함

4. 신선도 검사

너무 오래 가지고 있었다면 원 서버에 재검사

5. 응답 생성

원 서버의 응답 헤더를 토대로 응답 헤더 생성
캐시 신선도 정보(Cache-Control, Age, Expires..)를 삽입하며,
프락시 캐시를 거쳤다는 걸 알려주고자 종종 Via 헤더 삽입
Date 헤더는 최초 생성일자를 나타내므로 조정하면 안된다

6. 전송

응답 헤더가 준비되면 클라이언트에 응답을 돌려준다

7. 로깅

로그 파일과 캐시 사요에 대한 통계 유지
캐시 히트, 미스에 대한 통계 갱신

사본을 신선하게 유지하기

문서 만료

HTTP는 Cache-Control, Expires라는 특별한 헤더들을 이용해서 각 문서에 유효기간 붙일 수 있다
만료되면 반드시 재검사

유효기간과 나이

  • HTTP/1.0+ Expires
  • HTTP/1.1 Cache-Control:max-age

서버 재검사

캐시된 사본 만료 시 재검사

  • 원본 변경 시, 새로운 사본을 갱신하고 클라이언트에 전송
  • 원본 변경 X, 새 헤더들만 가져와 캐시 헤더만 갱신

조건부 메서드와의 재검사

GET 요청 메시지에 특별한 조건부 헤더를 추가하여 재검사를 효율적으로 처리

  • If-Modified-Since 날짜 재검사
  • If-None-Match 엔티티 태그 재검사 - 대응하는 엔티티 변경 시 태그 갱신

캐시 제어

문서가 만료되기 전까지 얼마나 오랫동안 캐시될 수 있게 할 것인지 설정

no-cache와 no-store 응답 헤더

Cache-Control : no-store, no-cache 헤더는 검증되지 않은 캐시된 객체로 응답하는 것을 막는다

  • no-store 캐시가 응답의 사본을 만드는 것을 금지
  • no-cache 로컬 캐시 저장소에 저장 가능, 캐시에서 클라이언트 제공 시 반드시 재검사

Max-Age 응답 헤더

Cache-Control : max-age=3600
초 단위로 최대 age 지정

Expires 응답 헤더

Expires : Fri, 05, Jul 2002, 05:00:00 GMT
초 단위 시간 대신 실제 만료 날짜 명시

Must-Revalidate 응답 헤더

Cache-Control : must-revalidate
캐시 성능을 위해 만료된 객체도 제공할 수 있는데, 이때 만료 객체 제공을 근원적으로 방지한다

휴리스틱 만료

응답이 어떤 캐시 제어 헤더도 갖고 있지 않다면, 경험적인 방법으로 최대 나이를 계산

클라이언트 신선도 제약

Cache-Control 요청 헤더를 이용해 브라우저, 프락시 캐시 만료를 더 엄격하게 할 수 있음
(Cache-Control: max-stale, min-fresh, no-cache ..)

문서 만료 주의할 점

만약 유효기간을 까마득한 미래로 설정하면 어떤 변경도 캐시에 반영되지 않는다

캐시와 광고

캐시는 사용자를 도와 더 좋은 경험을 제공하고, 네트워크 사업자가 트래픽을 줄일 수 있게 해준다

광고 회사의 딜레마

캐싱이 완벽하게 동작하면 원 서버 HTTP 접근을 캐싱 서버가 모두 흡수한다
-> 접근 횟수에 따라 돈을 벌면 달갑지 않은 일이다

퍼블리셔의 응답

광고를 CGI 게이트웨이를 통해 제공해 캐시 무력화 -> 매 접근 마다 광고 URL을 고쳐 씀

  • 이상적으로는 캐시가 흡수하도록 내버려 두고 캐시 적중을 광고 회사에 알린다
    -> 모든 접근에 대해 원 서버와 재검사하도록 캐시 설정
    => 캐시와 동시에, 원 서버에서 적중도 확인, But 트래픽을 증가시킨다

로그 마이그레이션

캐시 적중 로그를 서버에 제공한다 -> 크기 때문에 옮기기 어ㄹ움

RFC 2227, Meter 헤더

특정 URL에 대한 캐시 적중 횟수를 정기적으로 서버에 돌려주는 Meter 헤더를 추가

@cloudwi
Copy link
Contributor

cloudwi commented Nov 29, 2023

7장 캐시

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

  • 캐시는 불필요한 데이터 전송을 줄여서, 네트워크 요금으로 인한 비용을 줄여준다.
  • 캐시는 네트워크 병목을 줄여준다. 대역폭을 늘리지 않고도 페이지를 빨리 불러 올 수있게 된다.
  • 캐시는 원 서버에 대한 요청을 줄여준다. 서버는 부하를 줄일 수 있으며 더 빨리 응답할 수 있게 된다.
  • 페이지를 먼 곳에서 불러올수록 시간이 많이 걸리는데, 캐시는 거리로 인한 지연을 줄여준다.

불필요한 데이터 전송

캐시를 이용하면, 첫 번쨰 서버 응답은 캐시에 보관된다. 캐시된 사본이 뒤이은 요청들에 대한 응답으로 사용 될 수 있기 때문에, 원 서버가 중복해서 트랙픽을 주고받는 낭비가 줄어들게 된다.

대역폭 병목

캐시는 네트워크 병목을 줄여준다.

클라이언트들이 서버에 접근할 때의 속도는, 그 경로에 있는 가장 느린 네트워크의 속도와 같다. 만약 클라이언트가 빠른 LAN에 있는 캐시로부터 사본을 가져온다면 성능을 대폭 개선 가능하다.

갑작스런 요청 쇄도

갑작스런 사건으로 인해 많은 사람이 거의 동시에 웹 문서에 접근할 때 이런 일이 발생한다.
이벤트와 프로모션등 푸시알림을 타고 들어오는 경우가 있었다.

거리로 인한 지연

모든 네트워크 라우터는 제각각 인터넷 트래픽을 지연시킨다.

그리고 클라이언트와 서버 사이에 라우터가 그다지 많지 않더라도, 빛의 속도 그 자체가 유의미한 지연을 유발한다.

적중과 부적중

재검사

캐시는 반드시 그들이 갖고 있는 사본이 여전히 최신인지 서버를 통해 때때로 점검해야 한다. 이러한 ‘신선도 검사’를 HTTP 재검사라고 부른다.

캐시는 캐시된 사본의 재검사가 필요할 때, 원 서버에 작은 재검사 요청을 보낸다. 콘텐츠가 변경되지 않았다면, 서버는 아주 작은 304 응답을 보낸다.

이를 재검사 적중 혹은 느린 적중이라고 부른다. 이것은 순수 캐시 적중보다 느린데, 원 서버와 검사를 할 필요가 있기 때문이다. 그러나 캐시 부적중보다는 빠른데, 서버로부터 객체 데이터를 받아올 필요가 없기 때문이다.

적중과 부적중의 구별

응답의 Date 헤더 값을 현재 시각과 비교하여, 응답의 생성일이 더 오래되었다면 클라이언트는 응답이 캐시된 것임을 알아낼 수 있다.

캐시 토폴로지

캐시 처리 단계

요청 받기

파싱

검색

신선도 검사

응답 생성

발송

로깅

사본을 신선하게 유지하기

문서 만료

Cache-Control과 Expires라는 헤더를 활용해서 원 서버가 각 문서에 유효기간을 붙일 수 있게 해준다.

서버 재검사

캐시된 문서가 만료되었다는 것은, 그 문서가 원 서버에 현재 존재하는 것과 실제로 다르다는 것을 의미하지는 않으며, 다만 이제 검사할 시간이 되었음을 뜻한다.

재검사 결과 콘텐츠가 변경되었다면, 캐시는 그 문서의 새로운 사본을 가져와 오래된 데이터 대신 저장한 뒤 클라이언트에게도 보내준다.

재검사 결과 콘텐츠가 변경되지 않았다면, 캐시는 새 만료일을 포함한 . 새헤더들만 가져와서 캐시 안의 헤더들을 갱신한다.

정리가 힘들다

https://toss.tech/article/smart-web-service-cache

@kimday0326
Copy link
Member

캐시가 필요한 이유

  1. 같은 데이터의 반복된 전송은 네트워크 지연을 발생시키고, 웹 서버에 부하를 준다.
  2. 많은 클라이언트가 동시에 같은 요청을 보내게 되면, 네트워크와 웹서버에 장애가 생길 수 있다.
  3. 절대적인 거리와 중간에 거쳐가는 수맣은 네트워크 라우터 때문에 지연이 발생할 수 있다.
  4. 따라서 캐시를 사용하여 위의 문제점들을 개선할 수 있다.

캐시 피어링

여러 프락시 서버들이 서로 협력하여 네트워크 트래픽을 효율적으로 관리하고 캐시된 콘텐츠를 공유하는 방식

형제(Sibling) 및 부모(Parent) 피어

'부모' 피어는 보다 상위 레벨에서 작동하며, 하위 '자식' 피어들에게 캐시 서비스를 제공한다. 책에서 말하는 계층별 접근이 대표적인 예시이다. '형제' 피어는 서로 동등한 관계에서 작동하며, 캐시된 데이터를 서로 공유한다.

HTTP가 형제 캐시를 지원하지 않는 이유

  • HTTP는 1:1 통신을 중심으로 설계되었으며, 캐시 피어링과 같은 복잡한 네트워크를 고려하지 않고 설계된 프로토콜이다.
  • 기본적으로 포함된 캐시 매커니즘(캐시 제어)는 단일 서버 측 캐시에 초점이 맞춰져있다.
  • 캐시 피어링은 상당한 복잡도를 요구하며, 프로토콜 보다는 네트워크 레벨에서 관리 및 구성이 필요하다.
  • HTTP에 형제 캐시와 같은 고급 캐시 매커니즘을 직접 지원하는 것은 프로토콜의 복잡성을 증가시키므로, 캐시 피어링을 위한 추가적인 프로토콜을 사용한다.

형제 피어에 접근하는 방식

  • 같은 로컬 네트워크에 위치한 경우 게이트웨이를 거치지 않고 통신
  • 게이트웨이를 통한 통신
    -> 질의를 통해 캐싱된 응답만을 받아오고 그 외의 통신은 허용하지 않음
  • VPN 또는 터널링
    -> 보안이 중요한 환경에서는 VPN이나 터널링 기술을 활용해 연결을 구축한다.
    -> 이 또한 결국엔 게이트웨이를 거치지만 연결 자체는 암호화 되어있다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

7 participants