캐시

바그다드·2023년 3월 11일
0

데이터를 미리 복사해 놓는 임시 장소

캐시가 없을 때

  1. 서버에 데이터 요청
  2. 서버는 해당 데이터를 HTTP 메세지로 전송
  3. 서버에 데이터를 재요쳥
  4. 서버는 다시 해당 데이터를 HTTP 메세지로 전송
  • 같은 데이터를 이미 받았는데도 요청할 때마다 다시 받아야한다
  • 인터넷 네트워크는 느리고 비싸다

캐시가 있을 때

  1. 서버에 데이터를 요청하면
  2. 서버는 해당 데이터를 HTTP 메세지로 전송한다
  3. 클라이언트는 데이터를 캐시에 저장하고
  4. 재요청시 캐시가 유효하다면 캐시로부터 데이터를 받으면 된다.

5. 캐시 유효시간이 지나면 다시 데이터를 요청해야한다

  • 캐시가 유효한동안 네트워크를 사용하지 않아도 된다
  • 속도가 빠르고, 비싼 네트워크 사용량을 줄일 수 있다!!

캐시 시간이 끝났는데 서버의 기존 데이터에 변경이 없다면?

  • 기존 캐시 데이터를 사용하면 된다
  • 하지만 그러려면 데이터가 바뀌지 않았다는걸 확인할 방법이 필요하다.
  1. 서버에 데이터 요청
  2. 서버는 해당 데이터를 HTTP 메세지로 전송
    • 이때 검증 헤더를 추가한다(Last-Modified)
  3. 클라이언트는 데이터를 캐시에 저장
  4. 재요청시 캐시가 유효하다면 캐시로부터 데이터를 받음
  5. 캐시 유효시간이 지나 다시 서버에 데이터에 요청한다
    • 데이터가 수정되었는지 확인한다
  6. 서버의 기존 데이터가 수정되지 않았다면 HTTP헤더만 전송(바디는 없음)한다
    - 이후 캐시는 다시 유효시간동안 사용 가능



검증 헤더

  • 캐시 데이터와 서버 데이터가 같은지 검증하는 데이터
  • Last-Modified, ETag

조건부 요청 헤더

  • 검증 헤더로 조건에 따른 분기(java의 if문)
  • If-Modified-Since : Last-Modified에서 사용
    - If-Unmodified-Since도 있음
  • If-None-Match : ETag에서 사용
    - If-Match도 있음
  • 조건이 만족하면 200 OK
  • 만족하지 않으면 304 Not Modified
  • ex)
    - 데이터가 그대로인경우
    캐시 :2020년 11월 10일 10:00:00 vs 서버: 2020년 11월 10일 10:00:00
    304 Not Modified, 헤더만 전송
    전송 용량 매우 적음
    - 데이터 변경시
    캐시: 2020년 11월 10일 10:00:00 vs 서버: 2023년 03월 12일 11:00:00
    모든 데이터 전송
    전송 용량 상대적으로 큼

Last-Modified :If-Modified-Since 단점

  • 날짜 기반의 로직이다.
  • 1초 미만의 단위로 조정 불가능하다.
  1. 같은 데이터인데 수정 날짜가 다른 경우
    • 예를 들어 데이터를 수정했다가 원래 데이터로 다시 수정한 경우
  2. 서버에서 캐시 로직을 관리하고 싶은 경우
    • 예를 들어 스페이스나 주석처럼 큰 영향이 없는 선에서 캐시를 변경하고 싶은 경우
  • 위의 두 경우에 실제 데이터는 변화가 없음에도 날짜가 바뀌어 다른 데이터로 인식하고 데이터를 전송해야 한다.

ETag : If-None-Match

  • Entity Tag
  • 캐시용 데이터에 고유한 버전 이름을 달아두는 방법이다.
  • 데이터가 변경되면 이름을 변경한다.(Hash를 재생성)
    - Hash는 데이터가 같다면 같은 Hash값을 반환하고 다르다면 다른 Hash값을 반환한다. 이 Hash를 이름으로 사용한다.
  • ETag가 같으면 캐시데이터 유지하고, 다르면 다시 받는다.
  • 캐시 제어 로직을 서버에서 완전히 관리
  • 클라이언트는 단순히 이 값을 서버에 제공하기만 하면 된다.
    - 즉, 클라이언트가 캐시 매커니즘을 몰라도 된다.
  • ex) 어플리케이션 배포 주기에 맞춰 ETag를 모두 갱신할 때

캐시 제어 헤더

Cache-Control

Cache-Control: max-age

  • 캐시 유효시간(초단위)

Cache-Control: no-cache

  • 데이터를 캐시해도 되나, 항상 원래(origin) 서버에 검증 후 사용
    - 프록시 서버가 아닌 원래 서버

Cache-Control: no-store

  • 민감한 정보가 있으므로 저장하면 안됨
    - 메모리에서 사용하고 최대한 빨리 삭제
    • Cache-Control: no-cache랑 구분하자!!

Pragma

  • 캐시 제어(하위 호환)
  • Pargma: no-cache
  • HTTP 1.0 하위 호환

Expires

  • 캐시 만료일 지정(하위 호환)
  • expires: Mon, 01 Jan 1990 00:00:00 GMT
  • 날짜로 지정
  • HTTP 0.1부터 사용
  • 지금은 Cache-Controll: max-age권장
    - max-age가 더 유연하기 때문이다.
    • Cache-Controll: max-age와 함께 사용시 Expires는 무시된다!!

프록시 캐시

해외에 있는 서버에 접속 시 소요되는 시간이 길기 때문에 프록시 캐시를 두어 프록시 캐시에서 데이터를 받아감

Cache-Controll: public

  • 응답이 public 캐시에 저장되도 됨

Cache-Controll: private

  • 응답이 요청 사용자 private 캐시에 저장되어야 함
    - 기본값으로 설정되어 있다!

Cache-Controll: s-maxage

  • 프록시 캐시에 적용되는 유효시간

Age: 60(HTTP헤더)

  • 오리진 서버에서 응답 후 프록시 캐시 내에 머문 시간(초)

캐시 무효화

확실한 캐시 무효화 응답

  • Cache-Control: no-cache, no-store, must-revalidate
    Pragma: no-cache를 모두 선언해줘야 함
  • no-cache : 캐시는 되지만 원래 서버에 검증 후 사용
  • no-store : 민감한 정보가 있으므로 저장하면 안됨
  • must-revalidate
    - 캐시 유효시간이라면 캐시를 사용
    - 캐시 만료 후 최초 조회 시 원(original) 서버에 검증해야 함
    - 원 서버 접근 실패시 504(Gateway Timeout) 발생

    프록시 캐시와 원래 서버간 네트워크가 단절됐을 때,
    no-cache의 경우 캐시 서버의 설정에 따라 프록시 캐시를 반환할 수도 있음
    must-revalidate의 경우 504 Gateway Timeout 발생

출처 : 링크텍스트

profile
꾸준히 하자!

0개의 댓글