HTTP에서의 캐시와 헤더, CDN (작성중)
캐시가 없을 때의 상황이다.
클라이언트가 logo.jpg 이미지에 대한 요청을 보내고 서버가 해당 이미지에 대한 응답을 줄 때, HTTP 헤더가 0.1M, 바디가 5.0M로 총 5.1M로 가정해보자.
만약 브라우저를 F5 (리프레시)해서 다시 서버에 같은 이미지를 요청한다면 브라우저는 다시 똑같이 5.1M의 이미지를 서버로부터 받아야한다. 이 경우 받는 이미지가 변경되지 않아도 다시 5.1M를 서버로부터 받아와야 한다.
그러면 다음과 같은 문제점이 생긴다.
- 데이터가 변경되지 않아도 계속 다운로드를 받기에 데이터 소모가 크다. 또한 서버에도 부담이 된다.
- 인터넷 네트워크는 매우 느리고 비싸다.
- 브라우저의 로딩 속도가 느려져 좋지 못한 사용자 경험을 제공한다.
브라우저가 다시 이미지를 서버로부터 받지 않아도 되는 방법이 없을까?
이는 캐시를 통해 해결할 수 있다. 캐시는 컴퓨터 과학에서 데이터나 값을 미리 복사해 놓는 임시 장소를 가리킨다. 캐시는 캐시의 접근 시간에 비해 원래 데이터를 접근하는 시간이 오래 걸리는 경우나 값을 다시 계산하는 시간을 절약하고 싶은 경우에 사용한다.
캐시에 데이터를 미리 복사해 놓으면 계산이나 접근 시간 없이 더 빠른 속도로 데이터에 접근할 수 있다.
캐시 적용
브라우저에서 캐시를 사용하는 방법으로는 HTTP 헤더에 cache-control 속성을 설정하여 캐시의 유효 시간을 설정하는 방법이 있다. 만약 60초로 설정한다면 60초동안은 서버의 리소스 대신 해당 캐시를 사용한다는 의미가 된다.
만약 캐시 시간이 초과했다면, 서버로부터 다시 다운로드가 발생하고 다시 캐시를 갱신한다.
캐시 검증 헤더와 조건부 요청
위에서 보면 캐시의 유효시간이 경과하면 서버로부터 다시 같은 파일을 다시 다운받아야 했다. 그런데 유효시간이 지났다하더라도 파일에 대해 변경사항이 없다면 기존 브라우저의 캐시파일을 사용하고 싶을 것이다.
변경사항이 있는 지 확인하는 수단으로 검증 헤더의 Last Modified 값을 확인할 수 있다.
브라우저는 캐시에 있던 파일에 대해서 다시 서버에 요청할 때에 헤더에 Last Modified를 같이 전달하는데, 이는 데이터의 마지막 수정된 시간에 대한 정보를 가지고 있다. 서버는 해당 정보를 보고 서버에 있는 파일의 수정된 시간과 동일하다면 '브라우저에 있는 기존 캐시 파일과 동일하다는 상태코드 304 Not Modified'를 응답으로 전달한다. 기존 캐시 파일을 사용하면 되므로 서버는 파일을 전달하지 않고 헤더만 전달한다.
- 요점 정리
- 캐시의 유효 시간이 지났다하더라도 서버의 데이터가 달라지지 않았다면
- 304 Not Modified + 헤더에 메타 데이터만 응답 (payload 미전달)
- 클라이언트는 서버로부터 받은 응답헤더의 정보로 캐시의 메타데이터를 갱신
- 클라이언트는 캐시 정보를 재활용
- 결국 네트워크 다운로드는 발생했으나 용량이 적은 헤더정보만 다운받아도 됨
- 매우 실용적인 해결방안이다.
- 캐시의 유효 시간이 지났다하더라도 서버의 데이터가 달라지지 않았다면
Last Modified 를 통한 캐시 처리의 단점
- 서버의 데이터가 날짜만 달라진 경우에는 캐시 재활용이 안됨
- 서버에서 별도로 캐시 로직을 관리하고 싶을 경우
- e.g 스페이스나 주석 등을 수정하여 로직에는 영향이 없어 기존 캐시로 유지하고 싶을 때
Last Modified 에서의 단점에 대한 대응 방법
ETag (Entity Tag) 와 if-None-Match 검증헤더 적용
- 캐시용 데이터에 개발자가 임의의 고유 버전을 태그로 달아둘 수 있다.
- e.g ETag: "v5.0" , ETag "dafsf3352fer325253"
- 데이터 변경을 원할 때에 ETag값을 변경함
- e.g ETag: "524fas52" => "fdsfwfwef" (보통 해시값으로 생성)
- 단순하게 ETag가 같으면 캐시값 사용, 다르면 다시 다시 받음.
- 장점: 캐시 로직을 서버가 완전히 관리할 수 있다.
- Cache-Control
- max-age : 캐시 유효시간, 초단위
- no-cache: 캐시는 가능하나 항상 원 서버에서 검증 후 사용
- no-store: 데이터에 민감한 정보가 있어 저장하면 안됨 (메모리에서 사용 후 최대한 빠르게 삭제)
- Expires
- 캐시 만료일 지정
- 지금은 더 유연한 max-age 를 권장하며, Cache-Control: max-age 와 같이 사용 시 Expire는 무시됨.
CDN (Content Delivery Network)
- 기능
- 콘텐츠를 좀 더 빠르고 효율적으로 제공
- e.g ) 세계 곳곳에 분포하는 데이터센터에 동일한 콘텐츠를 저장해둔 뒤, 이후 콘텐츠 요청을 받으면 요청을 한 대상과 가장 가까이에 있는 데이터 센터에서 콘텐츠를 제공해주는 방식입니다. 따라서 속도가 빠르고 가장 가까운 캐시 서버가 응답처리 우선 순위를 가지게 됩니다. 예를 들어 원본 서버가 미국에 있고 CDN 서버가 중국과 캐나다에 있다고 가정해보자면, 한국에 있는 사용자는 서버의 정보를 얻어올 때에 지리적으로 가장 가까운 중국 CDN 서버에서 콘텐츠를 받아올 수 있어 빠른 속도를 제공받을 수 있게 됩니다.
- 콘텐츠를 좀 더 빠르고 효율적으로 제공
- 장점
- DDos 공격에 어느정도의 대응이 가능
- DDos 공격은 서버의 수용량보다 훨씬 많은 요청을 보내 서버를 사용 불가능하게 만드는데, 만약 DDos공격으로 특정 CDN 데이터센터가 불가능하게 되었다해도 다른 CDN 서버가 그 업무를 대신 할 수 있기에 서버는 정상적으로 돌아갈 수 있습니다.
- 로딩 속도 감소로 인한 사용자 경험 향상
- 트래픽 분산으로 인한 트래픽 관련 비용 절감
- DDos 공격에 어느정도의 대응이 가능
- 정적인 타입의 콘텐츠에 적합
- 정적인 정보들인 영상, HTML, 이미지 등은 변화가 거의 없는 정보들이기 때문에 CDN 서버에 저장하는 것이 적합합니다.
동적인 컨텐츠의 경우에는 보통 적합하지 않습니다. 빈번하게 정보가 바뀌어서 원서버에서 CDN 서버에 정보를 캐시해놓더라도 활용하기 어렵기 때문입니다.
- 정적인 정보들인 영상, HTML, 이미지 등은 변화가 거의 없는 정보들이기 때문에 CDN 서버에 저장하는 것이 적합합니다.
- 네트워크 구성 방법
- Scattered 방식
- 최대한 낮은 응답 시간에 집중
- Scattered 방식