🗄️ 데이터베이스

캐시

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}` 형태로 수정하겠습니다."

⚠️ 주의사항

🔗 관련 용어

📚 더 배우기