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

[2부 7장] 캐시 #7

Open
qkrqudcks7 opened this issue Aug 25, 2022 · 0 comments
Open

[2부 7장] 캐시 #7

qkrqudcks7 opened this issue Aug 25, 2022 · 0 comments

Comments

@qkrqudcks7
Copy link

qkrqudcks7 commented Aug 25, 2022

7. 캐시

웹 캐시란?

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

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

7.1 불필요한 데이터 전송

  • 여러 클라이언트들이 페이지에 접근하면서 드는 중복된 바이트들은 네트워크 대역폭을 잡아먹고 웹 서버에 부하를 준다.
  • 캐시를 이용하면, 첫 번째 응답을 캐시에 보관하여 다음에 오는 요청을에 대한 응답으로 사용하여 트래픽 낭비를 줄일 수 있다.

7.2 대역폭 병목

  • 캐시는 네트워크 병목을 줄여준다.
  • 만약 클라이언트가 빠른 LAN에 있는 캐시로부터 사본을 가져온다면, 캐싱은 성능을 대폭 개선할 수 있다.

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

  • 캐싱은 갑작스런 사건으로 인해 트래픽이 몰릴 때 대처하기 위해 특히 중요하다.

7.4 거리로 인한 지연

  • 대역폭이 문제가 되지 않더라도, 거리가 문제 될 수 있다.
  • 모든 네트워크 라우터는 제각각 인터넷 트래픽을 지연시킨다.
  • 클라이언트와 서버 사이에 라우터가 많지 않더라도, 빛의 속도 그 자체가 유의미한 지연을 유발한다.

7.5 적중과 부적중

  • 캐시의 용량 때문에 모든 문서의 사본을 저장할 수 없다.
  • 캐시에 요청이 도착했을 때, 그에 대응하는 사본이 있다면 그것을 이용해 요청을 처리하는 것을 캐시 적중
  • 대응할 사본이 없어서 그냥 원 서버로 전달되는 것을 캐시 부적중

7.5.1 재검사 (Revalidation)

image

  • 서버의 콘텐츠가 변경될 수 있기 때문에 캐시는 사본이 최신인지 서버를 통해 점검해야한다(HTTP 재검사)
  • 캐시는 캐시된 사본의 재검사가 필요할 때 원 서버에 작은 재검사 요청을 보낸다.
  • 변경이 안 됐다면, 서버는 아주 작은 304 Not Modified 응답을 보낸다. (재검사 적중)
  • HTTP는 캐시된 객체를 재확인하기 위한 도구중에서 가장 많이 쓰이는 것은 If-Modified-Since 헤더이다.
  • 서버에게 보내는 GET 요청에 이 헤더를 추가하면 캐시된 시간 이후에 변경된 경우에만 사본을 보내달라는 의미가 된다.

GET If-Modified-Sice 요청이 서버에 도착했을 때 세 가지 상황

재검사 적중

image

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

재검사 부적중

  • 서버 객체가 캐시된 사본과 다르다면, 서버는 콘텐츠 전체와 함께 HTTP 200 OK 응답을 클라이언트에게 보낸다.

객체 삭제

  • 서버 객체가 삭제되었다면, 서버는 404 Not Fount 응답을 돌려보내며, 캐시는 사본을 삭제한다.

7.5.2 적중률

  • 캐시가 요청을 처리하는 비율을 캐시 적중률, 혹은 문서 적중률이라고 부른다.
  • 적중률 0% : 캐시 부적중이라 네트워크 너머로 문서를 가져와야 함
  • 적중률 100% : 캐시 적중으로 캐시에서 사본을 가져온다.
  • 웹 캐시 적중률로 40%면 괜찮은 편이다.

7.5.3 바이트 적중률

  • 문서들이 모두 같은 크기인 것은 아니기 때문에 문서 적중률이 모든 것을 말해주지는 않는다.
  • 몇몇 큰 객체는 덜 접근되지만, 그 크기 때문에 전체 트래픽에는 더 크게 기여한다.
  • 바이트 단위 적중률은 캐시를 통해 제공된 모든 바이트의 비율을 표현한다.
  • 바이트 단위 적중률 100% : 모든 바이트가 캐시에서 왔다. 어떤 트래픽도 발생하지 않았다.
  • 문서 단위 적중률: 얼마나 많은 웹 트랜잭션을 외부로 내보내지 않았는가, 개선 시 지연시간 줄어듦.
  • 바이트 단위 적중률: 얼마나 많은 바이트가 인터넷으로 나가지 않았는가, 개선 시 대역폭 절약을 최적화함.

7.5.4 적중과 부적중의 구별

image

현재시간: 2022-08-27 19:30:00, date 헤더는 9:28:08 이므로 캐시된 것.

  • 클라이언트가 응답이 캐시에서 왔는지 알아내는 한가지 방법은 date 헤더를 이용하는 것이다.
  • date 헤더 값과 현재 시각을 비교해서 응답의 생성일이 더 오래되었다면 응답이 캐시된 것임을 알 수 있다.

7.6 캐시 토폴로지

  • 캐시는 한명의 사용자에게만 할당될 수 있고, 반대로 수천명의 사용자들 간에 공유될 수도 있다.
  • 한 명에게만 할당된 캐시를 개인 전용 캐시라고 하고, 공유된 캐시는 공용 캐시라고 한다

7.6.1 개인 전용 캐시

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

크롬은 URL + :cache 이라고 입력하면, 해당 페이지에서 캐시 콘텐츠의 목록을 볼 수 있다.

image

7.6.2 공용 프락시 캐시

  • 캐시 프락시 서버 혹은 더 흔히 프락시 캐시라고 불리는 특별한 종류의 공유된 프락시 서버이다.
  • 프락시 캐시는 로컬 캐시에 문서를 제공하거나, 사용자의 입장에서 서버에 접근한다.
  • 여러 사용자가 접근하기 때문에. 불필요한 트래픽을 줄일 수 있는 더 많은 기회가 있다.

7.6.3 프락시 캐시 계층들

image

  • 작은 캐시에서 캐시 부적중이 발생했을때 더 큰 부모 캐시가 걸러 남겨진 트래픽을 처리하도록 하는 계층을 만드는 방식이 합리적인 경우가 많다.
  • 캐시 계층이 깊다면 요청은 캐시의 긴 연쇄를 따라간다. 프락시 연쇄가 깊어지면 각 중간 프락시는 현저한 성능 저하가 발생한다.
  • 실제로 네트워크 아키텍처들은 2~3개 프락시만 거치도록 스스로 제한한다.

7.7 캐시 처리 단계

image

7.7.1 요청 받기

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

7.7.2 파싱

  • 캐시는 요청 메세지를 여러 부분으로 파싱하여 헤더 부분을 조작하기 쉬운 자료 구조에 담는다.

7.7.3 검색

  • 캐시는 URL 알아내고, 이미 로컬 사본이 존재하는지 검사한다.
  • 캐시된 객체는 서버 응답 본문과 원 서버 응답 헤더를 포함하고 있으므로 캐시적중 동안 올바른 서버 헤더가 반환될 수 있다.

7.7.4 신선도 검사

  • HTTP는 캐시가 일정 기간 동안 서버 문서의 사본을 보유할 수 있도록 해준다.
  • 이 기간 동안 문서는 신선한 것으로 간주되고, 캐시는 서버와의 접촉 없이 이 문서를 제공할 수 있다.
  • 캐시사본을 신선도 한계를 넘을 정도로 오래 갖고 있다면, 신선하지 않은 것, 캐시는 어떤 변경이 있는지를 검사하기 위해 서버와 재검사를 해야 한다.

7.7.5 응답 생성

  • 캐시된 응답을 원 서버에서 온 것처럼 보이게 하고 싶기 때문에, 캐시된 서버 응답 헤더를 토대로 응답 헤더를 생성한다.
  • 캐시는 클라이언트에 맞게 이 헤더를 조정해야 하는 책임이 있다.

ex) HTTP/1.1 응답을 기대하는 상황에 HTTP/1.0 응답을 반환했다면, 캐시는 그에 맞게 헤더를 번역해야 한다.

7.7.6 전송

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

7.7.7 로깅

  • 대부분의 캐시는 로그 파일과 캐시 사용에 대한 통계를 유지한다.
  • 각 캐시 트랜잭션이 완료된 후, 통계 캐시 적중과 부적중 등에 관한 통계를 갱신한다.

7.7.8 캐시 처리 플로 차트

image

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

  • 캐시된 데이터는 서버의 데이터와 일치하도록 관리되어야 한다.
  • HTTP는 어떤 캐시가 사본을 갖고 있는지 기억 안 해도 캐시된 사본이 서버와 일치하도록 유지할 수 있게 해주는 단순한 매커니즘을 가지고 있다. ( 문서 만료 , 서버 재검사 )

7.8.1 문서 만료

image

  • HTTP에서는 Cache-ControlExpires 라는 헤더들을 이용해서 원 서버가 문서에 유효기간을 붙일 수 있게 해준다.

7.8.2 유효기간과 나이

image

7.8.3 서버 재검사

  • 캐시가 원 서버에게 문서가 변경되었는지의 여부를 물어볼 필요가 있음을 의미하는 것을 서버 재검사라 부른다.
    • 컨텐츠가 변경되었다면? 그 문서의 새로운 사본을 가져와서 오래된 데이터를 저장한 뒤 클라이언트에게도 보내준다.
    • 변경되지 않았다면? 새 만료일을 포함한 새 헤더만 가져와서 헤더를 갱신한다.
  • 문서의 신선도를 매 요청마다 검증할 필요가 없다. 문서가 만료되었을 때 한 번만 서버와 재검사를 하면 된다.

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

  • HTTP는 캐시가 서버에게 조건부 GET 이라는 요청을 보낼 수 있도록 해준다.
  • 서버에 있는 문서가 캐시의 문서와 다른 경우에만 객체 본문을 보내달라고 하는 것이다.
  • 이렇게 신선도 검사와 객체를 받아오는 것을 하나의 조건부 GET으로 처리할 수 있다.
  • If-Modified-SinceIf-None-Match 조건부 헤더를 사용할 수 있다.

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

  • 만약 문서가 주어진 날짜 이후에 변경되었다면, true가 되고 GET 요청이 평범하게 성공한다.
  • 새 문서가 새로운 만료 날짜와 그 외 다른 정보들이 담긴 헤더들과 함께 캐시에 반환된다.
  • 만약 문서가 주어진 날짜 이후에 변경되지 않았다면, false가 되고 304 Not Modified 응답 메세지를 돌려준다.
  • 효율을 위해 본문은 보내지 않는다.

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

이런 상황에서 쓰여요

  • 어떤 문서는 일정 시간 간격으로 쓰여지지만 실제로 같은 데이터를 포함하는 경우 (즉, 내용은 아무런 변화가 없는데 변경시각이 주기적으로 업데이트 되는 경우)
  • 문서의 변경된 데이터를 다시 읽기에 사소한 것일 경우 (철자 수정이나 주석 수정인 경우)
  • 어떤 서버에서는 최근 변경 일시를 정확하게 판별할 수 없을 수도 있다.
  • 1초보다 작은 간격으로 갱신되는 문서를 제공하는 서버들에게
     
  • if-None-Match는 문서를 변경할때 새로운 버전으로 엔터티 태그를 변경할 수 있다.
  • 따라서 서버에서 유효한 변경이 있을시에만 엔터티 태그를 변경하여, 각 클라이언트의 캐시를 업데이트하도록 유도할 수 있다.

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

  • 엔터티 태그와 최근 변경일시는 둘 다 캐시 검사기다.

  • 서버는 캐시된 사본을 무효화시키지 않고 문서를 살짝 고칠 수 있도록 허용하고 싶은 경우가 있다.

  • 이때 위 조건들에 "W/"가 붙어있으면 약한 검사기가 되어서 어느정도의 컨텐츠 변경을 허용한다.
    image

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

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

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

7.9 캐시 제어

  • HTTP는 문서가 만료되기 전까지 얼마나 오랫동안 캐시될 수 있게 할 것인지 서버에서 설정할 수 있다.
    • Cache-Control: no-store
    • Cache-Control: no-cache
    • Cache-Control: must-revalidate
    • Cache-Control: max-age
    • Expires: 날짜 헤더
    • 아무 만료 정보 주지 않고, 캐시 스스로 결정할 수 있게 한다.

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

  • HTTP/1.1은 신선도를 관리하기 위해, 객체를 캐시하는 것을 제한하거나 캐시된 객체를 제공하는 여러 가지 방법을 제공한다.
  • no-cacheno-store 헤더는 캐시가 검증되지 않은 캐시된 객체로 응답하는 것을 막는다.

image

  • no-store는 캐시가 서버응답의 사본을 만드는 것을 막는다.
  • no-cache는 먼저 서버와 재검사를 하지 않고서는 캐시에서 클라이언트로 제공할 수 없는 것이다.

7.9.2 Max-Age 응답 헤더

  • Cache-Control: max-age는 신선하다고 간주되었던 문서가 서버로부터 받은 이후로 흐른 시간이고, 초로 나타낸다.
  • Cache-Control: s-maxage 헤더는 똑같지만 공용 캐시에만 적용된다.
  • 값을 0으로 설정하면 캐시가 매 접근마다 문서를 캐시하거나 리프레시하지 않도록 요청할 수 있다.

7.9.3 Expires 응답 헤더

  • deprecated 되었다.
  • 초 단위의 시간 대신에 실제 절대 만료 날짜를 명시한다.
  • 많은 서버가 부정확한 시계를 갖고 있어서 없어졌다.

7.9.4 Must-Revalidate 응답 헤더

  • 캐시는 성능을 개선하기 위해 신선하지 않은(만료된) 객체를 제공하도록 설정할 수 있다.
  • Cache-control: must-revalidate 헤더는 신선하지 않은 사본을 서버와의 재검사 없이는 제공해서는 안 됨을 의미한다.
  • 신선도 검사 시도했을 때 서버가 사용할 수 없는 상태면 504 Gatewat Timeout을 반환해야한다.

7.9.5 휴리스틱 만료

image

  • 응답이 max-age 헤더나 Expires 헤더 중 어느 것도 포함하지 않고 있다면, 경험적인 방법(heuristic)으로 최대 나이를 계산한다.
  • LM인자 알고리즘은 캐시가 서버와 대화했을 때와 서버가 문서의 최근 변경 일시를 말했을 때의 시간차를 계산한다.
  • 일반적으로 휴리스틱 신선도 유지기간의 상한을 1주일로 설정한다.

7.9.6 클라이언트 신서도 제약

  • 웹 브라우저는 신선하지 않은 캐시 컨텐츠를 강제로 갱신시켜주는 강한 새로고침이있다.
  • Cache-control 요청 헤더가 추가된 GET 요청을 발생시켜, 강제로 재검사하거나 서버로부터 콘텐츠를 무조건 가져온다.
  • 클라이언트는 이 요청 헤더를 사용하여 만료 제약을 엄격하게 하거나 느슨하게 할 수 있다.

7.10 캐시 제어 설정

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

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

mod_headers

모든 HTML 파일을 캐시되지 않도록 설정하는 예시
image

  • 이 모듈은 개별 헤더들을 설정할 수 있게 해준다.
  • 개별 HTTP 헤더를 설정할 수 있는 지시어를 이용하여 아파치 설정 파일에 설정을 추가할 수 있다.

mod_expires

image

  • 이 모듈은 적절한 만료 날짜가 담긴 Expires 헤더를 자동으로 생성하는 프로그램 로직을 제공한다.
  • 문서에 마지막으로 접근한 날 혹은 수정한 날 이후의 일정 시한으로 유효기간을 설정할 수 있게 해준다.

mod_cem_meta

  • 이 모듈은 HTTP 헤더들의 파일을 특정 객체와 연결시켜준다.
  • 제어하고자 하는 파일에 각각 대응되는 메타파일들을 생성하게 되므로, 각 메타 파일에 원하는 헤더를 추가하면 된다.

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

  • 웹 서버 설정 파일과의 상호작용 없이도 쉽게 HTML 문서에 HTTP 헤더 정보를 부여할 수 있게 하기 위한 것.
  • HTML 문서를 캐시하지 않도록 설정하는 HTML 2.0 태그

image

  • 원래 웹 서버에서 사용되도록 의도한 것인데, 이 기능을 지원하는 웹 서버나 프락시는 거의 없다.
  • 그 이유는 이 기능은 서버의 부하를 가중시키고, 설정값이 정적이고, HTML을 제외한 다른 타입은 지원하지 않기 때문이다.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant