웹 캐시 (WEB Cache) 정리

citron03·2022년 5월 28일
0
  • 웹 캐시는 사용될 일이 많은데, 최근에는 사용할 일이 없었던 것 같다.
  • 그렇기에, 까먹기 전에 HTTP와 관련된 웹 캐시에 대해서 배웠던 내용을 정리하기로 하였다.

🍥 캐시와 관련된 HTTP 헤더

  • 클라이언트 앱이 서버에 요청을 보낼 때, 이미 가지고 있는 용량이 큰 데이터(이미지 등)에 대한 요청을 다시 보낼 수도 있다.

  • 만약, 요청을 보냈을 때 마다 이미 가지고 있던 데이터라도(수정 되지 않은 데이터) 다시 받아오게 된다면 대단히 비효율적일 것이다.

🍝 인터넷 네트워크는 느리고 비싸다. 브라우저의 로딩 속도가 느려지면 느린 사용자의 경험이 제공되어 버린다.
🍝 용량이 큰 파일을 받을수록 당연히 로딩은 느려질 것이다.

  • 데이터나 값을 미리 복사하여 저장하는 임시장소인 캐시를 사용하면, 브라우저가 이를 기억하고 저장할 수 있다.

  • 캐시를 사용하면 데이터 접근에 걸리는 시간이나 같은 값을 계산하는 시간을 줄일 수 있다.

🍚 캐시의 데이터를 사용하면, 접근 시간이나 계산이 필요없이 더 빨리 데이터에 접근할 수 있다.

  • 브라우저의 캐시를 저장할 땐 cache-control 속성을 이용하여 캐시가 유효한 시간을 정할 수 있다.

  • 응답을 받은 경우 cache-control에 지정된 시간만큼 응답에 대한 결과를 브라우저 캐시에 저장한다.

  • 만약, 캐시가 존재할 때 cache-control에 지정된 시간 이내에 다시 이 데이터에 대한 요청이 온다면, 캐시에 있는 데이터를 가져오게 된다.

🍙 cache-control 속성의 값을 60초로 설정하면, 60초 동안 이 캐시가 유효하다는 것을 의미한다.

🍙 캐시를 사용하면, 네트워크를 사용하지 않고 데이터를 가져올 수 있기에 브라우저 로딩이 빠르다. 그렇기에 빠른 사용자 경험을 제공할 수 있다.

🍙 비싼 네트워크를 적게 사용할 수 있다.

  • cache-control에 지정된 캐시 유효기간이 지난 뒤 다시 요청이 오면, 이번에는 네트워크를 사용하여 서버에서 데이터를 받아와야 한다.

🍡 유효 기간이 지난 뒤 네트워크를 통해 다시 받은 응답의 결과는 기존에 유효기간이 지난 캐시에 덮어씌워(업데이트)진다. 그리고 유효기간은 다시 갱신된다.

🎂 캐시 검증 헤더

  • 캐시를 검증할 수 있는 캐시 검증헤더가 있다. 그리고 이를 통해서 조건부로 요청을 보낼 수 있다.

  • cache-control에 지정된 캐시 유효기간이 지났어도, 데이터가 변하지 않았다면 다시 캐시의 데이터를 사용할 수 있는 방법이 있다.

🍩 이때, 데이터를 검증을 한 뒤에 기존의 캐시 데이터를 사용할 수도 있다.

  • HTTP 응답 헤더의 검증 헤더인 Last-Modified의 값을 보고 언제 마지막으로 데이터가 수정되었는지 알 수 있다.

🍫 응답 결과가 캐시에 저장될 때 Last Modified(데이터 최종 수정 시간)도 저장된다.

  • 캐시의 유효기간이 초과 되었어도, If-Modified-Since HTTP 요청 헤더를 사용하여 조건부로 요청을 할 수 있다.

  • 서버는 데이터를 검증하고, 데이터가 수정되지 않았다면 바디를 제외한 HTTP 헤더만 보내어 데이터 수정이 없었음을 알려준다. (상태 코드 304 Not Modified)

🍧 클라이언트는 서버가 보낸 헤더의 정보로 캐시의 메타데이터를 갱신한다.

  • 이 응답을 받은 뒤 다시 캐시의 유효 기간은 갱신된다. 유효기간이 지났어도, 데이터가 변경되지 않았다면 서버에서 데이터 다운로드가 일어나지 않는 아주 효율적인 방법이다.

  • 다만, Last-Modified와 If-Modified-Since는 1초 미만의 단위로 캐시를 조정할 수 없고 날짜 기반의 로직을 사용한다.

🍪 따라서 같은 데이터라도 수정한 날짜가 다르면 다시 데이터를 전송한다. 그리고 서버에서 캐시 로직를 관리하고자 할 때 유효하지 않을 수 있다. (ex. 주석, 공백 제거 후 캐시 유지 하기)

  • Last-Modified와 If-Modified-Since보다 간편한 방법으로 ETag와 If-None-Match 검증 헤더가 있다.

🍡 서버에서 완전히 캐시를 컨트롤 하고자 한다면, ETag(Entity Tag)를 사용한다. ETag는 캐시 데이터에 고유한 버전 이름을 명시한다. 데이터가 변경되면 이 이름이 변경된다. (ETag가 변경되면 다른 데이터로 인식)

  • 응답의 ETag 값은 클라이언트 캐시에 저장되고 캐시 시간이 초과되었을 때, ETag는 ETag 값을 검증하는 If-None-Match를 요청 헤더에 작성되어 보내진다. (조건부 요청)

  • 데이터가 변경되지 않았다면 ETag 값은 동일하고, 이때는 body 없이 HTTP 헤더만 전송된다. (상태 코드는 304 Not Modified) 그리고 브라우저는 캐시의 데이터를 재사용한다.

  • 이때, 클라이언트는 서버의 캐시 로직을 알 수 없다.

🍪 Cache-Control의 값

  • max-age는 캐시 유효 시간 (초단위)를 의미한다.

  • no-cache는 데이터는 캐시를 해도 되지만, 항상 origin 서버에서 검증하고 사용되야 함을 의미한다.

  • no-store는 데이터에 민감한 정보가 있으니, 저장하지 않고 메모리에서만 빨리 사용하고 지우는 것을 의미한다.

  • Expires 속성으로 캐시 만료일을 정확한 날짜로 지정할 수도 있다.

🍙 프록시 캐시 (Proxy Cache)

  • 프록시 서버는 서버와 클라이언트 사이에서 대리(중계 기능)로 통신을 하는 서버를 의미한다.

  • 클라이언트나 서버가 다른 네트워크에 간접적으로 접속할 수 있기에 보안, 캐싱을 통한 성능, 트래픽 분산 등의 장점이 있다.

  • 서버와 클라이언트 중간에 프록시 캐시 서버를 통해서 많은 요청이 온 데이터를 캐시에 등록하여 빠르게 응답할 수 있다.

🍩 이는 Origin 서버에 응답을 보내고 응답을 받는 것 보다 빠르다.

  • 이때 클라이언트에서 사용하고 저장하는 캐시를 private 캐시라 하고, 프록시 캐시 서버의 캐시를 public 캐시라고 한다.

  • 프록시 캐시 서버와 관련된 헤더로 Cache-Control: public, Cache-Control: private, Cache-Control: s-maxage, Age: 60 등이 있다.

  • 클라이언트가 캐시를 저장하지 않아도 브라우저에서 임의로 캐시를 저장할 수 있는데, 이 경우 민감한 데이터를 캐시에 저장하지 못하도록 하는 방법으로 캐시를 무효화 하는 헤더를 사용한다.

🍚 Cache-Control: no-cache, Cache-Control: no-store, Cache-Control: must-revalidate, Pragma: no-cache

  • 확실히 캐시를 무효화하고자 한다면, 위의 캐시 지시어를 모두 사용한다.

  • no-cache와 must-revalidate 모두 origin 서버에 검증해야 하지만 그에 대한 응답에 대해 다른 점이 있다.

🍚 no-cache의 경우 캐시 서버 요청을 하면, 프록시 캐시 서버에서 origin에 요청을 하고 origin 서버에서 검증 후 304 응답을 한다.

🍚 프록시 캐시 서버와 origin 서버의 연결이 단절된 상태라면, 오류를 응답하지 않고 오래된 데이터를 보여주는 응답을 보낸다. (200OK)

🍚 반면, must-revalidate의 경우 origin 서버에 접근이 불가할 때 504 Gateway Timeout 오류를 보낸다.
🍚 통장 잔고 등 중요한 정보가 Origin 서버를 못 받았다고 해서 예전 데이터로 뜬다면 큰 문제가 생기기 때문에 이런 경우 must-revalidate를 써야 된다.

참고 자료 출처 : 코드 스테이츠

profile
🙌🙌🙌🙌

0개의 댓글