Redis를 활용한 저수준 캐시 API와 쿼리 결과 캐싱

웹 애플리케이션의 성능 병목은 대부분 데이터베이스 I/O에서 발생함. 캐싱을 통해 자주 사용되지만 잘 변하지 않는 데이터를 메모리에 저장하여 API 응답 시간을 단축하고 데이터베이스 부하를 줄임

Django에 Redis 캐시 연동

패키지 설치

pip install django-redis

settings.py 설정

CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379/1",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    }
}

Django 저수준 캐시 API

주요 메서드

  • cache.set(key, value, timeout): 캐시에 데이터 저장

  • cache.get(key, default=None): 캐시에서 데이터 조회

  • cache.get_or_set(key, default, timeout): 캐시 조회 후 없으면 저장하고 반환

  • cache.delete(key): 특정 캐시 삭제

get_or_set 활용 예시

from django.core.cache import cache

def get_popular_articles(limit=5):
    cache_key = f'articles:popular:{limit}'
    
    def _get_from_db():
        return list(Article.objects.order_by('-view_count')[:limit].values('id', 'title'))

    return cache.get_or_set(cache_key, _get_from_db, 60 * 60)

ViewSet 쿼리 결과 캐싱

list 메서드 캐싱

def list(self, request, *args, **kwargs):
    query_params = request.query_params.urlencode()
    cache_key = f'articles:list:{query_params}'
    
    cached_data = cache.get(cache_key)
    if cached_data:
        return Response(cached_data)

    queryset = self.filter_queryset(self.get_queryset())
    serializer = self.get_serializer(queryset, many=True)
    data = serializer.data
    
    cache.set(cache_key, data, 60 * 5)
    return Response(data)

캐시 무효화 전략

시간 기반: 짧은 timeout 설정으로 자동 만료

이벤트 기반: Django Signals 활용

from django.db.models.signals import post_save, post_delete
from django.dispatch import receiver

@receiver(post_save, sender=Article)
def invalidate_article_cache_on_save(sender, instance, **kwargs):
    cache.delete(f'articles:retrieve:{instance.pk}')

실무 주의사항

캐시 키 명명 규칙

  • 명확하고 일관된 패턴 사용: <app>:<model>:<view_type>:<identifier>

직렬화된 데이터 캐싱

  • QuerySet 객체 대신 직렬화 완료된 데이터(JSON, Python 딕셔너리/리스트) 저장

캐시 스탬피드 방지

  • get_or_set 사용으로 동시 요청 시 하나의 프로세스만 DB 조회 실행

캐싱 대상 선별

  • 자주 변경되는 데이터, 거의 사용되지 않는 데이터, 사용자별 민감한 데이터는 캐싱 지양

Last updated