CS/네트워크

HTTP 완벽 가이드 7장. 캐시

journey-dev 2024. 5. 13. 01:07

✅ 캐시 방법

1. 로컬 캐싱
: 클라이언트 측에 캐시를 저장하여 이전에 요청했던 리소스를 로컬에서 빠르게 제공할 수 있습니다.

이렇게 되면 동일한 리소스에 대한 요청이 다시 서버로 전송되지 않으므로 대역폭을 절약할 수 있습니다.

 

2. 중간 캐시
: 중간 캐시 서버(Proxy Server, CDN 등)가 클라이언트와 서버 사이에 위치하여 네트워크 트래픽을 캐시하여 처리합니다.
클라이언트가 요청한 리소스가 이미 중간 캐시에 존재한다면, 서버로부터 다시 요청할 필요가 없으므로 대역폭을 절약할 수 있습니다.

 

3. CDN(Content Delivery Network)
: CDN은 전 세계에 분산된 서버 네트워크를 통해 콘텐츠를 캐시하고 제공합니다.
이를 통해 지역적으로 가장 가까운 서버에서 콘텐츠를 제공할 수 있으며, 이로 인해 전체적인 대역폭 사용량이 감소하게 됩니다.

 

 

 캐시의 장점

1. 불필요한 데이터 전송 줄임

서버 응답이 캐시에 보관되어, 이 캐시된 사본을 여러 클라이언트에게 전달할 수 있다.

때문에 원 서버가 중복해서 트래픽을 쓰지 않아도 되어 > 네트워크 요즘으로 인한 비용 절감 가능

 

2. 대역폭 병목을 줄여줌 

캐시가 클라이언트와 서버 간에 전송되는 데이터 양을 줄여주고, 이로 인해 네트워크 트래픽이 감소함으로써 대역폭 사용량이 줄어들게 됨 

 

3. 서버의 과부하를 줄임

많은 사람이 동시에 웹문서에 접근해도 캐시를 사용하면, 원서버에 불필요한 트래픽 급증을 막을 수 있다.

 

4. 거리로 인한 지연 줄임

중간에 CDN같은 중간서버에서 캐시를 함으로서 문서가 전송되는 거리를 줄일 수 있다. > 트래픽 지연 완화

 


 
캐시 적중,부적중

 

1. 적중: 캐시 요청에 대응하는 사본이 있을시

2. 부적중 : 캐시 요청에 대응하는 사본이 없을시

3. 재검사 : 캐시는 사본이 여전히 최신인지 검사해야 함. 이런 신선도 검사를 HTTP 재검사라 함.

 

<캐시된 객체를 확인하는 법>

- 클라이언트가 GET요청 헤더에 If-Modified-Since:<date> 를 추가

  : date 이후로 수정되었으면 원서버에서 새로 리소스 요청해오게 됨

1) 재검사 적중 : 콘텐츠가 변경되지 않았다면

  - 원서버는 304 Not Modified응답을 보내고,
  - 캐시는 받아논 사본이 신선하다고 보아 받아논 그 사본을 클라이언트에게 제공한다.

 

2) 재검사 부적중 
: 서버 객체와 캐시된 사본이 다르다면

- 서버는 콘텐츠 전체와 200 OK응답을 클라이언트에 보냄

 

3)원서버에서 객체 삭제되었다면

-원버서는 404 Not Found응답, 캐시는 사본을 삭제함

 

 


 
캐시 적중률 

1. 캐시 적중률
  : 캐시가 요청을 처리하는 비율, 적중률이 높을 수록 캐시가 잘 동작하고 있는것
  : 적중률 40%만되도 웹 캐시로 괜찮은 편


  1) 캐시 문서 적중률(Cache Hit Ratio)
  : 캐시에서 요청된 문서를 찾은 비율.
  : 캐시에서 요청된 문서를 찾을 수 있는 경우 캐시 적중(Hit)이라고 하며, 찾을 수 없는 경우 캐시 미스(Miss)라고 합니다.

  2) 바이트 적중률(Cache Byte Hit Ratio)
  : 캐시에서 전송된 바이트 수의 비율. 
  : ex) 총 100MB의 데이터를 요청 했고, 70MB가 캐시에서 찾아진 데이터, 30MB가 캐시를 찾지 못한 경우 바이트 적중률은 70% 

 

2. 클라이언트에서 응답이 캐시에서 왔는지, 원서버에서 왔는지 알아내는 법

- http 클라이언트에게 응답이 캐시 적중이였는지, 원서버 접근이였는지 알려주진 았음.

   1) 응답의 Date헤더와 현재 시각 비교

   : 현재 시각보다 응답 생성일(Date)가 더 오래됐다면, 응답이 캐시된 것임.

   2) Age헤더 이용
   : 응답이 얼마나 오래되었는지 말해주는 헤더임

 

 

 캐시 토폴로지

1. 개인 전용 캐시

: 한 명의 사용자에게만 할당된 캐시

: 웹 브라우저는 개인 전용 캐시를 내장하고 있다. 브라우저는 개인 컴퓨터의 디스크나 메모리에 캐시해 놓을 수 있다.

 

2. 공용 캐시

: 여러 사용자들이 접근. 집단에게 자주 쓰이는 페이지를 담는다.

: 공용 캐시는 프락시 서버다. (중간에서 프락시 서버가 캐시해주는 구조)

: 공유된 캐시는 네트워크 트래픽을 줄일 수 있다.

 

[프락시 캐시 계층들]

- 작은 캐시에서 캐시 부적중 발생시, 부모 캐시가 트래픽 처리하도록 계층을 만듦

- 클라이언트 주위에는 작고 저렴한 캐시 사용,
  상단에는 많은 사용자들에게 공유되는 문서를 유지. 더 크고 강력한 캐시 사용

 


 
캐시 처리 단계

1. http요청 받기

2. 파싱 : url, 헤더 추출

3. 검색 : 캐시는 로컬 복사본이 있는지 검사하여 사본이 있는지 판별

4. 신선도 검사 : 캐시된 사본이 신선한지 검사

5. 응답 생성

: 캐시는 새로운 헤더와, 캐시된 본문으로 응답 메세지 만들어 응답함
: !! Date헤더를 조정해선 안된다 - Date헤더는 그 객체가 원 서버에서 최초로 생겨난 일시를 표현하는 것이여서 

6. 발송 : 네트워크를 통해 클라이언트에 응답

7. 로깅

캐시 GET요청 플로우 차트

 

 

캐시 사본 유효기간

Cache-Control : max-age=<초>

: max-age값은 문서의 최대 나이를 정의함.

: 해당 초 동안 문서를 캐싱할 수 있다

 

Expires : <http-date>
: 예)Expires: Wed, 21 Oct 2015 07:28:00 GMT

: 절대 유효기간을 표시.
: 이 유효기간 경과하면 문서는 더이상 신선하지 않다.

 

[서버 재검사]
: 캐시가 원서버에게 문서 변경 여부를 물어볼 필요가 있음

: 캐시된 문서가 만료됐다는 것은, 문서가 달라졌다는게 아니라 이제 검사할 시간이 됐다는 뜻이다.

: 재검사 결과

  - 콘텐츠가 변경됐다면 : 새로운 사본을 가져와 새로 저장, 클라이언트에 응답

  - 콘텐츠가 변경되지 않았다면 : 캐시는 새 만료일을 포함한 새 헤더만 가져와 -> 캐시된 사본의 헤더을 갱신한다.

 

 

[캐시 재검사]

1. 날짜 재검사

1) If-Modified-Since : <캐시된 마지막 수정일>

: 캐시가 캐시된 문서를 재검사 할 때, 캐시된 사본의 마지막 수정일을 서버에게 전달 하는 역할 함.

: IMG 날짜와 last-modified 날짜를 비교해서, img날짜 이후로 문서가 수정됐다면 새 콘텐츠를 가져온다.

: Get,Head 요청에서만 사용가능

 

2) Last-Modified : <날짜>

: 서버가 리소스를 마지막으로 수정한 시간을 클라이언트에게 알려주는 역할함.

 

3) If-Modified-Since 헤더는 Last-Modified 헤더와 함께 동작함

- IMG(2024.05.01) < Last-Modified(2024.05.03)
  : IMG 조건은 참, 새 문서가 새로운 만료 날짜로 캐시에 반환됨

 

- IMG(2024.05.03) > Last-Modified(2024.05.01)  

  : IMG 조건은 거짓
  : 304 Not Modified 응답. 본문은 보내지 않는다. 
  : 응답 헤더는 포함, 그러나 모든 헤더를 보내는게 아니라, '새 만료 날짜'와 같이 갱신이 필요한 것만 보낸다.

 

2.엔터티 태그 재검사 (ETag)

1) If-None-Match : <Etag>

  : 엔터티 태그가 변경됐다면, 새 문서의 사본을 얻게된다.

  : 엔터티 태그가 변경되지 않으면, 304응답

  : 캐시가 동일 문서에 대한 여러 사본을 갖고있는 경우, 서버에게 알리기 위해 
   하나의 If-None-Match헤더에 여러 개 엔터티 태그 포함시킬 수 있다. (
 If-None-Match : "v2.4","v2.5","v2.6" )

2) 동작

a-1) 최초 요청
a-2) 응답 : 200응답. 응답 헤더에 Etag 붙어있음
b-1) 재요청 : 이전에 받은 ETag 값을 요청 Header의 If-Not-Match 속성의 값으로 붙게됨. 
b-2) 응답 : 변경된 사항이 없어 304 Not Modified가 응답됨. 캐싱된 데이터 사용됨.

 

ETag를 통한 송수신

 

3. 언제 엔터티 태그를 사용하고, 언제 last-modified일시를 사용? 💡💡🥲

1) 엔터티 태그 (ETag)

  • 데이터의 정확성: 엔터티 태그는 리소스의 변경 여부를 식별하는데 더욱 정확하게 사용될 수 있습니다. 이는 보다 미세한 변경도 감지할 수 있다는 것을 의미합니다.
  • 리소스의 복잡성: 복잡한 데이터를 가진 리소스의 경우, 엔터티 태그가 더 유용할 수 있습니다. 예를 들어, 대규모 데이터베이스나 동적으로 생성되는 콘텐츠의 경우, 단순한 날짜 기반의 변경 시간으로는 충분하지 않을 수 있습니다.
  • 문서가 주기적으로 업데이트가 되지만, 바뀐 내용이 없는 경우 
    변경된 내용이 있지만, 응답상으로는 의미가 크지 않은 경우 
  • 유효한 시간을 정하기 어려운 경우 

2) Last-Modified 헤더:

  • 리소스의 변경 빈도: Last-Modified 헤더는 리소스의 최종 수정일을 나타내므로, 리소스의 변경이 상대적으로 자주 발생하지 않을 때 유용합니다. 예를 들어, 정적인 이미지 파일이나 CSS 파일 등은 변경이 드물기 때문에 Last-Modified 헤더를 사용할 수 있습니다.
  • 리소스의 단순성: 단순하고 정적인 리소스의 경우, Last-Modified 헤더가 더 간단하게 구현되고 사용될 수 있습니다.

일반적으로, 복잡하고 동적인 데이터의 경우에는 엔터티 태그가 더 적합하며, 정적인 파일이나 변경 빈도가 낮은 리소스의 경우에는 Last-Modified 헤더가 더 적합합니다.

 

또한, 엔터티 태그와 Last-Modified 헤더를 함께 사용하여 클라이언트 측의 캐시 유효성 검사를 보다 효과적으로 수행할 수 있습니다.

-> 이 경우 두 조건이 모두 부합되야 304 반환됨.


 캐시 제어

1. Cache-Control : no-store

  • 기능: no-store 헤더는 응답이나 요청에 대해 캐시를 사용하지 않도록 지시합니다. 이 헤더가 포함된 응답은 클라이언트나 중간 캐시에 저장되지 않으며, 매번 새로운 요청이 발생합니다.
  • 사용 방법: 캐싱을 피해야 할 민감한 정보가 포함된 리소스에 대해 이 헤더를 사용합니다.


2. Cache-Control : 
no-cache

  • 기능: no-cache 헤더는 캐시를 사용하지 않는 것을 강제하지는 않지만, 서버와 재검사를 하지 않고서는, 캐시에서 클라이언트로 제공될 수 없다.
  • 사용 방법: 캐시된 리소스의 변경 여부를 확인하고자 할 때 사용합니다. 서버에서 리소스가 변경되지 않았다면 클라이언트는 캐시된 리소스를 계속 사용할 수 있습니다.


3. Pragma
:

  • 기능: Pragma 헤더는 HTTP 1.0에서 사용되었으며, 캐시 동작을 제어하는 데 사용됩니다. 보통 Pragma: no-cache 형식으로 사용되며, 캐시를 사용하지 않도록 지시합니다.
  • 사용 방법: HTTP 1.0과의 하위 호환성을 유지하거나 특정 상황에서 캐시를 사용하지 않도록 지시할 때 사용됩니다.


4. Cache-Control : Max-Age = <second>

Max-Age 는 문서가 원 서버로부터 캐시 서버로부터 보낸 후 흐른 시간을 나타낸다. 캐시 서버에 사본이 정해진 시간 만큼만 존재 할 수 있도록 하며 시간은 초 단위로 나눈다.

사본을 저장시키지 않고 싶은 경우엔 Max-Age 를 0으로 설정하기도 한다.

5. Expires

Expires 헤더는 초 단위가 아닌 실제 만료 날짜를 명시한다.

다만 더 이상 해당 헤더는 사용하지를 않기를 권하는데 이는 서버 마다 부정확한 시계를 가지고 있기 때문에 차라리 초 단위로 만료 기간을 정하는 것을 더 추천한다고 한다.

6. Cache-Control : Must-Revalidate

Cache-Control : Must-Revalidate 는 캐시 서버가 만료 정보를 엄격하게 따르길 원할 때 사용한다.

원 서버는 캐시 서버가 원서버와의 최초의 재검사 없이는 제공하지 않도록 한다

 

 

- 클라이언트는 Cache-Control 요청 헤더를 사용하여 만료 제약을 엄격하게 or 느슨하게 할 수 있다.

 

 


참고자료

https://www.blog-dreamus.com/post/cache-control-%EC%9D%B4-%ED%95%84%EC%9A%94%ED%95%9C-%EC%9D%B4%EC%9C%A0

 

'Cache-Control'이 필요한 이유

앱의 성능을 향상시키는 방법 중 하나인 캐시. 클라이언트에서 캐쉬를 하고, 서버에서 컨트롤이 가능한 Cache-Control에 대해서 알아봅니다.

www.blog-dreamus.com

https://www.researchgate.net/figure/Conditional-request-using-the-ETag-and-If-None-Match-HTTP-headers_fig16_322746368