DRF에서의 Caching은 Django의 캐싱을 이용한다.
Django의 method_decorator를 사용하여 cache_page, vary_on_cookie, vary_on_header등의 다른 캐시 decorator를 사용 할 수 있다.
Django 에서는 여러 레벨의 캐시를 제공한다.
만들기 어려운 부분을 캐시 할 수도 있고, 전체 사이트를 캐시 할 수도 있다.
settings.py 에 다음과 같이 설정이 가능하다.
CACHES = {
'default': {
'BACKEND': 'cache의 바인딩 경로',
'LOCATION': 데몬이 실행중인 위치('ip:port 혹은 unix소켓 경로')
}
}
Memcached
Memory-based cache 서버이다.
daemon으로써 동작하고, 특정한 양의 RAM을 할당받는다.
데이터의 Add, Retrieve, delete의 속도를 높여준다.
메모리에 저장하기때문에, database, filesystem접근 overhead가 없다.
설정
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.PyMemcacheCache',
'LOCATION': [
'127.0.0.1:11211', #location은 여러개가 올 수 있다.
'unix:/tmp/memcached.sock' #unix 소켓을 이용 할 수 있다.
]
}
}
Redis
In memory database이지만, 캐시로도 사용 할 수 있다.
Redis를 위한 binding(redis-py/hiredis-py)을 설치해야 한다.
redis-py는 Django에서 지원
설정
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.redis.RedisCache',
'LOCATION': [
'redis://127.0.0.1:6379', #location은 여러개가 올 수 있다.
'redis://username:password@127.0.0.1:6379' #인증이 필요한 경우
]
}
}
캐시된 데이터를 데이터베이스에 저장 할 수 있다.
데이터베이스에 인덱스가 잘 설정된 경우 효과가 좋다.
Database 수준에서, 만료된 엔트리에 대한 정리를 지원하지 않는다.
대신, 만료된 엔트리는 add(), set(), touch()가 호출될 때마다 정리된다.
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
'LOCATION': 'database cache table'
}
}
데이터베이스 캐시 테이블 만들기
테이블의 이름은 LOCATION을 참조하여 만들어 진다.
데이터베이스 캐시를 여러개 사용 할 경우, 각각의 캐시마다 하나의 테이블을 만든다.
python manage.py createcachetable
여러개의 데이터베이스를 사용하여 데이터베이스 캐시를 할 경우, 이를 위한 라우팅을 작성해야 한다.
라우팅 설정을 하지 않는 경우 default DB를 사용하게 된다.
DB 캐시 테이블이 django_cache 애플리케이션의 CacheEntry라는 모델로 나타냄
라우팅 예시
class CacheRouter:
"""A router to control all database cache operations"""
# 모든 read는 cache_replica로
def db_for_read(self, model, **hints):
"All cache read operations go to the replica"
if model._meta.app_label == 'django_cache':
return 'cache_replica'
return None
# 모든 write는 cache_primary로
def db_for_write(self, model, **hints):
"All cache write operations go to primary"
if model._meta.app_label == 'django_cache':
return 'cache_primary'
return None
# 동기화는 cache_primary만 허용
def allow_migrate(self, db, app_label, model_name=None, **hints):
"Only install the cache model on primary"
if app_label == 'django_cache':
return db == 'cache_primary'
return None