캐시
캐시는 값비싼 연산 결과 또는 자주 참조되는 데이터를 메모리 안에 두고 빠르게 처리될 수 있도록 하는 저장소이다.
캐시 계층
데이터가 잠시 보관되는 곳으로 데이터베이스보다 훨씬 빠르다. 캐시 계층을 두면 성능 개선과 데이터베이스 부하를 줄일 수 있다. 또한 캐시 계층의 규모를 독립적으로 확장시키는 것도 가능하다.
웹 서버가 캐시에 데이터를 확인하고 있으면 리턴, 없다면 데이터베이스에서 데이터를 찾아 캐시에 저장한 뒤 리턴하는 전략을 읽기 주도형 캐시 전략(read-through caching strategy)라고 한다.
이외에도 데이터 종류, 크기, 액세스 패턴에 맞는 다양한 캐시 전략이 있고 이를 확인해서 사용한다.
캐시 사용 시 유의할 점
- 쓰기 작업보다 읽기 작업이 빈번하게 발생한다면 캐시 사용을 고려해볼 수 있다.
- 캐시 데이터는 휘발성이기 때문에 영속적 보관이 필요한 데이터는 캐시에 두지 않는다.
- 적절한 캐시 데이터 만료 정책을 마련해야한다. 만료 기한이 너무 짧으면 캐시 데이터 갱신이 자주 일어나게 될 것이고 너무 길면 원본과 차이가 날 가능성이 높아진다.
- 데이터베이스 갱신과 캐시 갱신 연산이 단일 트랜잭션에서 수행되지 않으면 일관성이 깨질 수 있다. 또한 여러 지역에 걸쳐 시스템을 확장할때 캐시와 저장소 사이의 일관성을 유지하는 것은 어려운 문제이다.
- 캐시 서버를 한 대만 두는 경우 해당 서버는 단일 장애 지점이 된다. 이를 피하기 위해서는 캐시를 여러 지역에 걸쳐 분산시켜야 한다.
- 캐시 메모리가 너무 작으면 데이터가 너무 자주 캐시에서 밀려나기 때문에 캐시 성능이 떨어진다. 캐시 메모리를 과할당해서 보관될 데이터가 갑자기 늘어났을 때 생길 문제를 방지한다.
- 캐시가 꽉 찼을때 추가로 캐시에 데이터를 넣어야 할 경우 기존 데이터를 내보내는 데이터 방출 정책을 만들어야한다. 널리 쓰이는 것은 LRU(Least Recently Used) 이다. 다른 정책은 LFU(Least Frequently Used)나 FIFO(First In First Out) 등이 있다.
콘텐츠 전송 네트워크(CDN)
CDN은 정적 콘텐츠를 전송하는 데 쓰이는 지리적으로 분산된 서버 네트워크이다. 이미지, 비디오, CSS, Javascript 파일 등을 캐시한다.
- 사용자가 image.png 요청
- CDN 서버 캐시에 해당 이미지가 없는 경우 원본 서버에 요청해서 파일을 가져온다.
- 원본 서버가 CDN 서버에 이미지를 저장한다. 응답 HTTP 헤더에는 TTL(Time To Live)값이 들어있다.
- CDN 서버는 파일을 캐시하고 사용자에게 반환한다. 이미지는 TTL 까지 캐시된다.
- 다른 사용자가 같은 이미지에 대한 요청을 CDN에 요청한다.
- 만료되지 않은 이미지에 대한 요청은 캐시를 통해 처리된다.
CDN 사용 시 고려해야 할 사항
- 비용 : 자주 사용되지 않는 콘텐츠를 캐싱하는 것은 이득이 작으므로 CDN에서 빼는 것을 고려한다.
- 적절한 만료 : Time-Sensitive 콘텐츠는 만료 시점을 잘 정해야한다.
- CDN 장애 : CDN 자체가 죽엇을 경우 해당 문제를 감지하여 원본 서버로부터 직접 콘텐츠를 가져오도록 클라이언트를 구성하는 것이 필요할 수 있다.
- Invalidation 방법 : 만료되지 않은 콘텐츠라 하더라도 CDN API, Object Versioning (콘텐츠 버전 지정, image.png?v=2)와 같은 방식으로 무효화를 한다.
CDN과 캐시가 추가된 설계
본 포스트는 알렉스 쉬 저자의 가상 면접 사례로 배우는 대규모 시스템 설계 기초를 기반으로 스터디하며 정리한 내용들입니다.