본문 바로가기

Back-end & Server/Django

[Django] 캐시 프레임워크

728x90
반응형

웹 서버는 사용자가 웹 페이지를 요청할 때마다 데이터베이스 쿼리부터 비즈니스 로직, 템플릿 렌더링, 비즈니스 로직에 이르기까지 모든 종류의 계산을 수행해 웹 사이트 방문자가 볼 수 있는 웹 페이지를 만듦

 

만약 중간 규모 이상의 트래픽이 많은 웹 사이트의 경우, 가능한 많은 오버헤드를 줄이는 것이 필수

 

이러한 문제를 해결하는 방법 중 하나로 캐시(Cache)를 사용할 수 있음

  • 동적으로 생성된 웹 페이지에서 캐시가 작동하는 의사코드
given a URL, try finding that page in the cache

if the page is in the cache:
    return the cached page
    
else : 
    generate the page
    save the generated page in the cache (for next time)
    return the generated page

 

Django는 동적 웹 페이지를 저장할 수 있는 캐시 시스템이 있기 때문에 각 요청을 계산할 필요 없고, 다른 수준의 캐시 세분성을 제공

  • 특정 뷰의 결과물을 캐싱
  • 제작하기 어려운 부분만 캐싱
  • 전체 웹 사이트를 캐싱

 

Django는 Squid 및 웹 브라우저 기반 캐시와 같은 다운 스트림 캐시에서도 잘 작동함

  • 웹 사이트의 어느 부분이 캐시돼야 하는지와 캐시 방법에 대한 힌트(HTTP 헤더를 통해)를 제공할 수 있는 캐시 유형

 

캐시 설정

캐시 시스템은 캐시된 데이터가 어디에 있어야 하는지(파일 시스템, 데이터베이스, 직접 메모리 등)를 명시에줘야 함

  • 캐시 성능에 영향을 미치는 중요한 결정임
  • 캐시 환경 설정은 설정 파일의 캐시 설정에 있음

 

 

Memcached

 

memcached - a distributed memory object caching system

What is Memcached? Free & open source, high-performance, distributed memory object caching system, generic in nature, but intended for use in speeding up dynamic web applications by alleviating database load. Memcached is an in-memory key-value store for s

memcached.org

  • Django가 기본으로 지원하는 가장 빠르고 효율적인 캐시 유형
  • 메모리 기반 캐시 서버
  • 사용방법
    • Memcached를 설치하고 Memcached 바인딩(pythonmemcached or pylibmc)을 설치해야 함
    • Django의 캐시 설정을 다음과 같이함
# python-memcached
CACHES = {
    'default':{
        'BACKEND' : 'django.core.cache.backends.memcached.MemcachedCache'
        # ip:port or unix:path
        'LOCATION' : '127.0.0.1:11211' # ip:port
        # ip는 Memcached 데몬ip 주소, port는 Memcached가 실행되는 포트 또는 unix:path 값
        #'LOCATION': 'unix:/tmp/memcached.sock' unix:path 		
        # path는 Memcached Unix 소켓 파일 경로
    }
}

# pylibmc
CACHES = {
    'default':{
        'BACKEND' : 'django.core.cache.backends.memcached.PylibMCCache'
        'LOCATION' : '127.0.0.1:11211'
    }
}
# 여러 서버에서 캐시를 공유
# 프로그램은 각 세스템의 캐시 값을 복제하지 않고 컴퓨터 그룹을 단일 캐시로 처리
CACHES = {
    'default':{
        'BACKEND' : 'django.core.cache.backends.memcached.PylibMCCache'
        'LOCATION' : [
             '172.19.26.240:11211',
             '172.19.26.242:11212',
             '172.19.26.244:11213'
         ]
    }
}
  • Memcached은 메모리 기반 캐싱 방식이기 때문에 서버가 충돌하면 데이터가 손실
  • 캐시 저장소는 데이터의 영구적인 저장을 위한 것이 아님

 

 

Redis(Django 4.0 부터 추가) 캐싱

 

Django

The web framework for perfectionists with deadlines.

docs.djangoproject.com

 

 

데이터베이스 캐싱

  • Django는 캐시된 데이터를 데이터베이스에 저장할 수 있음
  • 빠르게 잘 색인된 데이터베이스 서버를 갖고 있다면 가장 잘 작동
  • 사용방법(캐시 테이블 이름 : cache_table)
CACHES = {
    'default':{
        'BACKEND' : 'django.core.cache.backends.db.DatabaseCache'
        'LOCATION' : 'cache_table'
    }
}
  • 먼저 데이터베이스 캐시를 사용하기 전에 다음과 같은 명령으로 캐시 테이블을 만들어야함, 이름은 LOCATION 설정에서 가져옴
python manage.py createcachetable
  • 기존 테이블을 건드리지 않고, 누락된 테이블만 생성

 

여러 데이터베이스

  • 여러 데이터베이스에서 캐싱을 사용하는 경우 테이블에 대한 라우팅 지침도 설정해야함
  • 예시 : 라우터는 모든 캐시 읽기 작업을 cache_replica로 지시, cache_primary로 모든 쓰기를 보내고 캐시 테이블은 cache_primary에만 동기화됨
class CacheRouter:
    """A router to control all database cache operations"""

    def db_for_read(self, model, **hints):
        # 모든 캐시 일기 작은 복제본으로 이동
        if model._meta.app_label == 'django_cache':
            return 'cache_replica'
        return None

    def db_for_write(self, model, **hints):
        # 모든 캐시 쓰기 작업은 기본으로 이동
        if model._meta.app_label == 'django_cache':
            return 'cache_primary'
        return None

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        # 기본 캐시 모델만 설치
        if app_label == 'django_cache':
            return db == 'cache_primary'
        return None
  • 데이터베이스 캐시 모델에 대한 라우팅 방향을 지정하지 않으면 캐시 백엔드가 default 데이터베이스 사용함

 

 

파일 시스템 캐싱

  • 파일 기반 백엔드는 각 캐시 값을 직렬화해 개별 파일로 저장
  • 사용방법
CACHES = {
    'default':{
        'BACKEND' : 'django.core.cache.backends.filebased.FileBasedCache'
        'LOCATION' : '/var/tmp/django_cache', # 윈도우의 경우 'c:/foo/bar'
    }
}
  • LOCATION을 적절한 디렉터리에 설정, 디렉터리 경로는 절대경로
  • 디렉터리를 웹 서버가 실행되는 시스템 사용자가 읽고 쓸 수 있는지 확이해야 함

 

 

로컬-메모리 캐싱

  • 설정 파일에 다른 캐시가 지정돼 있지 않으면 로컬-메모리 캐싱이 기본 캐시
  • 사용방법
CACHES = {
    'default':{
        'BACKEND' : 'django.core.cache.backends.locmem.LocMemCache'
        'LOCATION' : 'unique-snowflake'
    }
}
  • LOCATION은 개별 메모리 저장소를 식별하는 데 사용
  • 하나의 locemem 캐시만 있으면 LOCATION 생략 가능, 둘 이상의 로컬 메모리 캐시가 있는 경우

 

 

더미 캐싱(개발용)

  • 실제로 캐시되지 않는 더미 캐시, 아무것도 하지 않고 캐시 인터페이스 만 구현
  • 개발/테스트 환경에 유용
  • 사용방법
CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.dummy.DummyCache',
    }
}

 

 

커스텀 캐시 백엔드 사용하기

  • 사용자 정의 캐시 백엔드를 사용할 경우
  • 사용방법
CACHES = {
    'default': {
        'BACKEND': 'path.to.backend',
    }
}

 

 

CACHE 설정의 인수

 

Django

The web framework for perfectionists with deadlines.

docs.djangoproject.com

 

  • 예시
CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
        'LOCATION': '/var/tmp/django_cache',
        'TIMEOUT': 60,
        'OPTIONS': {
            'MAX_ENTRIES': 1000
        }
    }
}

 

사이트별 캐시

캐시가 설정되면 캐싱을 사용하는 가장 간단한 방법은 전체 사이트를 캐시하는 것임

 

Django

The web framework for perfectionists with deadlines.

docs.djangoproject.com

 

뷰별 캐시

캐싱 프레임워크를 사용하는 좀 더 세밀한 방법은 개별 뷰의 출력을 캐싱하는 것

 

Django

The web framework for perfectionists with deadlines.

docs.djangoproject.com

 

URLconf에 per-view 캐시 지정하기

뷰별 캐시에서는 뷰가 캐시 된다는 사실을 하드코딩했음

이런 접근법은 캐시 시스템에 뷰를 연결하기 때문에 여러가지 이유로 이상적이지 않음

  • 캐시 기능이 없는 다른 웹 사이트에서 뷰 기능을 재사용하거나 캐시하지 않고 뷰 기능을 사용하고자 하는 사람들에게 뷰 기능을 배포 할 수 있음

 

이러한 문제들을 해결하는 방법으로 URLconf에 뷰 단위 캐시를 지정하는 방법임

 

Django

The web framework for perfectionists with deadlines.

docs.djangoproject.com

 

템플릿 조각 캐싱

더 많은 제어를 원하는 경우, 캐시 템플릿 태그를 사용해 템플릿 조각을 캐시할 수 있음

  • {% load cache %} : 템플릿에 이 태그에 대한 액세스 권한을 부여, 템플릿에 맨 위에 둬야함
  • {% cache %} ~ {% endcache %} : 주어진 시간 동안 블록 내용을 캐시
 

Django

The web framework for perfectionists with deadlines.

docs.djangoproject.com

 

저수준 캐시 API

 

Django

The web framework for perfectionists with deadlines.

docs.djangoproject.com

 

다운스트림 캐시

요청이 웹 사이트에 도착하기 전에도 사용자를 위해 웹 페이지를 캐시하는 시스템

 

Django

The web framework for perfectionists with deadlines.

docs.djangoproject.com

 

 

다양한 헤더(Vary 헤더)

Vary 헤더는 캐시 키를 작성할 때 캐시 메커니즘이 고려해야 하는 요청 헤더를 정의

 

Django

The web framework for perfectionists with deadlines.

docs.djangoproject.com

 

캐시 제어 : 다른 헤더 사용

 

Django

The web framework for perfectionists with deadlines.

docs.djangoproject.com

 

728x90
반응형

'Back-end & Server > Django' 카테고리의 다른 글

[Django] 보안  (0) 2023.02.06
[Django] 미들웨어(Middleware)  (0) 2023.02.06
[Django] 비 HTML 콘텐츠와 세션  (0) 2023.02.01
[Django] 배포  (0) 2023.01.31
[Django] 테스팅  (0) 2023.01.22