Notice
Recent Posts
Recent Comments
Link
관리 메뉴

look-forest

HTTP Header - 캐시와 조건부 요청 본문

Web/HTTP

HTTP Header - 캐시와 조건부 요청

studyHub 2021. 5. 31. 20:57

이번 시간에는 캐시와 캐시 관련 헤더에 대해 알아보겠다.

 


캐시 기본 동작

캐시가 없으면..

데이터가 변경되지 않아도 계속 네트워크를 통해서 데이터를 다운로드 받아야 한다

 

몇번이고 1.1M를 매번 다 받아야 한다..

인터넷 네트워크는 매우 느리고 비싸다브라우저 로딩 속도가 느려진다느린 사용자 경험

 

캐시를 도입하자!

1. 응답 메시지에 cache-control 필드 추가

 

2. 응답 결과를 브라우저 캐시에 저장

 

3. 이후 요청은 브라우저 캐시에서 꺼내쓴다!

 

캐시 덕분에 캐시 가능 시간 동안 네트워크를 사용하지 않아도 된다!!

 

그런데

캐시 유효 시간이 초과하면, 서버를 통해 데이터를 다시 받아 캐시를 갱신한다

리소스는 바뀐 게 없는데, 굳이 이런 바보 같은 짓을 해야 할까?

 

 


검증 헤더와 조건부 요청

캐시 유효 시간 초과 시

캐시 유효 시간이 초과해서 서버에 다시 요청하면 다음 가지 상황이 나타난다.

1. 서버에서 기존 데이터를 변경함

2. 서버에서 기존 데이터를 변경하지 않음데이터를 전송하는 대신에 저장해 두었던 캐시를 재사용할 수 있다

 그럴려면 클라이언트의 데이터와 서버의 데이터가 같다는 사실을 확인 있는 방법 필요하다.

 

[방법 1] Last-Modified와 If-Modified-Since

1. 응답 메시지에 검증 헤더 추가

 

데이터 최종 수정일이 2020 년 11 월 10 일 10:00:00 이다

2. 캐시 시간 초과로 재요청 , 조건부 요청

 

클라이언트가 가지고 있는 데이터의 최종 수정일을 보낸다

3. 검증

 

양측 데이터의 최종 수정일을 비교해본다

4. 응답

- 데이터 변경 , 200 OK, 모든 데이터 전송(BODY 포함)

- 서버의 데이터가 갱신되지 않았다면 304 Not Modified 응답 (헤더 메타 정보만 응답, 바디 X)

캐시로 리다이렉트!

클라이언트는 서버가 보낸 응답 헤더 정보로 캐시의 메타 정보를 갱신하고, 캐시에 저장되어 있는 데이터재활용한다.

유효 시간 갱신 후 재사용

 

Last-Modified, If-Modified-Since 단점

  1. A에서 B로 바꾸고 다시 A로 바꿨다면? (A→B→A)
    실제 데이터는 결과적으로 바뀐 게 없으나 수정 날짜는 변경됐다.

  2. 서버에서 별도의 캐시 로직을 관리하고 싶은 경우에 적합하지 않다.
    예) 스페이스나 주석처럼 크게 영향이 없는 변경에서 캐시를 유지하고 싶은 경우

 

[방법 2] ETag, If-None-Match

ETag 같으면 유지, 다르면 다시 받기!

 

ETag(Entity Tag)란?

  • 캐시용 데이터에 임의의 고유한 버전 이름 달아둔다. (*Hash 사용하기도 한다)
    ) ETag: "v1.0", ETag: "a2jiodwjekjl3"
  • 데이터가 변경되면 이름을 변경하거나 Hash 다시 생성

Hash는 파일 내용이 동일하면 같은 해시값을 갖는다는 것을 활용

 

 

1. 응답 메시지에 검증 헤더 추가

 

2. 캐시 시간 초과로 재요청 , 조건부 요청

 

 

3. 검증

- ETag 비교하여 데이터 변경 여부 확인

 

4. 응답

- 데이터 변경 시, 200 OK, 모든 데이터 전송(BODY 포함)

- 서버의 데이터가 갱신되지 않았다면 304 Not Modified 응답 (헤더 메타 정보만 응답, 바디 X)

 

 

ETag, If-None-Match 장점

캐시 제어 로직을 서버에서 완전히 관리할 수 있다

)

서버는 베 오픈 기간인 3 동안 파일이 변경되어도 ETag 동일하게 유지

애플리케이션 배포 주기에 맞추어 ETag 모두 갱신

 

 


캐시와 조건부 요청 헤더

캐시 제어 헤더

  • Cache-Control: 캐시 지시어(directives)
    • Cache-Control: max-age
      캐시 유효 시간( 단위)
    • Cache-Control: no-cache
      데이터는 캐시에 저장해도 되지만, 항상 (origin) 서버에 검증하고 사용
    • Cache-Control: no-store
      데이터에 민감한 정보가 있으므로 저장하면 안됨 (메모리에서 사용하고 최대한 빨리 삭제)
  • Pragma: 캐시 제어 (HTTP 1.0 하위 호환)
    Pragma: no-cache (데이터는 캐시해도 되지만, 항상 원(origin) 서버에 검증하고 사용)

  • Expires: 캐시 유효 기간 (HTTP 1.0 하위 호환)
    expires: Mon, 01 Jan 1990 00:00:00 GMT (초 단위가 더 유연하므로 Cache-Control: max-age 권장)

검증 헤더 (Validator)

  • Etag
  • Last-Modified

조건부 요청 헤더

  • If-Match, If-None-Match: ETag 사용
  • If-Modified-Since, If-Unmodified-Since: Last-Modified 사용

 


프록시 캐시

[문제] 원 서버 직접 접근

인터넷 네트워크는 매우 느리고 비싸므로, 멀리 있는 서버일수록 느리다.

 

 

[해결] 프록시 캐시 도입

가까운 프록시 캐시 서버에 원 서버의 데이터를 저장해둔다!

DNS을 조정하여, 클라이언트가 프록시 서버를 거쳐 오도록 한다.

 

프록시 캐시 서버에서 데이터를 빠르게 가져온다!

 

CDN도 같은 원리이다.

더보기

CDN (Contents Distribution Network)

비디오 데이터를 단일 거대 데이터 센터에서 제공할 경우,

  •  지점에 있는 경우 느리다 (많은 네트워크를 거칠수록 throughput 낮아질  있음)
  • 인기 있는 비디오가 동일 링크로 여러  반복 전송되는 낭비
  • 장애가 발생하면 전체 서비스가 중단될  있다

따라서 비디오 스트리밍 회사(컨텐츠 제공자)들은 CDN 이용한다.

CDN 다수의 지점 분산된 서버 운영하여, 복사본 이들 분산 서버에 저장한다.

 

URL 지정하여 특정 비디오를 요청하면,

CDN DNS 이용해 요청을 가로채고 클라이언트에게 가장 적당한 클러스터를 연결한다.

사용자는 최선의 사용자 경험을 제공할  있는 지점의 CDN 서버로 연결된다.

 

그래서 유튜브에서 인기 많은 영상은 빠르게   있고, 사람들이 많이 보지 않는 영상은 느린 것이다!

 

프록시 캐시 서버 관련 헤더

  • Cache-Control: private (기본값)
    응답이 해당 사용자만을 위한 것이다. 따라서 private 캐시에만 저장해야 한다. (로그인 내역 )
  • Cache-Control: public
    응답이 public 캐시에 저장되어도 된다.
  • Cache-Control: s-maxage
    프록시
    캐시에만 적용되는 max-age.

 


캐시 무효화

[문제 상황]

서버가 요청하지 않아도, 브라우저가 임의로 캐시해버릴 있다.

통장 잔고 계속 갱신되는 정보를 캐시해서 쓰면 안되기 때문에, 캐시하지 말라고 응답해야 한다.

 

확실한 캐시 무효화 응답을 위해 넣어야 하는 헤더 필드 값

확실한 캐시 무효화를 위해서는 아래 4가지를 전부 넣어줘야 한다.

  • Cache-Control: no-store, no-cache, must-revalidate
  • Pragma: no-cache (HTTP 1.0 하위 호환을 위해. HTTP 1.0 Cache-control 모른다)

no-store, no-cache, must-revalidate 의미하는

  • Cache-Control: no-store
    데이터에
    민감한 정보가 있으므로 저장하면 안된다. 메모리에서 사용하고 최대한 빨리 삭제해라.
  • Cache-Control: no-cache
    데이터는
    캐시에 저장해도 되지만, 항상 서버에 검증하고 사용해라
  • Cache-Control: must-revalidate
    캐시 만료후 최초 조회시 서버에 검증해야 한다. (캐시 유효 시간이라면 캐시를 사용한다)
※ no-store만으로 캐시가 무효화되어야 하나, 모호한 부분들이 존재해서 이것저것 다 때려 박는 것이다.

 

그런데, no-cache, must-revalidate은 기능이 겹치는 것 같은데 왜 둘 다 써야 하는가?

 

no-cache must-revalidate 차이

[no-cache 기본 동작]

프록시 서버는 no-cache 보고 서버에 요청을 전달한다

 

프록시 서버: "no-cache? 음 내가 처리하면 안되는 구나. 원 서버에게 보내야겠다."

 

[no-cache 에러에 대응하는 자세]

프록시 캐시 서버는 no-cache , 원 서버와 통신이 되지 않아도 에러를 내지 않는다

 

프록시 서버: " 장애를 내기보다는 옛날 데이터라도 보여주자"

 

[must-revalidate 에러에 대응하는 자세]

must-revalidate 원 서버 접근 실패 시 오류를 발생시킨다. (504, Gateway Timeout)

 

프록시 서버: "must-revalidate? must? 아 이건 못 참지"

 

 

 


 

참고 자료 & 이미지 출처
모든 개발자를 위한 HTTP 웹 기본 지식 (김영한 님)
컴퓨터 네트워킹 : 하향식 접근 7판 (JAMES F.KUROSE)

 

'Web > HTTP' 카테고리의 다른 글

HTTP Header - 일반 헤더  (0) 2021.05.31
HTTP 상태 코드  (0) 2021.05.28
HTTP 메서드 활용  (0) 2021.05.24
HTTP 메서드  (0) 2021.05.24
HTTP 기본  (0) 2021.05.17