웹 캐싱이란
웹사이트를 그리기 위해서는 서버에게 웹사이트를 구성하는 리소스를 요청하게 된다. 이 웹 리소스들을 가져오는데 시간이 오래걸리거나, 리소스의 크기가 크거나, 요청하는 사람이 많다면 웹사이트를 표시하는 데 시간이 더 걸리게 될 것이다. 웹 리소스를 로드하는 중 네트워크에서 발생하는 이런 문제들을 웹 캐싱으로 해결할 수 있다.
웹 캐싱은 웹 리소스를 제공하는 원서버까지 가서 리소스를 요청하기 이전에 임시 저장소에 보관하여, 이후 동일한 요청이 발생했을 때 더 빠르게 해당 리소스를 제공하는 기술이다. 비유하자면 사용해아할 자료들이 도서관에 있다고 할 때, 필요할 때마다 도서관에 가지 않고 한 번 빌려온 후 집 가까운 곳에 두고 사용하는 것이다.
캐싱의 주요 장점
- 성능 향상: 캐시된 리소스는 네트워크 왕복 시간을 줄여 빠른 응답을 제공한다.
- 서버 부하 감소: 동일한 데이터를 원서버가 반복적으로 요청받는 대신, 캐시에서 요청받고 제공함으로써 서버의 처리 부담을 줄인다.
- 대역폭 절약: 동일한 데이터가 네트워크 내에서 오가는 양을 줄여 대역폭을 절약한다.
- 사용자 경험 개선: 페이지 로딩 속도가 빨라져 사용자 만족도가 증가한다.
이런 웹 캐싱의 장점을 잘 활용하기 위해 캐싱이 일어나는 절차와 설정 방법에 대해 알아보며 기록했다.
캐싱 위치
그 임시 저장소는 어디에 위치할 수 있을까? 캐싱을 적용할 수 있는 위치는 다양하며, 각 위치에 따라 캐시는 한 명의 사용자에게만 할당될 수도 있고 반대로 여러 사용자들 간에 공유될 수 있다. 각각 개인 전용 캐시(private cahce), 공용 캐시(public cache)로 구분해 부른다.
클라이언트 측 캐싱 (개인 전용 캐시)
- 브라우저 캐시: 사용자 디바이스에 리소스를 저장하여 동일한 리소스 요청 시 재사용한다.
중간 계층 캐싱 (공용 캐시)
공용 캐시에는 여러 사용자가 접근하기 때문에 불필요한 네트워크 트래픽을 줄일 수 있는 기회가 있다.
- CDN 캐시: 콘텐츠 전송 네트워크(CDN)에서 리소스를 캐싱하여 사용자의 지리적 위치에 가까운 서버에서 데이터를 제공한다. 이는 마치 세계 각지에 책 복사본을 배포하여 가까운 도서관에서 빌릴 수 있도록 하는 것과 같다.
- 프록시 캐시: 프록시(Proxy)는 클라이언트와 원 서버 사이의 중개자로서, 원 서버를 대신하여 클라이언트의 요청을 받고 응답하는 역할을 한다. 프록시는 로컬에 캐싱된 문서를 제공하거 프록시가 대신 사용자 입장에서 서버에 접근해 리소스를 제공할 수 있다.
캐시 처리 단계
캐싱된 리소스를 사용할지 여부는 어떻게 판단하는 것일까? 기본적으로 웹 캐시 처리 절차는 아래와 같은 단계로 진행된다.
- 리소스 요청
- 검색 - 로컬 복사본이 있는지 검사하고, 사본이 없다면 사본을 받아온다. (그리고 로컬에 저장한다.)
- 신선도 검사 - 캐시가 일정 기간동안 서버 리소스의 사본을 보유할 수 있는 시간 동안 문서는 '신선'한 것으로 간주되고, 서버와의 접촉없이 이 문서를 제공한다. 이 기간을 넘으면 캐시는 리소스 제공 전에 리소스에 변경이 있었는지 확인하기 위해 서버와 재검사를 거쳐야 한다.
- 서버와 재검사 - 신선하지 않다면 변경사항이 있는지 서버에게 물어본다.
- 서버에서의 재검사를 통과했다면 캐시된 문서의 신선도를 갱신한다.
- 통과하지 않았다면 서버에서 신선한 문서를 새로 가져와 캐시에 저장한 후 제공한다.
프록시 캐시 같은 중간 계층 캐시에서는 HTTP 요청을 파싱하고 응답 헤더를 재생성하는 과정 등 기타 과정이 추가되나, 위 절차는 비슷하게 포함된다.
HTTP 헤더의 역할
캐시된 사본을 사용할지 판단하는 데 사용되는 신선도는 어떻게 판단할 수 있을까? 사본에 변경사항이 있는지 서버에서 어떻게 확인할 수 있을까? 이는 HTTP 헤더를 통해 관리된다. 서버가 클라이언트에 응답을 보낼 때 캐시 관련 HTTP 헤더를 보내면, 클라이언트 또는 다른 중간 계층 캐시에서 캐시를 관리할 때 해당 헤더를 사용한다.
만료 판단에 사용하는 헤더 (Caching Headers)
리소스의 캐시 여부, 신선도를 결정하는 시간에 대한 정보를 포함한다. 캐시는 이를 통해 사본을 저장할지, 저장된 사본이 신선한지를 판단한다.
- cache-control: 캐싱 정책을 명시하는 주요 헤더로, 리소스의 캐시 가능 여부와 유효 기간을 정의한다.
- private: 개인 전용 캐시에만 캐시될 수 있음을 의미하며, 오직 클라이언트나 브라우저에서만 저장된다.
- public: 리소스가 여러 사용자와 공유될 수 있음을 나타내며, 프록시 캐시 등 공개적으로 캐시될 수 있다.
- no-cache: 리소스를 캐시하되, 매 요청마다 서버에서 유효성을 확인한다.
- no-store: 리소스는 캐시되지 않으며, 클라이언트는 매번 서버에 새로 요청해야 한다
- max-age: 클라이언트가 특정 초 동안 캐시할 수 있음을 알려준다.
- ex) cache-control: max-age=3600 -> 60분 동안 콘텐츠를 캐시할 수 있음을 뜻한다.
- s-max-age: 공유된 캐시에 적용되는 max-age이다. max-age와 함께 있을 경우 개인 전용 캐시에는 max-age, 공용 캐시에는 s-max-age가 적용된다.
- must-revalidate: 서버에 연결할 수 없는 경우 또는 네트워크 문제가 있는 경우 해당 값이 설정되어있지 않으면 만료된 사본 리소스를 사용할 수 있다. 만약 must-revalidate 값이 설정되면 서버가 접근 불가능하더라도 클라이언트는 만료된 캐시 리소스를 사용해선 안 되며, 반드시 서버에서 새로 확인해야 한다
- proxy-revalidate는 must-revalidate와 동일하며 프록시에서 캐시된 리소스에 적용된다. 클라이언트가 인터넷에 연결되어 있지 않거나 네트워크 문제가 있는 경우 클라이언트에 저장된 만료된 리소스는 계속 제공할 수 있지만, 프록시에 연결할 수 있고 프록시에 만료된 리소스가 있는 경우 프록시는 만료된 리소스를 사용할 수 없고 원 서버에서 가져와야 한다
- 위 값들을 조합해 원하는 캐시 제어 정책을 설정할 수 있다.
- ex) Cache-Control: max-age=3600, s-max-age=600, public, must-revalidate
- 응답에 위 헤더가 포함되어 있다면
- -> 개인 전용 캐시에는 1시간 동안, 중간 계층 캐시에서는 10분동안 리소스가 신선한 걸로 판단한다. must-revalidate 가 있으므로 리소스가 만료될 때엔 서버에서 새로운 콘텐츠를 가져와 제공해야 한다.
- ex) Cache-Control: max-age=3600, s-max-age=600, public, must-revalidate
- expires: 리소스의 유효기간을 명시적으로 설정한다. 이 값은 1년을 초과할 수 없고 유효하지 않은 값이 제공될 경우 만료되었다고 간주한다.
- expires는 HTTP/1.1 이전에 사용된 헤더로 현재는 많이 사용하지 않으며, cache-control로 대체 가능하다.
서버 재검사에 사용하는 헤더 (Cache Validation)
캐시된 리소스가 만료되었다는 것은 그 문서가 원 서버에 현재 존재하는 것과 다르다는 것을 의미하지는 않으며, 검사할 시간이 되었음을 뜻한다. 이 검사는 캐시가 원 서버에게 리소스가 변경되었는지의 여부를 물어볼 필요가 있음을 의미하는 '서버 재검사'라고 부른다.
- 재검사 결과 리소스가 변경되었다면, 캐시는 새로운 사본을 가져와 오래된 데이터 대신 저장한 뒤 클라이언트에게도 보내준다.
- 변경되지 않았다면, 캐시는 새 만료일을 포함한 새 헤더들만 가져와서 캐시 안의 헤더들을 갱신한다.
아래는 재검사에 사용되는 사용되는 헤더의 종류 및 설명이다.
- ETag: 리소스의 고유 식별자로 응답 헤더에 포함된다
- If-None-Match: 클라이언트는 ETag를 사용하여 서버에 콘텐츠 변경 여부를 확인한다. 이 요청은 변경사항이 있는 경우에만 리소스를 보내달라고 하는 것이다.
- ex)
- server 응답 헤더
- Cache-Control: max-age=3600 Public
- ETag: "1234"
- client 요청 헤더
- if-none-match: "1234"
- 이 예시에서 클라이언트는 1시간 동안 해당 캐시 리소스를 계속 사용하고, 1시간이 지나면 클라이언트는 if-none-match 헤더를 사용하여 서버로 리소스의 ETag를 함께 전송한다. 서버 ETag를 비교해 새로 사용 가능한 리소스의 ETag와 일치하지 않으면 새 ETag와 새 리소스로 응답한다. ETag가 일치하면 변경사항이 없는 것으로 304 Not Modified 응답을 보낸다.
- server 응답 헤더
- HTTP/1.1은 콘텐츠가 조금 변경되었더라도 '그 정도면 같은 것'이라고 서버가 주장할 수 있도록 약한 검사기를(weak validator) 지원한다.
- 강한 검사기(strong validator)는 콘텐츠가 바뀔 때마다 바뀐다.
- 약한 검사기는 어느정도 콘텐츠 변경을 허용하지만 콘텐츠의 중요한 의미가 변경되면 함께 변경된다.
- 'W/' 접두사로 약한 검사기를 구분한다.
- ETag: W/"v2.6"
- If-None-Match: W/"v2.6"
- Last-Modified: 리소스가 마지막으로 수정된 시점을 표시한다.
- If-Modified-Since: Last-Modified 헤더와 함께 사용되며, 리소스가 Last-Modified 에 지정된 날짜 이후로 수정되었는지 서버에 확인한다. 여기에 기재된 날짜 이후로 변경이 있다면 새로운 응답을, 변경사항이 없다면 304 Not Modified 응답을 보낸다.
- ETag, Last-Modified 두 헤더가 응답에 모두 있는 경우?
- 이 경우 클라이언트는검사 요청에 If-None-Match, If-Modified-Since를 모두 전송한다. 서버는 둘 다 확인하여 304를 반환하거나 새 리소스를 반환한다.
- ETag, Last-Modified 둘 다 응답 헤더 에 없는 경우
- 리소스가 만료되면 원 서버에 바로 새로운 리소스를 요청하게 된다.
참고 자료 출처
https://www.youtube.com/watch?v=HiBDZgTNpXY&t=812s
Gourley, D., & Totty, B. (2015). HTTP 완벽 가이드 (이응준, 정상일 역). 인사이트. (원서 출판 2002)
https://www.yes24.com/Product/Goods/15381085
HTTP 완벽 가이드 - 예스24
웹 세상을 떠받치고 있는 HTTP에 대한 모든 것모든 성공적인 웹 트랜잭션 뒤에는, 웹 클라이언트와 서버가 문서와 정보를 교환하는 언어인 HTTP가 있다. HTTP는, 회사 인트라넷에 접근하거나 절판된
www.yes24.com