Cache란?

Frankle·2022년 2월 14일
1
post-thumbnail

Cache

10분 테코톡 큰곰, 소니님의 Cache 발표 영상을 보고 정리하였습니다.

Cache란?

Cache는 데이터나 값을 미리 복사해 놓는 임시 저장소이다.

CPU, DRAM, HDD, CDN, HTTP, Application, Proxy 등 굉장히 많은 곳에서 사용되고 있다.

Cache는 언제 사용하는가?

원본 데이터에 접근하는 시간이 오래 걸리거나 값을 재계산하는 시간을 절약하고 싶을 경우에 사용한다.

Cache를 사용하는 이유

캐시에 데이터를 미리 복사해 놓으면 계산이나 접근 시간 없이 더 빠른 속도로 데이터에 접근할 수가 있다.

메모리 계층 구조

  • 데이터를 저장하는 공간의 속도가 용량은 반비례 관계
    • 속도가 빠른 메모리일수록 용량이 작음
    • 용량이 큰 저장 장치는 속도가 느림
    • 데이터 저장 공간은 속도와 용량에 따라 특성에 맞게 역할을 나눠 사용한다.

캐시의 작동 방식

  • 원본 데이터와 별개로 자주 쓰는 데이터를 복사해둘 캐시 공간을 마련한다. 캐시 공간은 상수 시간 등 낮은 시간 복잡도로 접근 가능한 곳을 주로 사용한다.
  • 데이터를 달라는 요청이 들어오면, 원본 데이터가 담긴 곳에 접근하기 전에 먼저 캐시 내부에서부터 찾는다.
  • 캐시에 원하는 데이터가 없거나 너무 오래되어 최신성을 잃었으면(Expiration) 그때서야 원본 데이터로 접근하여 가져온다. 이 때 데이터를 가져오면서 캐시에도 해당 데이터를 복사하거나 갱신한다.
  • 캐시에 원하는 데이터가 있으면 원본 데이터가 있는 공간에 접근하지 않고 캐시에 있는 데이터를 가져다 제공한다.
  • 캐시 공간은 작기 때문에 공간이 모자라면 사용하지 않는 데이터부터 삭제하여 공간을 확보시킨다.

CPU의 캐시 메모리

  • 현대 CPU는 1초에 수십억 번을 작동할만큼 발달됨.
    • 아무리 빠른 주기억장치여도 CPU를 따라가긴 어려움
    • 그래서 SRAM이란 특수한 메모리를 CPU에 넣어 캐시 메모리로 사용

하드디스크, 데이터베이스

  • 하드디스크는 주 기억장치에 비해 10만 배 이상 느린 장치
  • 처리 효율을 올리려면 자주 쓰는 데이터를 캐싱하는 것이 좋다.
  • 데이터베이스 또한 쿼리를 실행하여 하드디스크에서 데이터를 읽고 쓰는 것은 시간이 오래 걸리는 작업
  • 대개 데이터베이스는 쓰기보다 읽기가 많으므로 자주 요청받는 쿼리의 결과를 캐싱하면 효율이 증가한다.

웹 캐시

  • 네트워크를 통해 리소스를 가져오는 것은 하드디스크에서 가져오는 것보다 느릴 때가 많다.
  • 웹 브라우저는 웹 페이지에 접속할 때 HTML, CSS, JS, 이미지 등을 하드디스크 또는 메모리에 캐싱해두었다가 다음에 다시 접속할 때 이를 캐시에서 가져와 효율성을 높인다. (브라우저 캐시)
  • 웹 서버 또한 상당수의 경우 동적 웹 페이이라 할지라도 매번 요청이 바뀌지 않는 경우가 더 많으므로, 서버에서 생성한 HTML을 캐싱해 두었다가 다음 번 요청에 캐시에서 가져와 효율성을 높인다. (응답 캐시)
  • 이와 유사하게, 클라이언트에서 자주 요청받는 내용은 웹 서버로 전달하지 않고 웹 서버 앞단의 프록시 서버에서 캐싱해둔 데이터를 바로 제공하기도 한다. (프록시 캐시)

EHCache

  • Java에서 가장 널리 사용되는 Cache 구현체
  • 자바의 표준 캐시 API 명세인 JSR-107을 따르는 오픈소스 캐시 구현체
  • Spring, Hibernate 등에서도 사용 가능
  • 캐시 저장공간을 속도에 따라 여러 등급으로 나누어 메모리 계층 구조를 적용할 수 있음.
  • 메모리에 캐시 된 내용을 하드 디스크에 기록 가능
  • 대규모 서비스에서 캐시 서버 여럿을 클러스터링 할 수 있는 기능 제공.

브라우저 캐시

브라우저는 보통 서버에서 응답 받은 정적 파일(js, css, image)를 브라우저 캐시에 저장해두고 재사용한다.

만약 서버에서 동일한 정적 리소스에 대한 내용이 변경이 되었다면 어떻게 해야할까.

Cache-Control

이를 위해 서버는 리소스를 응답할 때, HTTP Header에 해당 리소스에 대해 캐싱할 수 있는 시간을 포함해서 보낸다.

Cache-Control : max-age=600

하지만 캐시의 만료 시간은 부족한 점이 있다.

예를 들어 리소스에 대한 캐시 만료 시간이 지나면 서버에 다시 요청을 해서 가져오게 되는데, 리소스에 대한 내용이 변하지 않았다면 서버로 재요청을 하는 과정이 결국 불필요한 네트워크 비용이 발생한다.

위 문제를 해결하기 위해 나온 것이 ETag 이다.

ETag

ETag는 데이터에 대한 Hash 값인 유효성 검사 토큰이다.

Etag="x234dff"

ETag를 사용한 HTTP 클라이언트-서버 리소스 요청 과정

  1. 서버에서 리소스 조회 요청에 대해 ETag HTTP 헤더로 유효성 검사 토큰을 전달한다.
  2. 브라우저 캐시 내 리소스가 만료되면 ETag를 서버에 보내 해당 리소스가 변경되었는지 확인한다.
  3. ETag값이 같다면 변경사항이 없는 것이므로 캐시 내에 있는 리소스를 기존대로 사용한다.
  4. ETag값이 다르다면 변경사항이 있는 것이므로 서버는 업데이트 된 리소스와 새로운 ETag 값을 반환한다.

클라이언트가 리소스 수정 요청하게 되면, ETag 값도 따라서 변경된다.

이처럼 ETag를 사용하여 불필요한 네트워크 비용을 줄이고 효율적인 리소스 업데이트 검사를 할 수 있게 되었다.

다만, 아직 문제점이 하나 남아있다.

정적 리소스는 변경될 일이 적으므로 유효 기간을 넉넉하게 잡는 편인데..?

브라우저에 캐싱된 리소스는 유효 기간이 만료될 때까지 사용된다.

정적 리소스 파일은 변경될 일이 적으므로 만료 시간을 넉넉하게 잡는 경우가 많다.

예를 들어 어떠한 정적 리소스인 버튼에 대해 max-age를 7일로 설정하였고, 어떠한 경우로 인해 핫픽스를 진행하면서 해당 버튼의 색상이 빨간색에서 파란색으로 변경됐다고 생각해보자.

이전에 빨간색 버튼으로 이미 리소스를 응답받았던 클라이언트는 해당 리소스에 대한 max-age가 만료되기 전까지 서버에 다시 요청을 보내지 않으므로 서버에서 변경되었다고 하더라도 그냥 빨간색 버튼으로 보여지게 된다.

이러한 문제를 해결하기 위해 파일 이름 뒤에 별도의 토큰이나 버전 번호를 붙이면 해결이 된다.

요약하자면 ETag, Cache-Control과 더불어 파일 버전 관리를 함께 사용하면 HTTP 캐시를 효율적으로 활용할 수가 있다.

요약

조회가 자주 반복된다면 캐시화를 통해 효율성을 높이는 것을 고려해보자.

profile
이사 준비중...

1개의 댓글

comment-user-thumbnail
2022년 2월 23일

좋은글 감사합니다

답글 달기