캐싱 전략 (Redis / CDN)
캐싱은 가장 빠른 성능 개선 수단 중 하나입니다. 올바른 위치에 올바른 전략으로 적용하면 DB 부하를 90% 이상 줄일 수 있습니다.
캐시 계층 구조
Section titled “캐시 계층 구조”클라이언트 └─ CDN (Cloudflare / CloudFront) ← 정적 자산, API 응답 └─ API 서버 └─ Redis (인메모리 캐시) ← DB 조회 결과, 세션, 연산 결과 └─ Database요청이 위쪽 계층에서 처리될수록 빠르고 비용이 낮습니다.
Redis 캐싱 패턴
Section titled “Redis 캐싱 패턴”Cache-Aside (Lazy Loading)
Section titled “Cache-Aside (Lazy Loading)”가장 범용적인 패턴입니다. 읽기 요청 시 캐시를 먼저 확인합니다.
def get_user(user_id: str): cache_key = f"user:{user_id}"
# 1. 캐시 확인 cached = redis.get(cache_key) if cached: return json.loads(cached) # Cache Hit
# 2. Cache Miss → DB 조회 user = db.query("SELECT * FROM users WHERE id = ?", user_id)
# 3. 캐시에 저장 (TTL: 5분) redis.setex(cache_key, 300, json.dumps(user)) return user장점: 실제로 요청된 데이터만 캐싱 단점: 첫 요청은 항상 DB 조회 (Cache Miss 페널티)
Write-Through
Section titled “Write-Through”데이터를 쓸 때 DB와 캐시를 동시에 업데이트합니다.
def update_user(user_id: str, data: dict): # DB 업데이트 db.execute("UPDATE users SET ... WHERE id = ?", user_id)
# 캐시도 즉시 업데이트 cache_key = f"user:{user_id}" redis.setex(cache_key, 300, json.dumps(data))장점: 캐시와 DB 일관성 보장 단점: 쓰기 레이턴시 증가, 읽히지 않는 데이터도 캐싱
Write-Behind (Write-Back)
Section titled “Write-Behind (Write-Back)”캐시에 먼저 쓰고 DB 반영을 비동기로 처리합니다.
쓰기 요청 → Redis 즉시 저장 → 응답 반환 ↓ (비동기) DB 저장 (배치)장점: 쓰기 성능 최대화 단점: 장애 시 데이터 유실 위험 — 금융·결제 데이터에는 사용 금지
TTL 설계
Section titled “TTL 설계”# TTL 기준 예시CACHE_TTL = { "user_profile": 300, # 5분 — 자주 변경 "product_info": 3600, # 1시간 — 가끔 변경 "exchange_rate": 60, # 1분 — 실시간 필요 "static_config": 86400, # 24시간 — 거의 변경 없음}Cache Stampede 방지
Section titled “Cache Stampede 방지”동시에 많은 요청이 Cache Miss를 만나 DB에 몰리는 현상입니다.
import redisimport threading
def get_with_lock(cache_key: str, fetch_fn, ttl: int): cached = redis.get(cache_key) if cached: return json.loads(cached)
lock_key = f"lock:{cache_key}" # 락 획득 시도 (1개 요청만 DB 조회) if redis.set(lock_key, "1", nx=True, ex=5): try: data = fetch_fn() redis.setex(cache_key, ttl, json.dumps(data)) return data finally: redis.delete(lock_key) else: # 락 대기 후 재시도 time.sleep(0.1) return get_with_lock(cache_key, fetch_fn, ttl)CDN 캐싱
Section titled “CDN 캐싱”Cache-Control 헤더 설계
Section titled “Cache-Control 헤더 설계”# 정적 자산 (이미지, JS, CSS) — 장기 캐싱Cache-Control: public, max-age=31536000, immutable
# API 응답 — 단기 캐싱Cache-Control: public, max-age=60, stale-while-revalidate=300
# 사용자별 데이터 — CDN 캐싱 금지Cache-Control: private, no-storeCloudflare Page Rules 예시
Section titled “Cloudflare Page Rules 예시”| URL 패턴 | 캐시 설정 |
|---|---|
*.testforge.kr/assets/* | Cache Everything, TTL 30일 |
*.testforge.kr/api/public/* | Cache Everything, TTL 60초 |
*.testforge.kr/api/user/* | Bypass Cache |
Redis 운영 모니터링
Section titled “Redis 운영 모니터링”# 캐시 히트율 확인 (keyspace_hits / (hits + misses))redis-cli INFO stats | grep -E "keyspace_hits|keyspace_misses"
# 메모리 사용량redis-cli INFO memory | grep used_memory_human
# 만료 예정 키 수redis-cli INFO keyspace캐시 히트율 목표: 90% 이상. 히트율이 낮으면 TTL이 너무 짧거나 캐시 키 설계가 잘못된 것입니다.
부하테스트로 캐싱 효과 검증
Section titled “부하테스트로 캐싱 효과 검증”캐싱 적용 전후를 비교해 실제 효과를 측정하세요.
측정 항목:- P95/P99 레이턴시 변화- DB 쿼리 수 감소율- 서버 CPU 사용률 변화이 가이드를 내 서비스에 직접 적용해 보세요.
TestForge 무료 스캔 시작 →