캐시(Cache)

5o_hyun·2023년 1월 9일
0
post-thumbnail

캐시

캐시는 컴퓨터 내부의 임시 저장공간이다.
인터넷에서 사이트에 방문했을때 다운로드한 파일이 캐시에 저장되고, 다시 방문할때 모든것을 다운로드하지않아도 캐시에 있는걸 사용하면 된다.

캐시가 없을때 계속 네트워크를 통해서 데이터를 다운받아야 하므로 브라우저 로딩속도가 느리다.
캐시를 사용하면 캐시 가능 시간동안 네트워크를 타지 않아도 된다. 따라서 브라우저 로딩속도가 매우 빠르다.

캐시 기본동작

최초 요청시 응답메시지 헤더에 cache-control: max-age=유효시간을 넣어서 보낸다. 클라이언트 내부의 캐시저장소에 유효시간 정보를 저장한다. 캐시 유효시간이 남아있다면 서버에서 요청하지않고 캐시에서 가져온다.

캐시 유효시간 초과

캐시 유효시간이 초과하면, 서버를 통해 데이터를 다시조회하고, 캐시를 갱신한다.
그러나 변경되지 않은 데이터라면 이미 캐시로 다운로드 했던것을 굳이 또 다운로드 받아야할까?
아니다.
캐시 유효시간이 초과해서 서버에 다시 요청하면 다음 두 가지 상황이 나타난다.

    1. 서버에서 기존 데이터를 변경 ★ -> ☆
    1. 서버에서 기존 데이터를 변경하지않음 ★

캐시 만료후에도 서버에서 데이터를 변경하지않을경우 ★, 저장해 두었던 캐시를 재사용 할 수 있다.
단, 클라이언트의 데이터와 서버의 데이터가 같다는 사실을 확인할 수 있는 방법이 필요한데 이를 검증헤더 + 조건부요청으로 한다.

검증헤더와 조건부요청

  • 첫번째 요청시 서버에 star.jpg를 요청했을때 cache-control(유효시간) 과 Last-Modified(최종데이터수정일) 을 응답한다.
    브라우저에 캐시가 저장될때 응답값을 가지고 있는다.
  • 두번째 요청시 캐시의 유효시간이 초과되었을때 , 요청시 if-modified-since로 캐시가 가지고있던 데이터최종수정일을 보낸다.
    요청을 보낸 최종수정일 데이터와, 서버의 최종수정일 데이터가 일치하면 304코드와함께 HTTP 헤더만 전송한다 (body 전송 x)
    헤더 데이터를 갱신하여 유효시간을 갱신해줘서 캐시를 재사용 할 수 있다.
  • 결과적으로 검증헤더Last-Modified 와 조건부요청 cache-control 둘 다 사용

정리

  • 캐시 유효시간이 초과해도, 서버의 데이터가 갱신되지않으면 304응답코드
  • 헤더 메타정보만 응답 ( body x )
  • 클라이언트는 서버가 보낸 응답 헤더 정보로 캐시의 메타정보를 갱신
  • 클라이언트는 캐시에 저장되어 있는 데이터 재활용
  • 결과적으로 네트워크 다운로드가 발생하지만 용량이 적은 헤더 정보만 다운로드

검증헤더

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

조건부 요청 헤더

  • 검증헤더로 조건에 따른 분기로 서버에 요청
  • If-Modified-Since, If-None-Match
  • 조건이 만족하면 200 OK, 조건이 만족하지않으면 304 Not Modified

If-Modified-Since: 이후에 데이터가 수정되었나?

  • 데이터 미변경
    캐시데이터 === 서버데이터
    304 Not Modified, 헤더 데이터만 전송(BODY 미포함)
    : 너의 캐시저장소로 리다이렉션해서 데이터뿌려라
    전송용량 0.1M (헤더 0.1M + 바디 1.0M)
  • 데이터 변경
    캐시데이터 !== 서버데이터
    200 OK, 모든 데이터 전송(BODY 포함)
    전송용량 1.1M (헤더 0.1M + 바디 1.0M)

Last-Modified,If-Modified-Since 의 단점
1. 1초미만 단위로 캐시 조정 불가능
2. 날짜 기반의 로직 사용
3. 데이터를 수정해서 날짜가 다르지만, 데이터를 수정해서 데이터결과가 똑같은경우

서버에서 별도의 캐시로직을 관리하고싶을때는??
ex ) 스페이스나 주석처럼 크게 영향이 없는 변경에서 캐시를 유지하고 싶은경우

▼▼▼

Etag,If-None-Match (Last-Modified,If-Modified-Since 보완)

  • 캐시용 데이터에 임의의 고유한 버전 이름을 달아둠
    ex) ETag: "v1.0"
  • 데이터가 변경되면 이 이름을 바꾸어서 변경함 (Hash를 다시 생성)
    ex) ETag: "aaaaa" -> ETag: "bbbbb"
  • 진짜 단순하게 ETag만 보내서 같으면 유지, 다르면 다시 받기
  • 캐시 제어 로직을 서버에서 완전히 관리

캐시 제어 헤더

  • Cache-Control : 캐시 제어
  • Pragma : 캐시 제어 (하휘호환)
  • Expires : 캐시 만료일 지정 (하휘호환)

Cache-Control

캐시지시어

  • Cache-Control : max-age
    캐시 유효시간
  • Cache-Control : no-cache
    데이터는 캐시해도되지만, 항상 원(origin) 서버에 검증하고 사용
  • Cache-Control: no-store
    데이터에 민감한 정보가 있으므로 저장하면 안됨

Proxy Cache

  • Cache-Control: public
    응답이 public 캐시에 저장되어도 됨
  • Cache-Control: private
    응답이 해당 사용자만을 위한 것임, private 캐시에 저장해야 함(default)

Cache 무효화

우리가 캐시를 사용하지않아도 웹 브라우저에서 임의로 캐시를 저장하는 경우가있다. 하지만 이 페이지에서만큼은 진짜 캐시되면안돼!! 라고 할때(카드정보,통장잔고 등)

  • Cache-Control: no-cache, no-store, must-revalidate
  • Pragma: no-cache ( HTTP 1.0 하휘호환 => 예전브라우저까지 막음)

이 위에있는걸 다 넣어야한다. 확실한 캐시 무효화 응답 방법이다.

  • Cache-Control:no-cache
    데이터는 캐시해도 되지만, 항상 원 서버에 검증하고 사용(이름에 주의!)

  • Cache-Control: no-store
    데이터에 민감한 정보가 있으므로 저장하면 안됨
    메모리에서 사용하고 최대한 빨리 삭제

  • Cache-Control: must-revalidate
    캐시 만료 후 최초 조회시 원 서버에 검증해야함
    노캐시로만 사용시 원서버가 네트워크 단절시, 프록시서버에서 옛날 데이터라도 내려준다. 그럼 사용자는 옛날 데이터를 보게된다.
    (사용자가 옛날 통장잔고를 보게됨)
    원 서버에 접근 실패시 반드시 오류가 발생해야함 - 504(Gateway Timeout)

  • Pragma: no-cache
    HTTP 1.0 하위호환

profile
학생 점심 좀 차려

0개의 댓글