HTTP 완벽 가이드 - 7 캐시
2025/03/02
n°67
category : HTTP
☼
2025/03/02
n°67
category : HTTP

캐시는 자주 쓰이는 문서 사본을 자동 보관하는 HTTP 장치다. 웹 요청이 캐시에 도착했을 때. 캐시된 로컬 사본이 있다면, 그 문서는 원 서버가 아니라 그 캐시로부터 제공된다.
프론트 라이브러리들은 각자 사용하기 편한 인터페이스를 제공하지만, 근간에는 HTTP 캐시 디렉티브가 연관되어 기본적인 이해가 필요하다. Next.js의 최신 버전은 서버 측 fetch 함수의 오버라이드와 라우트 캐싱 설정 등 HTTP 캐싱 헤더와 관련된 네임스페이스를 사용한다.
불필요한 데이터 전송을 줄여 비용(요금)을 줄여줌.
네트워크 병목을 줄여줌. 대역폭을 늘리지 않고 페이지를 빨리 불러올 수 있게함.
원 서버로의 요청을 줄여줌. 서버 부하를 줄이고 더 빨리 응답할 수 있음.
거리로 인한 지연을 줄여줌.
여러 클라이언트가 자주 쓰이는 원 서버 페이지에 접근할 때, 복수의 사용자에게 같은 문서를 보냄.
똑같은 바이트가 네트워크를 통해 반복하여 이동함 -> 불필요한 데이터 전송
캐시를 사용하여 첫번째 서버 응답은 캐시에 보관 -> 뒤이은 요청에 캐시된 사본이 응답으로 사용됨
결과적으로 중복된 트래픽을 주고 받는 낭비를 줄일 수 있음
캐시는 앞서 살핀대로 네트워크 병목 또한 줄여준다.
많은 네트워크가 원격 서버보다 로컬 네트워크 클라이언트에 더 넓은 대역폭을 제공
클라이언트들이 원서버에 접근하는 속도는 그 경로의 가장 느린 네트워크 속도와 같음
빠른 LAN에서 캐시된 사본을 가져온다면 성능 개선이 가능
캐싱은 갑작스런 요청 쇄도에 대처하는데 중요하다.
요청쇄도: 갑작스런 사건(뉴스 속보, 스팸 등)으로 많은 사람이 거의 동시에 웹문서에 접근할 때 발생
요청쇄도로 불필요한 트래픽이 급증하여 네트워크, 웹서버에 장애가 발생할 수 있게됨
요청 쇄도에 대응할 수 있도록 캐시를 사용할 필요가 있음
클라이언트와 서버의 물리적인 위치 또한 응답 지연에 영향을 줄 수 있다
빛의 속도로 인한 지연이 발생할 수 있다. (실제 신호는 이보다 더 느려서 더 크다)
당연히 거리가 더 멀 수록, 이 지연은 더 커진다. 물리적인 위치 근처에 캐시를 사용해 이 지연을 낮출 수 있다.
캐시는 세상 모든 문서의 사본을 저장하지 않는다.
캐시에 요청이 도착했을 때, 이에 대응하는 사본이 있다면, 그 캐시를 사용해 요청이 처리된다.
이를 캐시 적중(cache hit)이라고 한다.
반대로 사본이 없다면 요청은 그대로 원서버에 전달된다. 이를 캐시 부적중(cache missed)라고 한다.
원 서버의 컨텐츠가 변경될 수 있다. 캐시된 사본과 서버의 컨턴츠가 동일한지 점검해야한다.
이러한 '신선도 검사'를 HTTP 재검사revalidation이라고 한다.
서버에서 해당하는 컨텐츠 전체를 가져오지 않고 신선도를 검사할 수 있다.
효율적인 재검사를 위해 특별한 요청 정의가 필요하다.
캐시는 캐시된 사본의 재검사를 위헤 원 서버에 아주 작은 재검사 요청을 보낸다.
HTTP는 캐시된 객체를 재검사하기 위한 도구를 제공한다.
If-Modified-Since 요청 헤더가 일반적으로 사용된다. GET 요청에 사용하며, 캐시된 시간 이후 변경된 경우에만 사본을 보낸다. [참조]([[Chapter 3 HTTP 메시지]])
재검사 이후 다음 3가지의 응답이 올 수 있다.
재검사 적중(느린 적중)
재검사 이후, 캐시가 변경되지 않을 시 304 Not modified 응답을 보낸다.
304를 받은 캐시는 여전히 유효한 캐시 사본임을 확인하고 이를 클라이언트에 제공한다.
원 서버와 검사를 하기 때문에 순수 캐시 적중보다 느리다.
캐시 부적중 보다 빠르다. 원 서버에서 데이터를 받을 필요가 없기 때문이다.
재검사 부적중
캐시된 사본과 서버 데이터가 다르다면, 서버는 컨텐츠 전체와 함께 평범한 HTTP 200 응답을 클라이언트에 보낸다
객체 삭제
서버 객체가 서버에서 삭제되었다면, 서버는 404 not found 응답을 보내고 캐시를 삭제한다.
캐시 적중률(캐시 적중비): 캐시가 요청을 처리하는 비율
얼마나 많은 웹 트랜잭션을 외부로 내보내지 않았는지 보여준다.
트랜잭션은 고정된 소요 시간을 포함하고, 지연될 수 있기 때문에 문서 적중률을 개선하면 전체 대기시간이 줄어든다.
적중률은 0~1까지의 값으로 되어있고 보통 %로 표현
0% 모든 요청이 캐시 부적중, 100%는 모든 요청이 캐시 적중
실제 적중률은 캐시가 얼마나 큰지, 캐시 사용자들의 관심사가 얼마나 비슷한지, 캐시된 데이터가 얼마나 자주 변경되거나 개인화되는지, 어떻게 캐시가 설정 되었는지에 따라 다르다.
예측은 어렵지만, 보통 40%면 준수한 적중률이다.
보통 크기의 캐시라도 자주 사용되는 문서를 충분히 캐시한다면, 트래픽을 상당히 줄이고 성능을 개선할 수 있다.
캐시는 유용한 컨텐츠가 캐시 안에 머무르도록 보장하기 위해 노력한다.
문서 적중률이라고도 불린다.
바이트 적중률: 바이트 단위의 캐시 적중률. 캐시를 통해 제공된 모든 바이트의 비율을 표현
얼마나 많은 바이트가 인터넷으로 나가지 않았는지 보여준다.
바이트 단위 적중률 개선은 대역폭 절약을 최적화한다.
문서가 모두 같은 크기는 아니기 때문에 적중률만으로 캐시가 효율적으로 사용되는지 알 수 없다.
바이트 적중률 100% = 모든 바이트가 캐시에서 왔으며, 어떤 트래픽도 인터넷으로 나가지 않았음
문서 적중률과 함께 유용한 캐시 지표이다.
HTTP는 클라이언트에게 응답이 캐시 적중인지 부적중인지 알려주지 않는다. 두 경우 클라이언트는 200 ok응답만 볼 것.
종종 프락시 캐시는 Via 헤더를 제공해 캐시 적중 여부를 알려주는 서비스도 있다.
Date 헤더를 이용해 캐시 여부를 알 수 있다.응답의 Date와 현재 시각을 비교하여, 응답 생성일이 더 오래되었다면, 캐시임을 알 수 있다.
또다른 방법으로 응답의 Age 헤더를 사용하는 것이다.
캐시는 한 명에게만 할당될 수도 있고, 수천 명의 사용자들간에 공유될 수도 있다. 한 명에게만 할당된 캐시를 개인 전용(private) 캐시라 하고, 공유된 캐시는 공용(public) 캐시라고 한다.
개인만을 위한 캐시. 한 명의 사용자가 자주 찾는 페이지를 담는다
많은 저장 공간을 필요로 하지 않아 작고 저렴할 수 있다.
브라우저는 개인 전용 캐시를 내장한다.
대부분의 브라우저는 자주 쓰이는 문서를 pc의 메모리에 캐시하고, 사용자가 캐시 사이즈와 설정을 할 수 있게 한다. 또한 브라우저가 캐시한 파일을 열어볼 수 있다
사용자 집단에게 자주 쓰이는 페이지를 담는다.
캐시 프록시 서버 혹은 프록시 캐시라 불리는 특별한 종류의 공유된 프록시 서버다.
프록시 캐시는 로컬 캐시에서 문서를 제공하거나, 사용자 입장에서 서버에 접근한다.
여러 사용자가 접근하기 때문에 트래픽을 줄일 수 있는 기회가 많다.
개인 전용 캐시는 캐시되지 않은 문서에 제각각 접근한다. 각 개인 전용 캐시는 같은 문서를 여러번 가져온다.
공용 캐시는 자주 찾는 객체를 단 한 번만 가져와 모든 요청에 공유된 사본을 제공해 트래픽을 줄인다.
프록시 캐시는 [앞서 살핀 프록시 규칙]([[Chapter 6 프록시]])을 따른다. 수동 프록시를 지정하거나, 자동설정 파일을 설정하여 브라우저가 프록시 캐시를 사용하도록 설정할 수 있다. 혹은 인터셉트 프록시를 사용해 브라우저 설정없이 HTTP 요청이 캐시를 통하도록 강제할 수 있다.
작은 캐시에서 캐시 부적중이 발생 시, 더 큰 부모 캐시가 '걸러 남겨진' 트래픽을 처리하도록 계층을 만들 수 있다.
클라이언트 주변에는 작고 저렴한 캐시를 사용하고, 계층 상단에는 많은 사용자가 공유하는 문서를 유지하는 것이다.
캐시 계층이 깊다면 요청은 캐시의 긴 연쇄를 따라가게 된다. 프록시 연쇄가 길어질 수록 각 중간 프록시는 성능 저하가 나타날 수 있다.
단순한 캐시 계층 대신 복잡한 캐시망을 만드는 방법
캐시망의 프록시 캐시는 서로 대화하여 캐시 커뮤니케이션 결정을 동적으로 내린다.
어떤 부모 캐시와 대화할 것인지, 요청이 캐시를 완전히 우회해서 바로 원서버로 가게 할 것인지 결정할 수 있다.
캐시망 안에서 컨텐츠 라우팅을 위해 설계된 캐시로 할 수 있는 일들
URL에 근거하여 부모 캐시와 원 서버 중 하나를 동적으로 선택
URL에 근거하여 특정 부모 캐시를 동적으로 선택
부모 캐시에 가기 전에 캐시된 사본을 로컬에서 찾아봄
다른 캐시들이 캐시된 컨텐츠에 부분적으로 접근을 허용하되, 캐시를 통한 인터넷 트랜짓을 허용하지 않기
캐시 사이의 관계는 서로 다른 조직들이 상호 이득을 위해 캐시를 연결하여 서로 찾아볼 수 있게 한다.
선택적인 피어링을 지원하는 캐시를 형제 캐시라고 부른다.
HTTP는 형제 캐시를 지원하지 않기 떄문에, 인터넷 캐시 프로토콜(ICP)나 하이퍼텍스트 캐시 프로토콜(HTCP)을 이용해 HTTP를 확장할 수 있다.
오늘날 상용 프록시 캐시는 복잡하다. 고성능이면서도 HTTP와 다른 기술의 고급기능을 지원하도록 만들어진다. 하지만 기본적인 웹 캐시의 동작은 단순하다. 다음 7 단계를 따른다.
요청받기 -> 파싱 ->검색 -> 신선도 검사 -> 응답 생성 -> 전송 -> 로깅
캐시는 네트워크로부터 도착한 요청 메시지를 읽는다.
캐시는 네트워크 커넥션에서의 활동을 감지하고, 들어오는 데이터를 읽어들인다.
고성능 캐시는 여러 개의 들어오는 커넥션으로부터 데이터를 동시에 읽고, 메시지 전체가 도착하기 전에 트랜잭션 처리를 시작한다.
캐시는 메시지를 파싱하여 URL과 헤더들을 추출한다.
요청 메시지를 여러 부분으로 파싱하고, 헤더 부분을 조작하기 쉬운 자료구조에 담는다.
캐싱 소프트워에는 헤더 필드를 처리하고 조작하기 쉽게 만들어준다.
캐시는 로컬 복사본이 있는 지 검사하고, 사본이 없다면 사본을 받아온다 (그리고 로컬에 저장)
URL을 알아내고, 그에 해당하는 로컬 사본이 있는지 검사한다.
로컬 복사본은 메모리, 디스크 혹은 근처 다른 컴퓨터에도 저장될 수 있다.
사본을 로컬에서 가져올 수 없다면, 캐시는 상황과 설정에 따라 원 서버나 부모 프록시에서 가져오거나 실패를 반환한다.
캐시된 객체는 서버 응답 본문과 원서버 응답 헤더를 포함하기 때문에 캐시 적중 동안 올바른 서버 헤더가 반환될 수 있다.
캐시된 객체는 객체가 얼마나 오랫동안 캐시에 머무르고 있었는지 알려주는 기록이나 얼마나 자주 사용되었는 지 등등 메타데이터를 포함한다.
캐시된 사본이 충분히 신선한지 검사하고, 신선하지 않다면 변경사항이 있는지 서버에 물어본다.
HTTP는 일정 기간동안 서버 문서의 사본을 보유할 수 있게 해준다.
이 기간 동안 문서를 '신선'하다고 간주하고, 캐시는 서버와의 접촉 없이 이를 제공한다.
캐시된 사본이 신선도 한계를 넘을 정도로 오래 보관되었다면, 문서에 변경이 있었는지 검사하기 위해 서버와 재검사revalidation을 해야한다.
캐시는 새로운 헤더와 캐시된 본문으로 응답 메시지를 만든다.
캐시된 응답을 원 서버에서 온 것처럼 보이게 하기 위해, 캐시는 캐시된 서버 응답 헤더를 토대로 응답 헤더를 생성한다.
이 base 헤더들은 캐시에 의해 수정되고 늘어난다.
캐시 (서버)는 클라이언트에 맞게 이 헤더를 조정할 책임이 있다.
ex) 클라이언트가 HTTP/1.1 응답을 기대하는데 서버가 1.0 응답을 반환했다면, 캐시는 반드시 헤더를 적절하게 번역해야한다.
캐시는 캐시 신선도 정보(Cache-Control, Age, Expires 헤더), 요청이 프록시 캐시를 거쳐갔으믈 알리기 위해 Via 헤더를 포함시켜야한다.
캐시는 Date 헤더를 조정해서는 안된다. Date 헤더는 원 서버와 최초로 응답 객체를 생성한 날짜를 가리키기 때문이다.
네트워크를 통해 응답을 클라이언트에 돌려준다.
응답 헤더까지 준비되면, 캐시는 응답을 클라이언트에 돌려준다.
프록시 캐시는 모든 프록시 서버와 마찬가지로 클라이언트와 커넥션을 유지할 필요가 있다.
선택적: 캐시는 로그파일에 트랜잭션에 대해 서술한 로그를 남길 수 있다.
대부분의 캐시는 로그 파일과 캐시 사용에 대한 통계를 유지한다.
각 캐시 트랜잭션 완료 이후, 캐시는 통계 캐시 적중과 부적중 횟수 등 관련 지표의 통계를 갱신하고, 로그 파일에 요청 종류 URL 등 어떤 일이 일어났는지 알리는 항목을 추가한다.
Squid fog, Netscape extended common log 포맷이 일반적이지만 많은 캐시 제품은 커스텀 로그를 허용한다.
캐시된 사본이 항상 서버 데이터와 일치하는 것은 아니다. 데이터에 변경이 있을 때 재검사를 진행하는 것을 알아봤다. 캐시가 오래된 데이터를 제공한다면 문제가 될 수 있다. 캐시 데이터는 서버 데이터와 일치하도록 관리해야한다.<...