kakasoo

[HTTP] 16. 캐시(1) 본문

프로그래밍/HTTP

[HTTP] 16. 캐시(1)

카카수(kakasoo) 2020. 12. 5. 21:22
반응형

웹 캐시는 자주 쓰이는 문서의 사본을 자동으로 보관하는 HTTP 장치다. 웹 요청이 캐시에 도착했을 때, 사본이 존재한다면 서버에 갈 필요없이 즉시 반환한다.

  • 네트워크 요금으로 인한 비용을 줄여준다.
  • 네트워크 병목을 줄여준다.
  • 원 서버에 대한 요청을 줄인다, 즉 부하를 줄여서 전체 속도를 빠르게 해준다.
  • 거리로 인한 지연을 줄여준다.

이 장에서는 캐시가 어떻게 성능을 개선, 비용을 절감하는지, 그리고 그것을 어떻게 측정하는지, 캐시가 있을 가장 적절한 위치는 어디인지에 대해 말할 것이다.

또한 HTTP가 어떻게 캐시된 사본을 신선하게 유지하는지, 캐시와 서버와의 상호작용은 어떻게 이뤄지는지를 이야기한다.

7.1 불필요한 데이터 전송

복수의 클라이언트가 똑같은 문서를 위해 서버에 접근할 때, 서버는 각각 한 번씩 클라이언트에게 전송을 한다. 이 똑같은 문서란 곧 똑같은 바이트들이다.

똑같은 바이트다 똑같이 서버를 통해 이동하게 된다면, 이 불필요한 데이터 전송은 값비싼 네트워크 대역폭을 잡아먹고, 전송을 느리게 만들며, 서버에 부담을 준다.

캐시를 이용하면 첫번째 서버 응답이 캐시에 보관이 되고, 뒤 이은 요청들에 대한 응답으로 보관된 사본을 사용하게 된다. 이는 중복된 트래픽을 줄인다.

7.2 대역폭 병목

캐시는 네트워크 병목을 줄인다. 많은 네트워크가 원격 서버보다는 로컬 네트워크 클라이언트에게 더 넓은 대역폭을 제공한다.

클라이언트가 서버에 접근할 때의 속도는, 그 경로에 있는 가장 느린 네트워크의 속도와 같다.

만약 클라이언트가 빠른 LAN에 있는 캐시로부터 사본을 가져온다면, 캐싱은 성능을 대폭 개선할 수 있을 것이다. (특히 큰 문서들에 대해서)

7.3 갑작스런 요청 쇄도 (Flash Crowds)

캐싱은 갑작스런 요청 쇄도에 대처하기 위해 특히 중요하다. 특별한 사건이 있는 경우 서버는 평소보다 수십 배 많은 요청을 받기도 한다.

7.4 거리로 인한 지연

네트워크가 빛의 속도로 오간다고 하더라도, 미국과 일본 사이에서는 600밀리초 정도의 지연이 발생할 수 있다. 이 때, 웹 사이트가 복잡해지면 이것은 수 초로 증가한다.

7.5 적중과 부적중

캐시에 요청이 들어왔을 때, 만약 그에 대응되는 사본이 있다면 그것을 이용해 요청이 처리될 수도 있다. 이것을 캐시 적중(cache hit)이라고 부른다.

만약 대응하는 사본이 없다면 그냥 원 서버로 전달되기만 할 뿐이다. 이것을 캐시 부적중(cache miss)이라고 부른다.

캐시 적중이 높으면 좋겠지만, 웹 상의 모든 문서를 보관할 정도의 충분한 캐시를 살 능력이 있는 사람은 거의 없고, 있다고 해도 정보 중에는 항상 최신 상태여야 하는 것도 있다.

7.5.1 재검사 (Revalidation)

원 서버의 콘텐츠는 변경이 될 수 있어서, 캐시는 반드시 그들의 사본이 최신 상태인지 점검해야 한다. 이런 신선도 검사를 재검사 (Revalidation) 이라고 한다.

효과적인 검사를 위해 HTTP는 서버로부터 전체 객체를 가져오지 않아도 콘텐츠가 여전히 신선한지 빠르게 검사할 수 있는 특별한 요청을 재정의했다.

모든 문서를 재검사하지 않고, 클라이언트가 요청한 문서가, 특별히 오래되어서 다시 검사가 필요해보이는 경우에만 한정하여 재검사를 한다.

캐시는 캐시된 사본의 재검사가 필요할 때, 원 서버에 작은 재검사 요청을 보낸다. 콘텐츠가 변경되지 않았다면 서버는 아주 작은 304 Not Modified 응답을 보낸다.

그 사본이 유효하다는 것을 알게 된 캐시는 즉각 사본이 신선하다고 임시로 다시 표시한 뒤 클라이언트에게 제공한다. 이를 재검사 적중 혹은 느린 적중이라고 부른다.

순수 캐시 적중보다는 느린데, 원 서버와 검사를 할 필요가 있기 때문이다.

HTTP는 캐시된 객체를 재확인하기 위해 몇 가지 도구를 제공하는데, 그 중에서 가장 많이 씌는 것은 If-Modified-Since 헤더다. 서버에 보내는 GET 요청에 이를 추가하면 된다.

이것은 캐시된 시간 이후 변경된 경우에만 사본을 보내달라는 의미가 된다. 아래는 이 헤더를 보낸 이후 발생하는 세 가지 경우이다.

재검사 적중

만약 서버 객체가 변경되지 않았다면 서버는 클라이언트에게 작은 HTTP 304 Not Modified 응답을 보낸다.

재검사 부적중

만약 서버 객체가 캐시된 사본과 다르다면, 서버는 콘텐츠 전체와 함께 평범한 HTTP 200 OK 응답을 클라이언트에게 보낸다.

객체 삭제

만약 서버 객체가 삭제되었다면, 서버는 404 Not Found 응답을 돌려보내며, 캐시는 즉각 사본을 삭제한다.

7.5.2 적중률

캐시가 요청을 처리하는 비율을 캐시 적중률이라고 한다. (혹은 캐시 적중비, 문서 적중률, 문서 적중비 라고도 한다.)

캐시 관리자는 캐시 적중률이 100%에 근접하게 되는 것을 좋아할 것이다. 실제 적중률은 캐시가 얼마나 큰지, 캐시 사용자들의 관심사가 얼마나 비슷한지, 또는,

캐시된 데이터가 얼마나 자주 바뀌거나 개인화되는지, 캐시가 어떻게 설정되어 있는지에 달려 있다.

적중률은 예측하기 어려운 것으로 악명이 높지만, 보통은 40%면 웹 캐시로서 괜찮은 편이다. 다행인 것은, 보통 크기의 캐시라도 충분히 효과적이라는 점이다.

7.5.3 바이트 적중률

문서들이 모두 같은 크기인 것은 아니기 때문에 적중률이 모든 것을 말해주지 못한다. 그렇기 때문에 별도로 바이트 단위 적중률 측정값을 계산하기도 한다.

(특히 트래픽의 모든 바이트에 요금을 매기려는 사람들이 그렇다.)

바이트 단위 적중률은 캐시를 통해 제공된 모든 바이트의 비율을 표현한다. 이 측정 값은 트래픽이 절감된 정도를 포착해낸다.

바이트 단위 적중률이 100%라면 어떤 트래픽도 인터넷으로 나가지 않았음을 의미한다.

문서 적중률은 트랜잭션이 얼마나 외부로 나갔는지를 보여주고, 바이트 단위 적중률은 얼마나 많은 바이트가 인터넷으로 나가지 않았는지를 보여준다.

각각이 트랜잭션과, 대역폭 절약을 최적화하는 데에 중요한 지표로 활용된다.

7.5.4 적중과 부적중의 구별

불행히도 HTTP는 클라이언트에게 응답이 캐시 적중이었는지 원 서버 접근이었는지 말해줄 수 있는 방법을 제공하지 않는다.

두 경우 모두 응답 코드는 응답이 본문을 가지고 있음을 의미하는 200 OK가 될 것이다. 다만 어떤 상용 프락시 캐시는 캐시에서의 일을 설명하고자 Via 헤더를 이용하기도 한다.

다른 방법으로는 Date 헤더를 이용하는 것이다. 응답의 Date 헤더 값을 현재 시각과 비교하여, 응답의 생성 일이 더 오래되었다면 캐시된 것임을 알 수 있다.

다른 방법으로 Age 헤더를 이용하는 방법이 있다.

7.6 캐시 토폴로지

캐시는 한 명의 사용자에게만 할당될 수도 있고, 반대로 수천 명의 사용자들 간에 공유될 수도 있다. 한 명에게만 할당된 경우를 개인 전용 캐시 (private cache)라고 부른다.

개인 전용 캐시는 개인만을 위한 캐시이므로 한 명의 사용자가 자주 찾는 페이지를 담는다. 공유된 캐시는 공용 캐시 (public cache) 라고 부른다.

7.6.1 개인 전용 캐시

개인 전용 캐시는 많은 저장 공간을 필요로 하지 않으므로 작고 저렴할 수 있다. 웹 브라우저는 개인 전용 캐시를 내장하고 있다.

대부분의 웹 브라우저는 자주 쓰이는 문서를 개인용 컴퓨터의 디스크와 메모리에 캐시해 놓고 사용자가 캐시 사이즈와 설정을 수정할 수 있도록 허용한다.

이전에는 chrome의 경우 about:cache 를 검색하여 캐시 목록을 볼 수 있었지만, 지금은 사라졌다. 단 캐시가 사라진 것은 아니라서 아래 경로에서 찾아 볼 수는 있다.

C:\Users\[username]\AppData\Local\Google\Chrome\User Data\Profile 1\Cache

조사해본 결과, 캐시 조회가 사라진 것은 캐시를 볼 수 있는 다양한 tool이 나온 탓이라고 되어 있지만, 실질적인 이유는 아닌 것 같다. (많은 개발자들이 이를 아쉬워 하고 있다.)

몇몇 개발자들은, 이것이 보안 쪽에서 야기된 문제로 인해 사라진 것이라고 추측하고 있다.

7.6.2 공용 프락시 캐시

공용 캐시는 캐시 프락시 서버, 혹은 더 흔히 프락시 캐시라고 부르는 특별한 종류의 공유된 프락시 서버다.

프락시 캐시는 로컬 캐시에서 문서를 제공하거나 혹은 사용자 입장에서 서버에 접근한다. 공용 캐시에는 여러 사용자가 접근하기에, 불필요한 트래픽을 줄일 더 많은 기회가 있다.

예를 들어, 각각의 개인 전용 캐시들이 자신의 사본이 최신의 정보인지 파악하지 위해 원 서버에 확인을 요청한다고 해보자. 작은 요청이라 할지라도 이 역시 많은 트래픽이 된다.

이 때 공용 프락시 캐시는, 서버에 이 사본이 최신인지에 대한 물음을 1번만 하면 되기 때문에 트래픽을 절감해준다.

수동 프락시를 지정하거나 프락시 자동설정 파일을 설정함으로써 브라우저가 프락시 캐시를 사용하도록 설정할 수 있다. 또는 인터셉트 프락시를 사용하여 강제할 수도 있다.

7.6.3 프락시 캐시 계층들

캐시 하나가 모든 것을 처리하는 것이 부담이 된다면, 프락시 캐시들로 계층을 만들어, 적은 클라이언트에게만 쓰이는 사본들 위에 캐시 프락시 하나를 두고,

많은 클라이언트들에게 쓰이는 사본을 그 프락시 서버들 위에 또 하나의 프락시 서버들을 두어 피라미드 구조처럼 만드는 것을 생각해볼 수 있다.

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

몇몇 네트워크 아키텍처는 단순한 캐시 계층 대신 복잡한 캐시망을 만든다. 프락시 캐시는 복잡한 방법으로 서로 대화하여 어떤 부모와 캐시할지, 바로 서버로 갈지 결정한다.

아래는 캐시망 안에서 콘텐츠 라우팅을 위해 설계된 캐시들이 할 수 있는 일이다.

  • URI에 근거, 부모 캐시와 원 서버 중 하나를 동적으로 선택한다.
  • URI에 근거, 특정 부모 캐시를 동적으로 선택한다.
  • 부모 캐시에게 가기 전, 캐시된 사본을 로컬에서 찾는다.
  • 다른 캐시들이 그들의 콘텐츠에 접근할 수 있도록 부분적인 허용을 하되, 인터넷 트랜짓 (다른 네트워크로 건너가는 행위) 은 허용하지 않는다.

서로 다른 조직들이 상호 이득을 위해 그들의 캐시를 연결하여 서로 찾아볼 수 있게 하는 것을 피어링이라고 한다.

선택적인 피어링을 지원하는 캐시는 형제 캐시라고 부르는데,

HTTP는 형제 캐시를 지원하지 않기 때문에 사람들은 인터넷 캐시 프로토콜(ICP)나 하이퍼텍스트 캐시 프로토콜(HTCP) 같은 프로토콜을 이용해 HTTP를 확장하였다.

반응형