캐시란?
캐시는 임시 저장 공간으로 최근에 사용한 데이터를 가까운 곳에 보관해두었다가 다음에 훨씬 더 빠르게 가져올 수 있게 해주는 것입니다.

캐시의 위치
External Caching

Redis나 MemCached를 통해 자체 서버 및 메모리를 관리하는 DB와 분리된 환경입니다. 보통 Application 서버에서 필요한 데이터를 먼저 캐시에서 찾고 캐시에 데이터가 있는 경우를 캐시 히트라고 하고 바로 가져옵니다. 캐시에 존재하지 않을 경우 캐시 미스라 하고 DB에서 데이터를 가져오고 해당 데이터의 복사본을 캐시 서버에 저장하고 클라이언트로 반환합니다.
외부 캐시의 장점은 Application 서버가 확장되도 동일한 외부 캐시 서버를 공유할 수 있다는 점입니다. 이를 글로벌 캐시라고 합니다.
In-process Caching

Redis나 MemCached를 새로 구성하지 않고 Application 서버의 메모리를 활용하는 방법입니다. 이 방법은 앞서 나온 방법보다 훨씬 빠른 캐싱 방법입니다. 비용이 빠른 구체적인 이유는 External Caching과는 다르게 네트워크 I/O 비용이 발생하지 않기 때문입니다. 하지만 서버를 확장하는 경우 서버마다 동기화가 필요하다는 단점이 존재합니다. 동기화를 하지 않을경우 데이터 정합성이 보장되지 않을 수 있기 때문에 문제가 발생합니다.
CDN

CDN은 콘텐츠 전송 네트워크로 콘텐츠를 제공해주는 서버를 클라이언트와 좀 더 가까운곳에서 캐시할 수 있도록 분산된 서버 네트워크 입니다. CDN은 메모리와 디스크 속도의 차이를 최적화하는 것이 아닌 네트워크 지연 시간을 최적화하는 것입니다. 위 그림에서 CDN이 없을경우 클라이언트는 거리상으로 더 먼 오리진 서버에서 직접 콘텐츠 데이터를 받아와야 합니다.
1. 사용자가 이미지와 같은 콘텐츠 데이터를 요청합니다.
2. 해당 요청은 사용자의 위치를 기준으로 가장 가까운 엣지 서버로 전송됩니다.
3. CDN 서버에 요청한 이미지가 이미 존재하는 경우라면 이미지 데이터를 바로 가져옵니다. (캐시 히트)
4. 존재하지 않는 경우라면 CDN 서버에서 오리진 서버로 필요한 이미지 데이터를 가져와서 캐싱합니다. (캐시 미스)
CDN은 정적 미디어 캐싱 외에도 훨씬 많은 일을 할 수 있습니다. 예를 들면, 공개 API 응답, HTML 페이지 캐싱, 엣지 로직으로 콘텐츠의 개인화가 가능합니다. 하지만 주로 많이 사용되는 것은 미디어 전송(이미지, 비디오, 파일)과 관련된 것입니다.
Client-side Caching

클라이언트 측 캐시는 데이터가 사용자의 기기와 브라우저나 앱에 직접 저장되는 방식으로 불필요한 네트워크 호출을 방지할 수 있습니다.
예를 들어 HTTP의 캐시나 브라우저 자체 내의 로컬 저장소가 있습니다.
캐시 아키텍처
Cache-aside

캐시 미스가 발생하는 경우 DB에서 조회한 후 사용자에게 반환해 지연 시간이 증가합니다.
Write-through

애플리케이션이 먼저 캐시에 데이터를 작성한 후 캐시는 해당 데이터를 DB에 동기적으로 기록한 후 사용자에게 반환하는 방식입니다.
따라서 캐시와 DB가 모두 업데이트 될 때까지 쓰기 작업이 완료된 것으로 간주하지 않습니다. Redis나 MemCached 같은 도구들은 데이터베이스 쓰기 로직을 일반적으로 지원하지 않기 때문에 이 부분을 자동으로 실행할 무언가가 필요합니다.
이 방법의 단점은 Redis와 Database 두 곳에 전부 쓰기 작업이 완료되야 하므로 쓰기 속도가 느려진다는 점과 읽히 지도 않을 여러 데이터로 캐시를 오염시킬 수 있다는 것입니다. 또한 캐시 쓰기는 성공했지만 DB 쓰기가 실패할 경우 혹은 그 반대의 경우 데이터 일관성이 깨질 수도 있습니다.
Write-behind

Write-through 방법과 비슷하지만 차이점으로는 Cache에서 DB에 동기화를 할때 비동기로 진행한다는 점입니다.
이 구성은 높은 쓰기 처리량이이 중요하고 약간의 지연이 허용되는 경우에 사용합니다.
Read-through

Read-through는 캐시를 통한 읽기 방식입니다. 이전 Cache aside와 다른 점은 캐시 서버에서 직접 DB를 조회한다는 점입니다.
이 방식은 CDN 서버가 동작하는 방식입니다.
캐시 제거 정책
Least Recently Used
최근에 사용되지 않은 항목을 제거합니다. 가장 흔한 방식입니다.
Least Frequently Used
최근에 접근했더라도, 사용 빈도가 가장 낮은 항목을 제거합니다. 접근 패턴이 한쪽으로 크게 치우친(특정 키만 매우 자주 쓰이는) 경우에 좋습니다.
First-In-First-Out
최근에 접근했더라도, 사용 빈도가 가장 낮은 항목을 제거합니다.
Time-To-Live
각 항목이 정해진 시간뒤에 만료됩니다. 사용자 세션이나 API 응답 등과 같이 시간이 지나면서 효력을 잃을 수 있는 데이터에 매우 유용합니다.
캐시 사용시 발생하는 문제
Cache Stamped

이 현상은 TTL이 만료되는 경우 발생할 수 있습니다.
이 문제는 TTL 시간을 늘리는 방법과 여러 요청이 동시에 들어오는 경우 하나의 요청에 대해서만 캐싱 데이터를 적재를 하는 동안 나머지 요청들은 대기시키는 것입니다.
Cache Consistency

캐싱된 데이터와 DB의 데이터가 불일치할 수 있습니다. 예를 들어 사용자가 이름을 변경하는 경우 DB에는 변경이 되었지만 캐시에 캐싱된 데이터는 변경되기 이전의 데이터를 갖고 있을 수 있습니다.
이 문제는 DB에 데이터를 쓰는 경우 캐시에 저장된 오래된 버전의 데이터를 무효화하는 것입니다. 혹은 짧은 TTL 시간을 사용해 일관성을 유지 할 수 있습니다.
Hot Key

핫 키는 다른 캐시 키보다 훨씬 많은 트래픽이 집중되는 키를 의미합니다. 캐시는 빠른 조회로 성능 이점을 제공하지만, 특정 키에 요청이 과도하게 몰리면 해당 키가 위치한 노드에 지연이 발생하고 캐시의 이점이 줄어들 수 있습니다. 이를 완화하기 위해 캐시 클러스터를 구성해 트래픽을 여러 노드로 분산하고, 필요하면 레플리카 활용, 키 분산(키 샤딩), 로컬 캐시 등의 기법을 함께 적용합니다.
정리
캐싱을 도입해야 하는 경우
- 읽기 요청이 많은 워크로드
- 비용이 무거운 쿼리
- 데이터베이스 CPU 사용률이 높은 경우
- 지연시간 요구사항이 빡빡한 경우
캐싱을 도입하는 방법
- 병목 지점을 파악합니다.
- 무엇을 캐시할지 결정합니다.
- 캐시 아키텍처를 선택합니다.
- 캐시 제거 및 만료 정책을 정합니다.
- 캐싱의 단점과 부작용을 해결합니다.
'서버' 카테고리의 다른 글
| API Gateway (0) | 2026.01.06 |
|---|---|
| DB Index (0) | 2026.01.02 |
| [BOJ] 3151: 합이 0 (0) | 2026.01.02 |
| 선착순 결제 API 개선기 #1 (0) | 2025.12.31 |
| LEAD:ME 아키텍처에서 발생할 수 있는 문제점 (0) | 2025.12.30 |