HTTP 완벽 가이드 2부 - HTTP 아키텍처(2/2)
Updated:
HTTP 완벽 가이드 시리즈를 정리한 내용입니다.
7장 캐시
7.1 불필요한 데이터 전송
- 여러 클라이언트들이 자주 쓰이는 원 서버 페이지에 접근한다면, 원 서버는 클라이언트들에게 같은 응답을 각각 한번씩 전송한다.
- 이러한 불필요한 전송은 값비싼 네트워크 대역폭을 잡아먹고, 전송을 느리게 만들고, 웹 서버에 부하를 준다.
- 캐시를 이용하자
7.2 대역폭 병목
- 네트워크는 원격서버보다 로컬 네트워크 클라이언트에서 더 넓은 대역폭을 제공한다.
- 클라이언트가 LAN에 있는 캐시로부터 사본을 가져온다면 성능을 대폭 개선할 수 있다.
7.3 갑작스런 요청 쇄도
- 갑작스런 사건이 있따면 같은 웹 문서에 대해 많은 요청이 들어온다.
- 이러한 불필요한 트래픽 급증은 네트워크와 웹 서버의 심각한 장애를 야기한다.
7.4 거리로 인한 지연
- 대역폭이 문제가 되지 않더라도 거리가 문제가 될 수 있다.
- 빛의 속도의 한계로, 결국 전송되어야 하는 거리가 멀면 시간이 오래걸린다.
7.5 적중과 부적중
- 캐시가 세상 모든 문서의 사본을 저장하지는 않는다.
캐시 적중
: 요청이 도착했을 때 해당하는 사본이 있다.캐시 부적중
: 해당하는 사본이 없어 원 서버로 요청이 전달된다.
7.5.1 재검사
- 원 서버의 콘텐츠는 변경될 수 있으므로 캐시는 갖고있는 사본이 최신인지 때때로 점검해야 한다. ->
신선도 검사
- 캐시는 스스로 사본을 재검사할 수 있지만, 대체로 클라이언트가 사본을 요청하고 그 사본이 검사를 필요로 할 정도로 오래됐을 때 재검사한다.
- 캐시가 재검사 요청을 원 서버로 보냈을 때, 콘텐츠가 변경되지 않았다면
304 Not Modified
응답을 보낸다.- 캐시는 사본이 신선하다고 다시 표시한 뒤 사본을 클라이언트에게 제공한다.
재검사 적중
,느린 적중
이라 부른다.
- 캐시 적중보다는 느리고 캐시 부적중보다는 빠르다.
If-Modified-Since
헤더가 가장 많이 사용된다.
재검사 적중
- 서버는 클라이언트에게 작은
304 Not Modified
응답을 보낸다.
재검사 부적중
- 서버 객체가 캐시된 사본과 다르면, 서버는 콘텐츠 전체와 함께
200 OK
응답을 보낸다.
객체 삭제
- 서버 객체가 삭제되었다면, 서버는
404 Not Found
응답을 보내며 캐시는 사본을 삭제한다.
7.5.2 적중률
- 캐시가 요청을 처리하는 비율을
캐시 적중률
,문서 적중률
이라고 부른다. - 0에서 1의 값으로 되어있으나, 흔히 퍼센트로 표현하기도 한다. (100%면 모두 적중)
문서 적중률
을 개선하면 전체 대기시간(지연)이 줄어든다.
7.5.3 바이트 적중률
- 문서들이 항상 같은 크기인 것은 아니다.
- 큰 객체는 덜 접근되지만, 캐시가 적중하면 트래픽에 더 크게 기여한다.
바이트 적중률
을 개선하면 대역폭 절약을 최적화한다.
7.5.4 적중과 부적중의 구별
- HTTP는 클라이언트에게 응답이 캐시 적중이었는지, 원서버의 접근인지 말해줄 수 있는 방법이 없다.
Date
헤더는 응답이 생성됐을때의 시각을 표시하므로, 이를 현재 시각과 비교하면 캐시된 응답인지 알아낼 수 있다.
7.6 캐시 토폴로지
- 캐시는 한 명에게만 할당된
개인 전용 캐시
와 공유된 캐시인공용 캐시
로 나눌 수 있다.
7.6.1 개인 전용 캐시
- 웹 브라우저는 개인 전용 캐시를 내장한다.
- 자주 쓰이는 문서를 디스크와 메모리에 캐시한다.
7.6.2 공용 프록시 캐시
- 프록시 캐시는 로컬 캐시에서 문서를 제공하거나, 사용자 입장에서 서버에 접근한다.
- 여러 사용자가 접근하므로, 불필요한 트래픽을 더 많이 줄일 수 있다.
7.6.3 프록시 캐시 계층들
- 작은 캐시에서 캐시 부적중이 발생하면, 더 큰 부모 캐시가 걸러진 트래픽을 처리하도록 하는 것이 합리적이다.
- 클라이언트에 가까울수록 작고 저렴한 캐시를 사용하고, 많은 사용자들에게 공유되는 문서는 계층 상단에 위치한다.
7.6.4 캐시망, 콘텐츠 라우팅, 피어링
- 몇몇 네트워크 아키텍처는 단순한 캐시 계층 대신 복잡한 캐시망을 만든다.
- 어떤 부모 캐시와 대화할 것인지, 아니면 바로 원 서버로 요청이 가도록 할 것인지 동적으로 결정한다.
- 서로 다른 조직들이 상호 이득을 위해 그들의 캐시를 연결하여 서로를 찾아볼 수 있도록 해주기도 한다.
7.7 캐시 처리 단계
7.7.1 단계 1: 요청 받기
- 캐시가 네트워크 커넥션에서의 활동을 감지하고, 들어오는 데이터를 읽는다.
7.7.2 단계 2: 파싱
- 요청 메세지를 여러 부분으로 파싱하여 헤더 부분을 조작하기 쉬운 자료구조에 담는다.
- 캐싱 소프트웨어가 헤더 필드를 처리하고 조작하기 쉽게 만든다.
7.7.3 단계 3: 검색
- 캐시는 URL을 알아니내고 해당하는 로컬 사본이 잇는지 검사한다.
- 로컬에서 가져올 수 없다면, 원서버, 부모 프록시에서 가져오거나, 혹은 실패를 반환한다.
7.7.4 단계 4: 신선도 검사
- 캐시된 사본이 신선도 한계를 넘을 정도로 오래되었다면, 신선하지 않은 것으로 간주되어 서버와 재검사를 해야한다.
7.7.5 단계 5: 응답 생성
- 캐시된 서버 응답 헤더를 토대로 응답 헤더를 생성한다.
- 캐시는 클라이언트의 상황에 맞추어 헤더를 적절하게 번역해야 한다.
- 캐시 또한 캐시 신선도 정보를 삽입해야 한다.
Date
헤더는 객체가 원 서버에서 최초로 생겨난 일시를 표현하는 것이므로 캐시가 조정해서는 안된다.
7.7.6 단계 6: 전송
- 캐시는 응답을 클라이언트에게 돌려준다.
7.7.7 단계 7: 로깅
- 대부분의 캐시는 로그 파일과 캐시 사용에 대한 통계를 유지한다.
- 각 캐시 트랜잭션이 완료된 후, 통계 캐시 적중과 부적중 횟수에 대한 통계를 갱신하고 로그 파일에 요청 종류, URL 그리고 무엇이 일어났는지를 알려주는 항목을 추가한다.
7.8 사본을 신선하게 유지하기
7.8.1 문서 만료
Cache-Control
과Expires
라는 헤더를 이용해서 원 서버가 각 문서에 유효기간을 붙일 수 있다.
7.8.2 유효기간과 나이
Cache-Control: max-age
: 문서의 최대 나이를 정의한다. 문서의 신선도 유효기간을 초단위로 지정한다.Expires
: 절대 유효기간을 명시한다.
7.8.3 서버 재검사
- 재검사 결과 콘텐츠가 변경되었다면, 캐시는 그 문서의 새로운 사본을 가져와 오래된 데이터 대신 저장한 뒤 클라이언트에게도 보내준다.
- 재검사 결과 콘텐츠가 변경되지 않았다면, 캐시는 새 만료일을 포함한 새 헤더들만 가져와서 캐시 안의 헤더들을 갱신한다.
- 캐시의 응답의 종류
- 충분히 신선한 캐시된 사본
- 원 서버와의 재검사를 마치고 신선하다고 확신할 수 있는 사본
- 에러 메세지(원 서버 다운등으로 인한 재검사 불가능)
- 경고 메세지가 부착된 캐시된 사본(부정확할 수 있음)
7.8.4 조건부 메서드와의 재검사
- GET메세지에 특별한 헤더를 추가하여 재검사를 실시한다.
If-Modified-Since
: 문서가 주어진 날짜 이후로 수정되었다면 요청 메서드를 처리한다.If-None-Match
: 문서에 대한 특별한 태그를 비교하여 다르다면 요청 메서드를 처리한다.
7.8.5 If-Modified-Since: 날짜 재검사
- 문서가 주어진 날짜 이후 변경되었다면, 조건은 참이므로 새문서와 새로운 만료날짜가 담긴 헤더 등이 캐시에게 반환된다.
- 변경되지 않았다면, 조건은 거짓이므로
304 Not Modified
와 갱신이 필요한 것(새로운 만료 날짜 등)을 캐시에게 반환한다. - 마지막으로 변경된 일시인
Last-Modified
헤더와 함께 동작한다.
7.8.6 If-None-Match: 엔티티 태그 재검사
- 최근 변경 일시 재검사가 행해지기 어려운 상황이 있다.
- 일정 간격으로 다시 쓰여지지만 내용에는 변화가 없을 때
- 문서의 변경이 다시 캐시하기에는 너무나도 사소할 때
- 서버가 갖고있는 페이지에 대한 최근 변경 일시를 정확하게 판별할 수 없을 때
- 1초보다 적은 간격으로 갱신되는 문서를 가진 서버여서 1초보다 더 작은 정밀도가 필요할 때
- 퍼블리셔는 문서를 변경했을 때 문서의 엔티티 태그를 새로운 버전으로 표현한다.
7.8.7 약한 검사기와 강한 검사기
- HTTP1.1은 서버가 캐시된 사본들을 무효화하지 않고 문서를 조금 고치고 싶을 때 사용할 수 있는
약한 검사기
를 지원한다. 강한 검사기
는 콘텐츠가 바뀔 때마다 무조건 바뀐다.- 서버는
W/
접두사로 약한 검사기를 구분한다.
7.8.8 언제 엔티티 태그를 사용하고 언제 Last-Modified 일시를 사용하는가
- HTTP/1.1 클라이언트는 만약 서버가 엔티티 태그를 반환했다면, 반드시 엔티티 태그 검사기를 사용해야 한다.
- 서버가
Last-Modifeid
값만을 반환했다면, 클라이언트는If-Modifed-Since
검사를 사용할 수 있다. - 모두 사용 가능하다면, 클라이언트는 두 가지의 재검사 정책을 모두 사용해야 한다.
- HTTP/1.1 원 서버는 가능하다면 엔티티 태그 검사기를 보내야 한다.
- 모든 조건에 부합할 때만
304 Not Modifed
응답을 반환해야 한다.
7.9 캐시 제어
- 문서가 만료되기 전까지 얼마나 오랫동안 캐시될 수 있게 할 것인지 서버가 설정할 수 있다.
7.9.1 no-cache와 no-store 응답 헤더
Cache-Control: no-store
Cache-Control: no-cache
Pragma: no-cache
no-store
는 캐시가 그 응답의 사본을 만드는 것을 금지한다.no-cache
는 캐시가 저장될 수 있으나, 재검사를 하지 않고서는 캐시에서 클라이언트로 제공될 수 없다.Pragma: no-cache
는 HTTP/1.0+와의 하위호환성을 위해 포함되어 있다.
7.9.2 Max-Age 응답 헤더
Cache-Control: max-age=3600
Cache-Control: s-maxgage=3600
max-age
는 신선하다고 간주되었던 문서가 서버로부터 온 이후로 흐른 시간이다.s-maxage
는max-age
와 같지만 공유된 캐시에서만 적용된다.
7.9.3 Expires 응답 헤더
Expires: Fri, 05 Jul 2002, 05:00:00 GMT
- 초 단위의 시간 대신 실제 만료 날짜를 명시한다.
- 많은 서버가 동기화되어있지 않기 때문에,
max-age
가 더 유용하다. - 0으로 설정할 수 있으나, 이는 문법 위반이고 사용해서는 안된다.
7.9.4 Must-Revalidate 응답 헤더
Cache-Control: must-revalidate
- 캐시가 성능을 위해 만료된 객체를 제공하도록 설정할 수도 있는데, 이를 방지한다.
- 이 객체의 신선하지 않은 사본을 원 서버와의 최초의 재검사 없이는 재사용해서는 안 됨을 의미한다.
- 원 서버가 사용할 수 없는 상태라면, 반드시
504 Gateway Timeout error
를 반환해야 한다.
7.9.5 휴리스틱 만료
- 응답이
Cache-Control: max-age
헤더나Expires
헤더 모두 포함하지 않으면 캐시는 경험적인 방법으로 최대 나이를 계산한다. - 유명한 휴리스틱 만료 알고리즘으론 LM 인자 알고리즘이 있으며, 문서가 최근 변경 일시를 포함하고 있다면 사용할 수 있다.
- 캐시된 문서가 마지막으로 변경된 것이 상당히 오래전이라면, 안정적인 문서이고 변경가능성이 크지 않을 것이라고 판단하여 더 오래 보관한다.
- 캐시된 문서가 최근에 변경됐다면, 자주 변경될 것이라고 생가갛여 짧은 기간만 보관한다.
- 최근 변경일 조차 없다면 근거가 없으므로 기본 신선도 유지기간을 설정한다.
7.9.6 클라이언트 신선도 제약
- 클라이언트는
Cache-Control
요청 헤더를 사용하여 만료 제약을 엄격하게 하거나 느슨하게 할 수 있다.
Leave a comment