웹풀스택 공부 중
HTTP Cache(캐시)란? 본문
HTTP Cache (캐시)
HTTP Cache란?
- 웹 성능 개선을 위함
- 매 요청에 따른 WB와 WS의 부하를 줄여준다
- WB: 이전에 받았던 응답을 저장 후, 매번 요청할시 저장해놓은 응답을 재사용하여 반환을 한다
- 결과적으로 결과 반환 비용 (시간 + 네트워크)를 줄일 수 있다
- 네트워크 트래픽 및 비용 감소
- 유저 경험 증진 (로딩 없이 바로 사용가능)
- 결과적으로 결과 반환 비용 (시간 + 네트워크)를 줄일 수 있다
- WS: 이전에 반환한 응답을 저장 후, 매번 요청 받을시 저장해놓은 응답을 재사용하여 반환한다
- 결과적으로 결과 생성 비용 (노동, 자원)을 줄일 수 있다
- 결과를 만드는 CPU나 Memory를 사용하지 않아도 된다
- 서버 자원을 사용하지 않지만 네트워크만 발생한다
- 어찌됬든 결과를 반환해야되니까
- 블특정 다수의 WB에게도 캐시된 자원 제공이 가능하다
- 물론 WB의 캐시는 WB의 유저만 활용 할 수 있다
- 서버 비용이 저렴해진다
- Serverless에 유용하다
- 결과적으로 결과 생성 비용 (노동, 자원)을 줄일 수 있다
- WB: 이전에 받았던 응답을 저장 후, 매번 요청할시 저장해놓은 응답을 재사용하여 반환을 한다
- 웹의 성능:
- 요청을 보냈을 때 응답을 가능한 빠르게 받는 것 = 웹 페이지 로드 시간 단축
- 웹 서버로부터 웹 페이지 로드 성능 개선: SEO을 위한 Performance Metrics
- 웹 브라우저에 웹 페이지 로드 성능 개선: HTTP Cache
- 요청을 보냈을 때 응답을 가능한 빠르게 받는 것 = 웹 페이지 로드 시간 단축
- Cost: 어떤 요청을 보냈을 때 응답까지 기다리는 시간
- 매 요청에 따른 WB와 WS의 부하를 줄여준다
- 웹 성능 개선을 위함
Cache는 웹 브라우저(WB) 에서 동작한다
- Cache를 설정&관리하는 주체는 웹 서버(WS) 이다
- 관리한다고? = 캐시에 저장할지, 얼마나 가지고 있을지, 어떤걸 저장할지, ...
- 어떻게 관리하지? = WS가 응답을 줄때 "Response Header"을 추가한다
- Response Header: Cache Control에 Cache의 정보를 가진다
- 어디에 저장할지 명시한다 (Public vs. Private)
- Public:
- Proxy (Shared Cache) + WB에 저장한다 (남들이 볼 수 있음)
- WB가 처음으로 요청할때: Proxy checks the header -> Save the Cache -> Return to WB -> Save the Cache
- Private:
- WB에만 저장한다 (남들이 볼 수 없음)
- WB가 처음으로 요청할때: Proxy checks the header -> does not save the cache -> return to WB -> Save the Cache!
- Cache가 있으면 Hit, 없으면 Miss
- Check: Cache가 있는지 없는지 확인한다
- Public:
- 어디에 저장할지 명시한다 (Public vs. Private)
- Response Header: Cache Control에 Cache의 정보를 가진다
- 어떻게 관리하지? = WS가 응답을 줄때 "Response Header"을 추가한다
- 관리한다고? = 캐시에 저장할지, 얼마나 가지고 있을지, 어떤걸 저장할지, ...
- Cache를 설정&관리하는 주체는 웹 서버(WS) 이다
Cache: 임시로 재사용할 내용을 저장하는 행위
- CPU Cache != HTTP Cache != Server Cache
Cache의 종류
- Cache: WB와 WS 사이의 임시 중간 저장소
- 그 둘과 떨어져 있을 필요는 없다
- WB와 WS사이에 존재하는 모든 저장소를 HTTP Cache라고 부른다
- WB와 WS에게 반복되는 요청에 대해 부담을 나누기 위한 기술
- HTTP Cache에 재활용하려는 동적 웹 페이지 (결과)를 저장한다
- Cache는 WB, 중간 (= Proxy), WS에 위치할 수 있다
- Server Cache:
- WS에서 사용하는 Cache
- DB는 영구저장이라면 Cache는 일시 (반영구적) 저장
- 일시적 저장: 주기를 가지고 미사용 데이터를 지우거나 특정 상황에 지우도록 설정됨
- DB를 일시적 저장소로 쓴다면 Cache라고 부른다
- In-Memory 기반의 DB인 Redis를 Cache로 사용할 수 있다
- Redis: 영구적 저장소로도 쓰이나 일시적 저장소로도 활용이 가능하다
- 하지만 매우 비싸다... 물론 빠르다!
- Redis: 영구적 저장소로도 쓰이나 일시적 저장소로도 활용이 가능하다
- In-Memory 기반의 DB인 Redis를 Cache로 사용할 수 있다
- 4 가지 종류가 있다
- HTTP Cache:
- Private
- Located in WB (for one WB)
- 해당 WB만을 위해 캐시가 사용된다
- WS가 HTTP Cache 헤더 (= Cache-Control)를 통한 제어가 가능하다
- Service Worker (Cache API)를 활용하여 오프라인 시 웹 페이지 렌더링을 하면 좋은 포토폴리오가 될 수 있다
- Shared
- Located in Proxy (for multiple WB for multiple users)
- 모든 WB를 위해 캐시가 사용된다
- ex.) Reverse Proxy, CDN, ...
- Proxy Cache: WS HTTP Cache 헤더 (Cache-Control)를 통해 Private과 Shared에 저장 / 제어가 가능하다
- WS가 관리한다
- 관리형 Cache: 개발자가 직접 정책을 제어, 배포, 캐싱할 데이터를 직접 업로드하여 관리할 수 있다
- 개발자가 관리한다
- Proxy Cache: WS HTTP Cache 헤더 (Cache-Control)를 통해 Private과 Shared에 저장 / 제어가 가능하다
- Private
- Server Cache:
- Local
- for one WS
- ex.) LRU-Cache, Memcache, Ehcache
- LRU-Cache (Least Recently Used): 가장 오랫동안 사용되지 않은 데이터를 먼저 폐기한다
- Global
- for multiple WS
- ex.) Redis
- 정확하게 In-memory 기반의 NoSQL DB로, 속도가 뛰어난 장점이 있다
- Local
- HTTP Cache:
Cache의 동작 방식
- 먼저 Cache를 쓰는게 유효한 전략인지 판단을 해야한다
- 캐시 사용 여부: 실시간성이 매우 중요한 데이터는 성능에 문제가 되더라도 캐시를 사용하지 않는게 맞다
- 중간에 데이터가 바뀐다면 캐시는 실시간 데이터에 접근할 수가 없음!
- 그래서 재검증이 필요하다
- 데이터의 실시간성 검증을 위해 = 캐시 삭제를 위해
- 재검증: 특정 주기에 따라 Cache 되어 있는 데이터가 오래되었는지 확인하는 과정
- 그래서 재검증이 필요하다
- 중간에 데이터가 바뀐다면 캐시는 실시간 데이터에 접근할 수가 없음!
- 캐시 사용 여부: 실시간성이 매우 중요한 데이터는 성능에 문제가 되더라도 캐시를 사용하지 않는게 맞다
- 동작 원리:
- Cache는 임시 저장을 위한 전략이다
- 실시간성을 아예 포기하는게 아닌, 준실시간을 보장하는 정책이다
- 준실시간 (max-age): 어느 시점까지만 실시간을 포기한다
- 캐시해놓은 데이터가 너무 오래된 데이터가 되지 않도록 특정 주기 (max-age)에 따라 재검증을 한다
- 준실시간 (max-age): 어느 시점까지만 실시간을 포기한다
재검증
- 검증 방법: 조건부 요청 사용 = 재검증의 기준이 되는 값을 서버에게 보낸다
- 조건부 요청: 무언가를 확인하기 위한 요청
- 2개가 있다
- HTTP Cache 재검증
- CORS 요청 가능 여부
- 이후에 다룰 내용
- 2개가 있다
- 재검증의 기준이 되는 값: 캐시해 놓은 데이터가 오래됬는지 여부를 원본 주인인 WS가 판단하기 위한 기준 근거
- 2개가 있다
- 주기:
- 얼마 간격으로 재검증을 할지
- "이거 써도 돼?"
- 기준:
- WS가 판단하기 위한 기준 근거
- "써도 되는 기준": 뭘 기준으로 쓸지 말지
- 주기:
- 2개가 있다
- 재검증 기준:
- 수정일 (Last-Modified)
- WS가 보낸 해더중에 Last-Modified = 전송 Resource의 마지막 수정일
- 캐시가 유효한지 여부 = 원본이 바뀌었는지 여부를 시간 기반으로 판단한다
- 낮은 정확도
- 실제 데이터가 바뀌지 않았는데 수정일이 바뀔 수 있다
- ex.) .txt 파일 수정 후, 다시 원상복구를 한 경우 Last-Modified만 바뀐다
- 실제 데이터가 바뀌지 않았는데 수정일이 바뀔 수 있다
- 검사 방법 (조건부 요청):
- 바뀌었는가? (If-Modified-Since) - GET, HEAD 같은 단순 조회에 사용된다 (safe)
- 바뀌었다 (True): 200 Resource Cache + 새 응답 (새로운 캐시)
- 안바뀌었다 (False): 304 Not Changed
- 안바뀌었는가? (If-Unmodified-Since) - POST 같은 서버의 상태를 변경할때 사용된다 (non-safe)
- 안바뀌었다 (True) : 304 Not Changed
- 바뀌었다 (False) - 412 Precondition Failed (오류케이스)
- Access is denied because the condition (= If-Unmodified-SincE) is not met.
- 바뀌었는가? (If-Modified-Since) - GET, HEAD 같은 단순 조회에 사용된다 (safe)
- WS가 보낸 해더중에 Last-Modified = 전송 Resource의 마지막 수정일
- 고유값 (ETag = Entity Tag)
- 캐시가 유효한지 여부 = 원본이 바뀌었는지 여부를 고유값(Hash, ID)를 기반으로 판단한다
- 높은 정확도
- Very Detective! : 한톨이라도 바뀌면 바로 찾아낼 수 있다
- 검사 방법 (조건부 요청):
- 바뀌었는가? (If-None-Match)
- 바뀌었다 (True): 200 Resource Cache + 새 응답 (새로운 캐시)
- 안바뀌었다 (False): 304 Not Changed (GET이나 HEAD일 경우)
- Or 412 Precondition Failed (POST같은 서버 상태 변경일 경우)
- 안바뀌었는가? (If-Match)
- 바뀌었다 (True): 304 Not Changed
- 안바뀌었다 (False): 412 Precondition Failed.
- 바뀌었는가? (If-None-Match)
- WS가 ETag 헤더를 보내줬다면 WB가 재검증 시 If-None-Match나 If-Match 해더를 전달한다
- WS가 Last-Modified 헤더를 보내줬다면 WB가 재검증 시 If-Modified-Since나 If-Unmodified-Since 해더를 전달한다
- 둘다 보낼 수 있나? = 같이 쓴다
- ETag 기준으로 재검증
- 수정일 (Last-Modified)
- 조건부 요청: 무언가를 확인하기 위한 요청
Hash란?
- 객채의 고우성을 판단 / 대표 해준다
- 원래라면 두 객채가 동일한지 검사하기 위해 모든 필드를 비교해야했지만 객체 마다 객체의 고유성에 해당하는 필드를 비교하면 매우 쉽게 비교할 수 있다
- ex.) ID, UserID, ...
- 보안에서 Hash를 사용한다면 데이터의 변조를 판단할 수 있다
- ex.)
- 파일 다운로드: 받는 파일이 변조되었는지 판단할 수 있다
- Open API: 응답이 변조되었는지 판단할 수 있다
- 파일 업로드 시
- 원본 파일 + Hash값을 같이 업로드 한다
- 다운로더가 Hash값을 조합하고 원본 파일이 올린 Hash값과 비교를 하여 같다면 변조된것이 아니고, 다르다면 변조된 것이다.
- 고유성 검증을 위한 Hash 활용의 예시:
- HMAC (Hash-based Message Authentication Code)
- 다운로드 받은 파일이 변조되었는지 알기 위해
- Open API를 통해 받은 결과값이 변조되었는지 알기 위해
- 다운로더가 Hash값을 조합하고 원본 파일이 올린 Hash값과 비교를 하여 같다면 변조된것이 아니고, 다르다면 변조된 것이다.
- 원본 파일 + Hash값을 같이 업로드 한다
- ex.)
HTTP Cache 동작: Cache-Control Header를 통한 세부 설정
- 캐시할 데이터는 WS가 반환하는 값이고, 그 소유주는 WS이기에 WS가 Cache를 모두 제어한다
- 갑은 WS
- 을은 WB or Proxy - 시키는데로 할 수 밖에 없다
- 세부 설정
- 캐시 저장 여부: 캐시해? 말아?
- . no-store: 캐시 안함
- . no-cache: 캐시 함, 단, 매번 재검증 후 사용 (패킷 경량화를 한다 = 데이터양이 매우 줄어든다)
- 캐시 저장 장소: 어디에 저장해?
- . Public: Private (WB) + Shared (Proxy)
- . Private: Private (WB)에만 저장한다
- 캐시 재검증 주기: 얼마가 지나면 재검증해?
- . max-age: Expires (유효시간)이 지나면 재검증해
- WB를 위한 것이다
- 기존 Expries가 있다면 덮어쓴다
- max-age = 0 은 no-cache (매번 재검증)과 같다
- . s-maxage: Proxy Cache에만 적용되는 유효기간이다
- ex.) s-maxge = 31436000 (1년), max-age = 0
- WB는 계속 CDN (= Proxy)에게 재검증을 수행한다
- 1년 주기로 WS에게 재검증을 받는다
- WB는 CDN (=Proxy = Buffer)이 자체적으로 무효화하지 않는 이상, 1년동안 같은 데이터만 사용한다
- 새버전 배포시 Invalidate하는걸 잊지말자!
- 새버전 배포시 Invalidate하는걸 잊지말자!
- WB는 계속 CDN (= Proxy)에게 재검증을 수행한다
- ex.) s-maxge = 31436000 (1년), max-age = 0
- . max-age: Expires (유효시간)이 지나면 재검증해
- 재검증 강제: 재검증이 꼭 서버로부터 이뤄진 데이터만 보낼게
- .
must-revalidate
: 꼭 웹 서버와 직접 재검증후 완료되면 Cache를 사용하겠다는 정책 - 무조건 재검증이 된 응답만 받겠다!
- . no-cache 랑 max-age는 서버가 죽었을때 재검증이 불가능하여 그냥 넘겨준다
- .
must-revalidate
는 서버가 죽었을때도 안넘겨준다! (더욱 엄격하다)
- 서버와의 접속문제로 재검증에 실패했을 경우에도 기존 행동은 Cache되어있는 데이터를 반환하지만
- .
must-revalidate
가 활성화되어있다면 504 에러가 반환된다- . 504 Error: WS와 연락이 안된다!
- .
- .
- SWR (Stale-While-Revalidate): 캐시의 즉시성과 최신성을 한번에
- 현재 캐싱된 Content를 한곳에 저장해두고 계속해서 사용한다
- 즉시 로드가 가능하여 즉시성을 보장한다
- 미레에 업데이트될 Cached Content가 사용될 수 있도록 보장하는 최신성을 보장한다
- 즉시성: "지금 당장은 급하니까 Cache를 쓰자!"
- 최신성: "요청 후 답변이 오면 그때 쓰자!"
- 캐시 조회와 재검증을 동시에진행한다!
- 초록색 = 즉시성 + 최신성
- 장점:
- 성능이 좋다!
- ReadTime이 없다
- 성능이 좋다!
- 동작 방식:
- 0~1초 (신선 = 즉시성) = 캐싱된 응답을 "재검증" 없이 바로 반환
- 1~60초 (오래되었지만 반환과 동시에 재검증) = 캐싱된 응답을 바로 반환 + "재검증" 요청 (백그라운드에서)
- 60+초 (재검즘 = 최신성) = 캐싱된 응답을 사용하지 않음 + 서버에 요청을 보내어 응답 캐싱 및 반환
- 현재 캐싱된 Content를 한곳에 저장해두고 계속해서 사용한다
- 캐시 저장 여부: 캐시해? 말아?
HTTP Cache의 이점
- Perspective of WS
- WS 부하 완화
- 반복 연산 감소
- 웹 서버가 동적 웹 페이지를 생성하는 연산을 하지 않아도 된다
- 캐시를 반환하면 된다
- 웹 서버가 동적 웹 페이지를 생성하는 연산을 하지 않아도 된다
- 트래픽 분산:
- WS가 모든 요청 트래픽을 받아내지 않아도 된다
- 캐시가 일부 트래픽을 분담해준다
- 부분 DDos Attack을 방어할 수 있다
- 캐시가 일부 트래픽을 분담해준다
- WS가 모든 요청 트래픽을 받아내지 않아도 된다
- 반복 연산 감소
- WS 부하 완화
- Perspective of WB
- 네트워크 트래픽 감소
- Latency 및 네트워크 대역폭 사용 감소
- 유저 경험 증진
- 네트워크 트래픽 감소
정리
- 웹 서버의 캐시 제어:
- 웹 서버가 Cache-Control 헤더를 통해 Cache 동작을 관리한다
- 재검증 매커니즘:
- Last-Modified와 ETag를 사용해 캐시의 유효성을 확인한다
- 유호기간 성정:
- max-age와 s-maxage를 통해 브라우저와 프록시의 캐시 유효기간을 각각 제어할 수 있다
- 성능과 실시간성 균형:
- 캐시는 준실시간 데이터 제공을 통해 성능과 최선성 사이의 균형을 맞춘다
- String Tokenzie
- 역질문
- 누가 키를 가지고 있는가
- 기술적 요구사항 vs 비지니스의 요구사항
- ㅂ
반응형
'웹개발' 카테고리의 다른 글
HR이 직접 알려준 개발자 이력서 작성법 (2) | 2025.02.23 |
---|---|
웹 애플리케이션 프레임워크의 기초 (0) | 2024.08.16 |
백엔드 웹 개발의 기초 (0) | 2024.08.16 |