Published on

[Django] 장고의 캐시설정

Authors
  • avatar
    Name
    Almer Minified
    Twitter

[Django] 장고의 캐시

장고의 캐시 처리 방법

캐시를 통해 데이터베이스 쿼리, 템플릿 렌더링 결과, 기타 쿼리 결과 등을 저장할 수 있다. 캐시는 자주 사용되거나 변하지 않는 데이터를 빠르게 액세스할 수 있는 임시 저장소로 메모리에다가 저장해놓고 불러오기 좋은 경우에 좋다. 당연히 데이터베이스를 계속 조회하는 것보다 메모리에 놓고 빠르게 불러오는 게 편하다. 데이터베이스를 계속 조회하는 건 상당히 무거운 작업이기떄문에 그 쿼리 결과 자체를 어떤 변수에 넣어서 저장해두는 것이다. 대부분 경우엔 웹에서 읽기 요청이 많고 쓰기 요청이 적기 떄문에 같은 결과를 요청하는 요청이 많다. 그러므로 캐시를 써두면 같은 읽기 작업을 서비스 구조에 따라 10배정도도 줄일 수 있다.

기본적인 캐시 설정

주로 멤캐시와 레디스를 쓴다. 멤캐시를 쓴다면,

CACHES = {
  'default': {
      'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
      'LOCATION': '127.0.0.1:11211',
  }
}

레디스를 쓴다면,

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

위에서처럼 여기서 LOCATION은 캐시 서버의 주소와 사용할 데이터베이스를 지정하는 역할이다. 물론 로컬에서 사용할 때도 서버를 따로 켜놓고 해야한다. 맥북같은 경우는 brew를 이용해 쉽게 설치할 수 있다.

뷰에서 캐시 적용

뷰에다가 그대로 캐시를 적용할 수 있다. 뷰에서 리턴되는 결과 자체를 캐시에 넣어서 보관하는 것이다.

from django.views.decorators.cache import cache_page

@cache_page(60 * 15)  # 캐시 유지를 15분으로 설정하기
def my_view(request):
  # 뷰 로직

이렇게 하면 그 뷰의 결과 자체가 캐시에 저장되게 된다. 물론 주의해야 할 것은 어떤 주소에 요청이 오면 그대로 다 저장되기 때문에 유저에 따라서 다르게 결과를 주어야 한다면 뷰가 아니라 따로 cache.get, cache.set을 이용해서 처리해줘야 할 것이다. 조금 섬세하지만 이게 마음 편하기도 하다.

템플릿 캐시 적용

템플릿에서도 캐시를 쓸 수 있다. 장고 템플릿 태그 자체에서 바로 캐시를 쓰게 설정되어있다.

{% load cache %}
{% cache 500 sidebar %}
... cache와 endcache사이에 있는 부분을 캐시로 처리함 ...
{% endcache %}

이렇게 해놓으면 500초 동안 캐시가 지속되며 저 cache태그와 endcache태그 사이에 있는 내용이 저장된다.

cache.set과 cache.get 사용

저렇게 뷰와 템플릿 말고 직접 캐시를 다루는 방법도 있다. 우선 cache.set의 사용법을 보면


from django.core.cache import cache

def expensive_calculation():
    # 너만의 쿼리
    return result

# 캐시에 데이터 저장
result = expensive_calculation()
cache.set('your_key', result, timeout=300)  # 300초 동안 캐시 유지

이렇게 된다. 직접 cache에 키를 지정해서 저장하는 것이다. 이제 저장해놓은 캐시를 내가 지정했던 your_key를 이용해 가져오자.

from django.core.cache import cache

# 캐시에서 데이터 가져오기
result = cache.get('my_key', default=None)

if result is None:
    # 캐시에 데이터가 없을 경우의 처리
    result = expensive_calculation()
    cache.set('my_key', result, timeout=300)    

이러면 그대로 캐시를 가져올 수 있다.

주의사항

캐시는 데이터베이스의 업데이트가 자동으로 반영되는 것이 아니다. 그러므로 이 부분을 고려해서 설계해야 한다. 실시간으로 변하는 서비스를 위해서는 캐시서버와의 polling을 구현해 줘야 할 수도 있다.