✅ 캐시 방법
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. 로깅
✅ 캐시 사본 유효기간
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가 응답됨. 캐싱된 데이터 사용됨.
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 느슨하게 할 수 있다.
참고자료
'Cache-Control'이 필요한 이유
앱의 성능을 향상시키는 방법 중 하나인 캐시. 클라이언트에서 캐쉬를 하고, 서버에서 컨트롤이 가능한 Cache-Control에 대해서 알아봅니다.
www.blog-dreamus.com
'CS > 네트워크' 카테고리의 다른 글
HTTP완벽 가이드 3장 (0) | 2024.05.01 |
---|