캐시
Cache
자주 사용하는 데이터를 빠른 저장소에 임시 보관. Redis, Memcached. 응답 시간 단축.
Cache
자주 사용하는 데이터를 빠른 저장소에 임시 보관. Redis, Memcached. 응답 시간 단축.
캐시(Cache)는 자주 접근하는 데이터를 빠른 저장소에 임시 보관하여 응답 시간을 단축하는 기술입니다. 데이터베이스 조회 결과, API 응답, 세션 정보 등을 메모리에 저장해 반복적인 연산이나 I/O를 줄입니다.
대표적인 캐시 솔루션으로 Redis(인메모리 데이터 구조 서버), Memcached(분산 메모리 캐시), Varnish(HTTP 가속기) 등이 있습니다. 캐시 전략에는 Cache-Aside(필요 시 로드), Write-Through(쓰기 시 동시 갱신), Write-Behind(비동기 쓰기) 등이 있습니다.
캐시 적중률(Hit Rate)이 높을수록 성능 개선 효과가 크며, 만료 정책(TTL)과 무효화(Invalidation) 전략이 데이터 일관성 유지의 핵심입니다.
import redis
import json
# Redis 연결
cache = redis.Redis(host='localhost', port=6379, db=0)
def get_user_profile(user_id: int) -> dict:
cache_key = f"user:profile:{user_id}"
# 1. 캐시 확인
cached = cache.get(cache_key)
if cached:
print("Cache HIT")
return json.loads(cached)
# 2. 캐시 미스 - DB 조회
print("Cache MISS")
profile = db.query(f"SELECT * FROM users WHERE id = {user_id}")
# 3. 캐시에 저장 (TTL 300초)
cache.setex(cache_key, 300, json.dumps(profile))
return profile
def update_user_profile(user_id: int, data: dict):
# DB 업데이트
db.update("users", user_id, data)
# 캐시 무효화 (삭제)
cache.delete(f"user:profile:{user_id}")
# 패턴: 캐시 데코레이터
from functools import wraps
def cached(ttl=60):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
key = f"{func.__name__}:{args}:{kwargs}"
result = cache.get(key)
if result:
return json.loads(result)
result = func(*args, **kwargs)
cache.setex(key, ttl, json.dumps(result))
return result
return wrapper
return decorator
PM: "상품 목록 API 응답이 2초나 걸린다는 불만이 많아요."
백엔드 개발자: "Redis 캐시 도입하면 50ms 이내로 줄일 수 있어요. 상품 정보는 자주 안 바뀌니까요."
PM: "재고나 가격 변동은요?"
백엔드 개발자: "상품 정보 업데이트할 때 캐시 무효화하고, 재고는 TTL 짧게 30초로 잡으면 됩니다."
면접관: "캐시 관련해서 발생할 수 있는 문제점과 해결 방안을 설명해주세요."
지원자: "Cache Stampede는 TTL 만료 시 동시 요청이 몰리는 문제인데, 락이나 확률적 조기 갱신으로 해결합니다. Cache Penetration은 존재하지 않는 키 반복 조회로 DB 부하가 생기는데, 빈 값도 캐싱하거나 Bloom Filter를 씁니다."
면접관: "캐시 일관성은 어떻게 보장하나요?"
지원자: "데이터 변경 시 캐시 삭제 후 다음 조회에 갱신하는 Cache-Aside가 일반적이고, 중요 데이터는 이벤트 기반 무효화를 씁니다."
리뷰어: "이 API에서 캐시 키에 user_id만 쓰고 있네요?"
개발자: "사용자별 데이터라서요."
리뷰어: "근데 이 응답에 언어 설정에 따라 다른 텍스트가 들어가잖아요. 캐시 키에 locale도 포함해야 해요."
개발자: "아, 맞네요. `user:{user_id}:locale:{locale}` 형태로 수정하겠습니다."