Cache
Cache란 ?
: 자주 사용하는 데이터나 값을 미리 복사해 놓는 임시 저장소이다. 쉽게 말해, 보관 장소라고 생각하면 된다.
파레토의 법칙이란?
: 캐시 동작의 당위성을 부여하는 철학적 법칙 (?) 이다.
80퍼센트의 결과는 20퍼센트의 원인으로 인해 발생한다는 의미!
즉, 모든 결과를 저장할 필요가 없다는 말이다. 서비스를 할 때 많이 사용되는 20%를 캐싱한다면 나머지 80%의 결과에 대한 효율을 극대화시킬 수 있다는 의미이다.
Cache의 종류
1. look aside cache (Lazy Loading)
- Cache에 Data 존재 유무 확인
- Data가 있다면 cache의 Data 사용
- Data가 없다면 cache의 실제 DB Data 사용
- DB에서 가져온 Data를 Cache에 저장
look aside cache는 캐시를 한번 접근하여 데이터가 있는지 판단한 후, 있다면 cache의 데이터를 사용하고, 없을 경우 DB 또는 API를 호출하는 로직으로 구현된다. 대부분의 cache가 위 캐시 로직을 따른다.
2. write back
- Data를 Cache에 저장
- Cache에 있는 Data를 일정 기간동안 Check
- 모여있는 Data를 DB에 저장
- Cache에 있는 Data 삭제
write back은 cache를 다르게 이용하는 방법이다. DB는 접근 횟수가 적을수록 전체 시스템의 퍼포먼스가 좋아지는 것에서 출발한다.
데이터를 쓰거나 많은 데이터를 읽게되면 DB에서 Disk를 접근하게 되는데, 이는 어플리케이션 속도의 저하를 유발한다.
따라서 write back은 데이터를 cache에 모으고 일정한 주기 또는 일정한 크기가 되면 한번에 처리하는 방식으로 처리된다.
Cache의 작동 순서
- 원본 데이터(System-of-Record)와는 별개로 자주 쓰이는 데이터(Hot Data)들을 복사해둘 캐시 공간을 마련한다.
- 캐시 공간은 상수 시간등 낮은 시간 복잡도로 접근 가능한 곳을 주로 사용한다.(HashMap 같은)
- 데이터를 달라는 요청이 들어오면, 원본 데이터가 담긴 곳에 접근하기 전에 먼저 캐시 내부부터 찾는다.
- 캐시 내부에 원하는 데이터가 없거나, 너무 오래되어서 최신성을 잃은 경우
- 원본 데이터가 있는 곳에 접근해 데이터를 요청한 후 가져온다.
- 원본 데이터를 가져올 때, 캐시에도 해당 데이터를 복사하거나 갱신한다.
- 캐시에 원하는 데이터가 존재하는 경우
- 원본 데이터가 있는 곳에 접근하지 않고 캐시에서 바로 데이터를 찾아 제공한다. (Cache hit)
- 캐시 내부에 원하는 데이터가 없거나, 너무 오래되어서 최신성을 잃은 경우
- 캐시 공간이 모자라는 경우에는 안쓰는 데이터부터 삭제하여 공간을 확보한다.
Cache의 다양한 활용
CPU의 캐시메모리
- 속도가 빠른 장치와 느린 장치 사이에서 속도 차에 따른 병목 현상을 줄이기 위한 범용 메모리를 말하는 것이다.
- CPU가 메모리에 저장된 데이터를 읽어들이면서, 자주 사용하는 데이터는 아예 캐시 메모리에 저장한다.
- 다시 사용할 때는 메모리가 아닌 캐시 메모리에서 가져오는 것이다.
- 캐시 메모리의 장점 : 일반 메모리보다 속도가 빠르다
- 캐시 메모리의 단점 : 용량이 적고 가격이 비싸다.
- 아무리 빠른 주기억장치라도 CPU를 따라가기는 어렵다.
- 그래서 SRAM이라는 특수한 메모리를 CPU에 넣어 캐시메모리로 사용
하드디스크의 캐시메모리
- 프로세서와 시스템 메모리를 보조하는 역할
- CPU 입장에서 HDD와 SSD는 느려 터진 장치이기 때문에, 이 속도 차이를 완충하기 위해 캐시 메모리가 쓰인다.
하드 디스크에서 사용하는 캐시 메모리의 장점
- 데이터 처리가 빨라진다.
- CPU 사용률을 최소화할 수 있다.
데이터베이스의 캐시메모리
- 데이터베이스에서 쿼리를 실행하고, 하드디스크에서 데이터를 읽고 쓰는 것은 시간이 오래 걸리는 작업이다.
- 보통 데이터베이스는 쓰기보다는 읽기 작업을 많이 한다. 따라서, 자주 요청받는 쿼리의 결과를 캐싱해두면 성능이 증가한다.
- 데이터베이스 자체에서 별도의 캐시를 가지고 있다.
- ex) JPA 영속성 컨텍스트 (1차캐시)
1차 캐시, 2차 캐시란?
1차 캐시
: 영속성 컨텍스트 내부에서 엔티티를 보관하는 장소
[ 동작 과정 ]
- 조회 시 처음 1차 캐시에 해당 데이터가 있는지 탐색을 한다.
- 존재할 경우 해당 값을 리턴한다.
- 존재하지 않는 경우 데이터베이스에 접근해 값을 탐색한다.
- 탐색 결과를 바로 리턴하지 않고, 다음 탐색에서 재사용할 수 있도록 1차 캐시에 저장한 후 반환한다.
[ 유효 시점 ]
트랜잭션 시작 ~ 종료 시점까지 유효하다.
[ 동일성 ]
-> 같은 엔티티가 있을 경우 객체 동일성이 보장된다.
2차 캐시
: 애플리케이션 범위 캐시로, '공유 캐시'라고도 한다.
[ 동작 과정 ]
- 1차 캐시에서 엔티티를 조회한다.
- 존재하지 않는 경우 2차 캐시에서 엔티티를 찾는다.
- 2차 캐시에 찾는 엔티티가 존재는 경우에는 2차 캐시에서 객체를 반환한다.
- 2차 캐시에 엔티티가 존재하지 않는 경우 데이터베이스에 접근해 값을 탐색한다.
- 이때동시성을 극대화하기 위해 캐시 한 객체를 직접 반환하지 않고 복사본을 만들어 반환한다.
[ 유효 시점 ]
애플리케이션 종료 시점까지 유효하다.
[ 특징 ]
동시성을 극대화시키기 위해 캐시한 객체를 직접 반환하지 않고 복사본을 만들어 반환한다.
(캐시한 객체를 그대로 반환하면 여러 곳에서 같은 객체를 동시 수정할 경우와 같은 동시성 문제가 발생할 수 있기 때문)
[ 동일성 ]
-> 영속성 컨텍스트가 다르면 엔티티가 같더라도 객체 동일성이 보장되지 않는다.
CDN(Content Delivery Network)
- 사용자가 인터넷상에서 가장 가까운 곳의 서버로 컨텐츠를 전송받아, 트래픽이 특정 서버에 집중되지 않고 각 서버로 분산되도록 하는 기술
- ex) 유튜브
- 유튜브의 메인 서버는 미국에 있다.
- 한국과 미국을 잇는 국제 인터넷 회선은 비싸고 용량을 늘리기도 어렵다.
- 구글은 각 통신사마다 Google Global Cache를 두어 인기 있는 유튜브 동영상은 미국 서버까지 접속할 필요 없이 국내 서버에서 처리하도록 하였다.
- 비싼 국제 회선 비용이 절감되고, 버퍼링이 줄어 고화질 서비스의 이용 경험이 개선되었다.
- 이처럼 세계 각지에 캐시 서버를 두어 전송 속도를 높이고 부하를 분산하는 시스템이 CDN이다.
웹 캐시
- 네트워크를 통해 데이터를 가져오는 것은 하드디스크보다도 느릴 수 있다.
- 따라서, '캐시'를 사용해 사이트 응답시간을 줄이고, 서버 트래픽 감소 효과를 기대한다.
- 브라우저 캐시
- 웹 브라우저는 웹 페이지에 접속할 때 HTML, CSS, 자바스크립트, 이미지 등을 하드디스크나 메모리에 캐싱하고 이를 재사용한다.
-
더보기앱 서버에서 클라이언트에 보내는 HTTP 헤더에 캐시 지시자를 삽입하면, 클라이언트 웹 브라우저에서 해당 지시자에 명시된 캐시 정책에 따라 캐시를 실시한다.보안상 캐싱을 하지 않을 수도 있다.
- 응답 캐시
- 웹 서버 또한 매번 내용이 바뀌지 않는 경우가 더 많다.
- 서버에서 생성한 HTML을 캐싱해 뒀다가 다음 요청시 이를 재활용 한다.
- 프록시 캐시
- 클라이언트에서 자주 요청받는 내용은 웹 서버로 전달하지 않고 웹 서버 앞단의 프록시 서버에서 캐싱해둔 데이터를 바로 제공해 응답 시간을 감소시킨다.
Redis
- Remote Dictionary Server
- 메모리 기반 오픈소스 NoSQL DBMS일종으로 웹 서비스에서 캐싱을 위해 많이 쓴다.
- Redis는 List, Set, Sorted Set, Hash 등과 같은 Collection을 지원한다.
- Redis는 SingleThread로 원자성을 보장한다.
- 여기서 Dictionary는 Java의 HashMap<Key, Value>을 생각하면 된다.
- 기본적으로 모든 데이터를 메모리에 저장하여 처리하므로 속도가 빠르다.
- persistence를 지원한다. 서버 재부팅 시 메모리의 데이터가 휘발되지 않게끔 데이터를 하드디스크에 기록한다. 서버가 꺼져도 저장된다는 이야기!
- DBMS의 일종이므로, 명시적으로 삭제하지 않는 한 메모리에서 데이터를 삭제하지 않는다.
- Redis 사용 예시
- Remote Data Store
- 여러 서버의 Data 공유를 위해 사용될 수 있음.
- 특히, Redis의 경우 Single Thread 이므로 Race Condition 발생 가능성이 낮다는 것을 활용할 필요가 있을 경우
- 인증 토큰 개발
- Ranking Board (Sorted Set)
- 유저 API Limit
- Job QUeue
- Remote Data Store
EHcache
- Java의 표준 캐싱 API 명세인 JSR-107을 따르는 오픈소스 캐시 구현체
- Spring 프레임워크나 Hibernate ORM 등에서 바로 사용 가능
- 자바 진영에서 가장 널리 쓰인다고 한다.
- 캐시 저장공간을 속도에 따라 여러 등급(Tier)으로 나누어 메모리 계층 구조를 적용 가능
- 메모리에 캐시된 내용을 하드디스크에 기록 가능
- 대규모 서비스에서 캐시 서버 여럿을 클러스터로 묶을 수 있는 기능을 제공
참고했어요!
cache를 붙일 때 조회가 많고 갱신이 적고, 중요도가 많은 데이터를 사용한다.
만료 정책 필요 (LRU, LFU, FIFO -> cache도 Queue이기 때문)
일관성을 어떻게 유지할 것인지
캐시 다운에 대한 정책 (캐시는 보통 이중화시킨다. 한개가 다운되더라도 나머지 한개를 사용할 수 있는 구조)
캐시 서버에 대한 정책 (크면 클수록 좋다. 과해도 된다고 책에 나와있음)