캐시 계층 구조는 어떻게 설계해야 하는가
- 캐시 계층 구조(L1, L2, L3)의 개념
- 애플리케이션, DB CDN 등 다양한 수준에서 캐시가 어떻게 동작하는가
- 각 계층별 캐시의 목적과 역할 구분하기
- 실제 서비스 환경에서 여러 캐시 계층이 함께 동작하는 구조
- 대규모 트래픽 환경에서 캐시 계층 구조가 성능에 미치는 영향
캐시 계층 구조 개요
캐시는 시스템의 여러 위치에서 동작할 수 있음
캐시가 배치되는 위치에 따라 L1 / L2 / L3 캐시로 구분됨
각 계층은 접근 속도, 저장 용량, 유지 비용이 다르며 "가까운 곳일수록 빠르고, 비쌀수록 용량이 작다" 라는 특성을 가짐
| 계층 | 위치 | 속도 | 용량 | 주 용도 |
| L1 | CPU, 앱 메모리 | 매우 빠름 | 작음 | 즉시 접근 가능한 데이터 캐싱 |
| L2 | 애플리케이션 외부(Redis, Memcached 등..) | 빠름 | 중간 | 여러 서버간 공유 캐시 |
| L3 | CDN, DB 캐시, 프록시 서버 등등.. | 상대적으로 느림 | 큼 | 전역적 데이터 배포 및 캐시 |
캐시의 계층적 접근 흐름
사용자가 요청함
- > L1(CPU, 애플리케이션 메모리)에서 데이터를 찾음
- > 없으면 L2(애플리케이션 외부, Redis 등)에서 데이터를 찾음
- > 없으면 L3(CDN, DB캐시, 프록시 등)에서 데이터를 찾음
- > 없으면 DB로..
상위 캐시에서 하위 캐시로 이어짐
L1 캐시(애플리케이션 레벨 캐시, CPU)
1. 개념
L1은 가장 가까운 계층으로, 애플리케이션 내부 메모리에 존재함
CPU의 L1 캐시처럼 프로그램이 실행중인 프로세스에서 즉시 접근할 수 있어서 지연(레이턴시)이 거의 없음
예 : HashMap, ConcurrentHashMap, Caffeine, Guava Cache
2. 예제
import java.util.*;
public class AppLevelCache {
private static final Map<String, String> cache = new HashMap<>();
public static String getData(String key) {
if(cache.containsKey(key)) { // cache에 key가 존재한다면, 검증
return "[L1 Hit] " + cache.get(key); // Hit
}
// 없다면, DB에서 데이터를 가져오고 cache에 값을 넣음, Miss
String data = "데이터 : " + key;
cache.put(key, data);
return "[L1 Miss]" + data;
}
public static void main(String[] args) {
System.out.println(getData("user:1"));
System.out.println(getData("user:1"));
}
}
결과
[L1 Miss]데이터 : user:1
[L1 Hit] 데이터 : user:1
* 단일 서버나 스레드 기반 빠른 캐시 조회가 필요할 때 L1 캐시를 사용함
팁
* L1 캐시는 요청이 많고 동일한 데이터를 반복 조회하는 경우 유용함
* 단, 서버가 여러대라면 각 인스턴스의 캐시가 서로 다른 데이터를 가질 수 있어서 일관성이 깨질 수 있음
L2 캐시(외부 캐시 서버)
1. 개념
L2 캐시는 서버간 공유 가능한 캐시 계층임
Redis나 Memcached같은 외부 캐시 서버가 이에 해당함
여러 애플리케이션 인스턴스가 같은 L2 캐시를 공유하기 때문에, 일관성을 유지하면서 분산 환경에서도 효율적 캐싱이 가능
2. 구조
* 모든 서버가 동일한 캐시 서버(Reidis 등)에 접근해서 데이터를 공유함
* L1 캐시에서 캐시 미스가 발생하면, L2 캐시에서 데이터를 가져옴
3. 예제(redis.clients.jedis.Jedis import 필요)
import redis.clients.jedis.Jedis;
public class RedisCacheExample {
public static void main(String[] args) {
// Redis 연결(기본 포트는 6379)
try(Jedis jedis = new Jedis("localhost", 6379)) {
String key = "user:100";
if(jedis.exists(key)) {
System.out.println("[L2 Hit] 캐시에서 데이터 조회" + jedis.get(key));
} else {
System.out.println("[L2 Miss] 캐시 미스 발생 -> DB에서 조회 후 저장");
// 실제 서비스에서는 DB 조회 결과를 가져와서 저장함
String data = "김블러퍼";
jedis.setex(key, 10, data); // TTL 10초 설정
System.out.println("[L2 Update] Redis에 데이터 저장 완료");
}
// 데이터 확인
System.out.println("현재 Redis 데이터 : " + jedis.get(key));
}
}
}
* L2 캐시는 여러 서버가 같은 데이터를 캐시하여 데이터 일관성을 유지함
L3 캐시(CDN 및 DB 캐시, 가장 느림)
1. 개념
L3 캐시는 글로벌 트래픽 분산 및 네트워크 지연 최소화를 위한 캐시 계층임
대표적으로 CDN(Content Delivery Network)나 DB Query Cache가 해당함
CDN 캐시 : 정적 자산(이미지, JS, CSS)을 사용자 근처 엣지 서버에 저장함
- > Cloudflare, Akamai
DB 캐시 : 반복되는 SQL 쿼리 결과를 캐싱함
- > MySQL Query cache, PostgreSQL Plan Cache
2. CDN 캐시 동작 흐름
* CDN 캐시는 사용자의 지리적 위치에 따라 가장 가까운 엣지 서버에 데이터를 제공하여 지연시간(레이턴시)를 획기적으로 단축함
팁
* CDN 캐시는 이미지, 동영상, 정적 HTML 등 변경이 적은 자산에 이상적임
* DB 캐시는 고정 쿼리(select * from category 등..)에 사용하면 서버 부하를 줄일 수 있음
캐시 계층 통합 구조
캐시 계층은 단일 수준으로 동작하지 않고, 여러 계층이 함께 작동하여 전체 성능을 극대화할 수 있음
L1 -> L2 -> L3 순으로 캐시를 구성하면, 데이터 접근 속도는 빨라지고 DB 부하가 감소한다고 함
정리
| 캐시 계층 | 주요 위치 | 예시 | 특징 |
| L1 캐시 | 애플리케이션 내부 | HashMap, Guava Cache | 초고속, 단일 인스턴스 적용 |
| L2 캐시 | 외부 캐시 서버 | Redis, Memcached | 다중 서버 공유, 확장성 우수 |
| L3 캐시 | CDN, DB 레벨 | Cloudflare, MySQL Query Cache | 전역 배포, 네트워크 최적화 |
'Spring Boot > Cache' 카테고리의 다른 글
| 캐시 아키텍처와 종류 : 실무 캐시 아키텍처 설계 (0) | 2026.01.04 |
|---|---|
| 캐시 아키텍처와 종류 : 주요 캐시 솔루션 비교 (0) | 2026.01.02 |
| 캐시의 기본 개념과 필요성 : 캐시 적용 고려사항 (0) | 2025.12.31 |
| 캐시의 기본 개념과 필요성 : 대용량 트래픽에서 캐시의 역할 (0) | 2025.12.21 |
| 캐시의 기본 개념과 필요성 : 캐시의 핵심 원리 (0) | 2025.12.19 |