Redis를 활용한 저수준 캐시 API와 쿼리 결과 캐싱
웹 애플리케이션의 성능 병목은 대부분 데이터베이스 I/O에서 발생함. 캐싱을 통해 자주 사용되지만 잘 변하지 않는 데이터를 메모리에 저장하여 API 응답 시간을 단축하고 데이터베이스 부하를 줄임
Django에 Redis 캐시 연동
패키지 설치
pip install django-redissettings.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
