본문 바로가기
CS/HTTP

HTTP 캐시

by 29살아저씨 2025. 10. 31.
반응형

💡 캐시란?

캐시는 자주 쓰이는 웹 리소스(문서, 이미지 등)의 사본을 자동으로 보관하는 HTTP 장치

웹 브라우저나 프락시 서버 같은 중간 지점에서 사본을 저장했다가, 이후 같은 요청이 들어왔을 때 원 서버 대신 응답을 제공하는 역할을 함

 

캐시의 역할?

1. 불필요한 데이터 전송을 줄여서, 네트워크 요금을 절약

2. 대역폭을 늘리지 않고도 페이지를 빨리 불러올 수 있게 하여 네트워크 병목을 줄여줌

3. 원 서버에 대한 요청을 줄여서 부하를 줄이고, 더 빠른 응답처리가 가능하게 해줌

4. 거리로 인한 지연을 줄여줌

 

캐시가 성능을 개선하고 비용을 줄이는 방법

7.1 불필요한 데이터 전송 최소화

다수의 클라이언트가 같은 문서에 접근할 때, 캐시가 없다면 서버는 모든 클라이언트에게 동일 문서를 각각 전송해야 함

캐시를 이용하면, 첫 번째 응답은 캐시에 보관되고, 뒤이은 요청에 대해서는 캐시가 응답을 대신 처리함으로써 원 서버 트래픽 낭비를 현저히 줄여줌

 

7.2 대역폭 병목 해소

클라이언트의 서버 접근 속도는 경로상의 가장 느린 네트워크 속도와 같음

빠르고 가까운 LAN 캐시로부터 사본을 가져온다면, 네트워크 병목을 우회하여 성능을 대폭 개선 가능

 

7.3 갑작스런 요청 쇄도 대처

많은 사용자가 동시에 특정 웹 문서에 접근할 때 트래픽 급증으로 심각한 장애가 야기시킴

캐시는 이러한 갑작스러운 요청 쇄도에 효과적으로 대처하여 서비스 안정성을 유지하는 핵심 장치임

 

7.4 거리로 인한 지연

 

대역폭 문제가 없더라도, 데이터가 물리적 거리를 이동하며 발생하는 전파 지연은 피할 수 없음

모든 네트워크 라우터와 빛의 속도 제한으로 인해 유의미한 지연(Latency)이 발생하며, 캐시는 사용자와 가까운 위치에서 응답함으로써 이 지연을 최소화

 

7.5 적중과 부적중

캐시는 세상 모든 문서의 사본을 저장하지 않음.

  • 캐시 적중 (Cache Hit): 요청에 대응하는 사본이 캐시에 있을 때. 캐시가 바로 응답을 처리함.
  • 캐시 부적중 (Cache Miss): 대응하는 사본이 캐시에 없을 때. 요청은 원 서버로 전달됨.

HTTP 재검사 (Validation)

원 서버의 콘텐츠는 변경될 수 있기 때문에, 캐시는 보유 중인 사본의 신선도를 주기적으로 검사

서버 변경이 없으면 캐시된 데이터를 그대로 사용하고, 변경 시 새로 받아옴

 

 

재검사가 필요할 때 : 원 서버에 재검사 요청을 보냄 -> 콘텐츠가 변경되지 않음 -> 서버에서는 304 Not Modified 응답을 보냄 -> 캐시는 데이터가 신선하다고 판단 -> 클라이언트에게 캐시된 데이터를 그대로 전달

 

가장 많이 쓰이는 재검사 방식 : If-Modified-Since 헤더

클라이언트가 GET 요청 시 If-Modified-Since 헤더를 함께 전송함.
서버는 아래 세 가지 중 하나로 응답함.

  1. 304 Not Modified → 변경 없음, 캐시 데이터 그대로 사용
  2. 200 OK → 콘텐츠 변경, 새 데이터 다운로드
  3. 404 Not Found → 삭제됨, 캐시 사본 삭제

캐시 성능 지표

적중률

캐시 적중률 : 캐시가 요청을 직접 처리한 비율임.

  • 0% → 모든 요청을 원 서버에서 가져옴
  • 100% → 모든 요청을 캐시에서 처리함

40% 정도의 적중률이면 웹 캐시로 괜찮은 편으로 판단.

 

바이트 적중률

바이트 적중률 : 캐시를 통해 제공된 모든 바이트의 비율을 표현

  • 문서 적중률 개선 → 대기시간 단축
  • 바이트 적중률 개선 → 대역폭 절감 극대화

100% -> 모든 바이트가 캐시에서 왔으며, 어떤 트래픽도 서버로 나가지 않았음을 의미

 

 

적중과 부적중의 구별

HTTP는 클라이언트에게 응답이 캐시 적중이였는지, 원서버 접근이였는지 말해줄 수 있는 방법이 없음

주로 응답 헤더의 Date 값을 현재 시각과 비교하여, 응답 생성일이 더 오래되었다면 캐시에서 온 응답임을 판단

 

7.6 캐시 토폴로지

캐시는 개인용과 공용으로 나뉨.

  • 개인 전용 캐시 : 브라우저 내부 캐시. 자주 쓰는 문서를 디스크나 메모리에 저장함.
  • 공용 프록시 캐시 : 여러 사용자가 공유함. 캐시 서버가 로컬 사본 제공 또는 원 서버에 요청 보냄.

프락시 캐시 계층

작은 캐시에서 부적중 발생 시, 더 큰 부모 캐시가 요청 처리함.
하위엔 사용자 근처의 빠른 캐시, 상위엔 다수 사용자 공유 캐시 배치함.
계층 구조로 효율적 트래픽 분산 가능함.

 

Q. 어떻게 캐시가 다른 캐시나 서버와 상호작용 하는지?

A. 캐시망, 콘텐츠 라우팅, 피어링

단순 계층형보다 진보된 형태로, 여러 캐시 서버를 연결한 캐시망(Cache Mesh)

  • URL 기준으로 부모 캐시 또는 원 서버를 동적으로 선택
  • 요청 전 로컬 캐시 사본 탐색
  • 다른 캐시와 콘텐츠 공유 (피어링)

이러한 방식은 서로 다른 조직들이 상호 이득을 위해 서로 다른 조직 간 캐시 공유로 효율성 극대화

 

7.7 캐시 처리 단계

웹 캐시의 기본적인 동작은 아래와 같음 (HTTP GET 메시지 기준)

 

  1. 요청 받기: 네트워크 커넥션을 감지하고 데이터를 읽어 들임.
  2. 파싱: 요청 메시지를 파싱하여 헤더를 자료구조에 담음.
  3. 검색: URL에 해당하는 로컬 사본이 있는지 확인함.
  4. 신선도 검사: 캐시된 콘텐츠 제공 전에 변경 여부를 서버와 재검사함.
  5. 응답 생성: 캐시된 서버 응답 헤더를 토대로 클라이언트 응답 헤더를 생성함. (Date 헤더는 조정하지 않아야 함.)
  6. 전송: 응답 헤더와 바디를 클라이언트에게 돌려줌.
  7. 로깅: 캐시 적중/부적중, 요청 종류, URL 등 정보를 로그로 작성함.

 

7.8 사본을 신선하게 유지하기

HTTP는 문서 만료서버 재검사라는 단순한 메커니즘을 통해 캐시된 사본이 서버와 일치하도록 유지

 

문서 만료

 

- Cache-Control, Expires라는 특별한 헤더를 이용해 서버가 각 문서에 유효기간을 붙일 수 있게 함

- 캐시 문서가 만료되면 반드시 서버에 문서 변경 여부를 검사해야 하며, 변경 사항이 있다면 새 유효기간과 함께 신선한 사본을 얻어와야 함

 

유효기간과 나이

- Cache-Control, Expires를 통해 유효기간을 명시

- 둘 다 같은 역할을 하지만, Expires는 절대 시간을 사용하므로 컴퓨터 시계가 올바르게 맞춰져 있어야 함

- 클라이언트 요청 시 캐시의 유효시간이 경과했다면 서버를 통해 신선한 사본을 얻어와야 함

 

서버 재검사

캐시가 원 서버에게 문서가 변경되었는지 여부를 물어볼 필요가 있음을 의미

  • 콘텐츠 변경됨 → 새 사본 가져와 저장 후 클라이언트에게 전달
  • 콘텐츠 변경 없음 → 새 만료일이 포함된 새 헤더만 갱신

조건부 메서드와의 재검사

HTTP는 캐시가 서버에 조건부 GET 요청을 보낼 수 있도록 지원
조건부 GET은 GET 요청에 특정 헤더를 추가해, 조건이 참일 때만 객체를 반환

  • If-Modified-Since : 문서가 특정 날짜 이후 수정된 경우만 처리
  • If-None-Match : 문서의 일련번호(ETag)를 기반으로 변경 여부 판단

If-Modified-Since : 날짜 재검사

가장 일반적인 캐시 재검사 방식

  • 주어진 날짜 이후 수정됨 → 200 OK, 새 문서와 새 만료일 포함
  • 변경 없음 → 304 Not Modified, 새 만료일만 반환

If-None-Match : 엔터티 태그 재검사

어떤 서버는 페이지 변경일을 정확히 판단하기 어려움. 이럴 때 엔터티 태그(ETag)를 사용

 

예를 들어, 캐시가 v2.6 버전을 가지고 있다면 원 서버에 “v2.6이 아니면 새 객체를 달라”고 요청
캐시가 여러 사본을 가질 수 있으므로, If-None-Match 헤더에 여러 ETag를 포함할 수도 있음

 

약한 검사기와 강한 검사기

리소스 변경 여부를 판단하는 두 가지 방식

  • 강한 검사기 (Strong ETag) : 단 1비트라도 바뀌면 ETag 값이 변경됨.
  • 약한 검사기 (Weak ETag) : 의미상 동일한 경우 ETag를 변경하지 않음.

예시) HTML 본문은 그대로인데, 헤더 타임스탬프나 카운터만 바뀐 경우 → 약한 ETag 유지 가능.
서버는 W/ 접두어로 약한 ETag 표시함. (예: W/"weak-hash-B")

 

 

언제 엔터티 태그를 사용하고, 언제 Last-Modified 일시를 사용하는가?

 

- 서버가 ETag 제공 시 → 반드시 ETag 검사기 사용

- 서버가 Last-Modified만 제공 시 → If-Modified-Since 사용 가능

- 두 조건이 함께 존재할 때 → 둘 다 충족하지 않으면 304 Not Modified 반환 불가

 

 

7.9 캐시 제어

no-cache와 no-store 응답 헤더

  • no-cache : 캐시 저장은 가능하지만, 사용 전 반드시 서버 검증 필요
  • no-store : 절대 저장 금지. 서버, 프록시, 브라우저 모두 캐싱 금지

Max-Age 응답 헤더

- 문서가 서버에서 온 이후 경과한 시간 지정
- max-age=0 설정 시 매 요청마다 서버에 재검사 수행

 

Expired 응답 헤더

실제 만료 날짜를 명시. 절대시간 기반

 

Must-Revalidate 응답 헤더

캐시가 만료된 후 서버 접근이 불가능하면 504 Gateway Timeout 발생
즉, 만료된 리소스는 재검증 없이는 절대 제공 불가하게 강제함. 매우 중요!

 

휴리스틱 만료

서버가 유효기간을 명확히 지정하지 않았을 때 캐시가 자체 판단으로 추정하는 방식임.

일반적으로 Last-Modified 헤더를 기반으로 추정함.

  • Last-Modified : 서버가 리소스를 마지막으로 수정한 시각 표시

7.10 캐시 제어 설정

웹 서버(Apache, Nginx 등)에서 캐시를 제어하는 목적은 클라이언트와 프록시/CDN이 어떤 리소스를 얼마나 오랫동안 저장하고,

언제 서버에 유효성 재검사를 해야 하는지 정확히 알 수 있게 하기 위함

핵심은 Cache-Control, Expires, ETag, Last-Modified 등의 헤더를 적절히 설정하는 것

 

7.11 자세한 알고리즘

문서의 나이(Age)신선도(Freshness Lifetime) 계산 알고리즘

 

나이와 신선도 수명

캐시된 문서가 충분히 신선한지 알려주려면, 캐시는 단 두가지 값만 계산하면 됨

- 캐시된 사본의 나이 : 서버가 문서를 보낸 후 그 문서가 '나이를 먹은' 시간의 총합

- 신선도 수명 : 문서의 유효기간과 신선도에 영향을 주는 클라이언트의 모든 요청을 고려 하여 신선하다고 볼 수 있는 수명

 

나이 계산

응답이 서버에서 생성되었을 때 부터 지금까지의 총 시간

캐시는 응답이 캐시에 도착했을 때 Date나 Age 헤더를 분석해서 얼마나 오래된 것인지 알 수 있음

 

1. 점층적 나이 계산

모든 서버가 동기화된 시계를 갖고 있지 않은 문제 등을 해결하기 위한 우회책임.

- 문서가 프락시나 캐시를 통과할 때마다 그 장치들이 Age 헤더에 상대적인 나이를 누적해서 더하도록 함.

- Age 헤더 값은 프락시들을 통과하면서 점점 늘어남.

 

2. 네트워크 지연에 대한 보상

느린 네트워크나 과부하 서버에서는 실제보다 적게 계산될 수 있음.
HTTP/1.1에서는 요청 시각과 도착 시각을 기준으로 왕복 지연시간(RTT) 을 보정하여 더 정확한 나이 계산이 가능함.

 

완전한 나이 계산 알고리즘

문서가 캐시에 얼마나 머물렀는지 계산함.

  • 캐시에 머문 시간 = (클라이언트 요청 시각) - (문서가 캐시에 도착한 시각)

신선도 수명 계산

신선도 수명은 서버와 클라이언트의 제약조건에 의존

- 매우 안정된 서류철 보고서는 수년동안 신선한 상태

- 정기 간행물이라면 남아있는 시간동안 신선한 상태

 

반응형

'CS > HTTP' 카테고리의 다른 글

HTTP 엔터티와 인코딩  (0) 2025.11.21
보안 HTTP  (0) 2025.11.14
HTTP 웹 서버  (0) 2025.10.16
HTTP 커넥션 관리 (TCP/IP)  (0) 2025.10.10
HTTP와 URL, 그리고 앱 커스텀 스킴 경험  (0) 2025.09.15

댓글