[Перевод] Руководство по кэшированию в Django
В этой статье речь пойдет о кэшировании в Django и веб-разработке в целом. Вы узнаете, что такое кэширование и о его преимуществах, как настроить кэширование в Django, какие бэкенд-системы поддерживают Django, а также о лучших практиках кэширования.
К концу статьи вы будете ясно понимать, что такое кэширование и как его можно реализовать в своих Django-проектах, чтобы достичь высокой производительности.
Все веб-разработчики имеют своей целью создание приложений с высокой производительностью. Разработка высокопроизводительных веб-приложений на популярном бэкенд-фреймворке Django не должна вызывать особых затруднений, поскольку Django поставляется с фреймворком кэширования. Он позволяет использовать различные механизмы кэширования, такие как кэш в памяти, файловое кэширование, кэш баз данных и т.д.
Введение в кэширование в Django
Кэширование в веб-разработке — это техника для повышения производительности приложений. Каждое веб-приложение обладает ресурсами, которые постоянно используют его юзеры. Ресурсом может быть что угодно — от простой веб-страницы до данных, хранящихся в базе данных. Кэширование играет важную роль в увеличении скорости доступа к ресурсам.
Базовые сценарии и варианты использования кэширования
Фреймворк кэширования Django предоставляет широкий спектр сценариев и вариантов использования, позволяющих разработчику кэшировать часто используемые данные. Ниже перечислены распространенные сценарии кэширования:
Кэширование страниц. Это сценарий, при котором полностью кэшируются часто посещаемые страницы сайта. При поступлении запроса приложение отображает кэшированные версии страниц, а не воспроизводит содержимое страницы с нуля.
Кэширование запросов к базе данных. Кэширование запросов к базе данных — хороший подход для приложений, которые часто обращаются к БД за информацией. Ряд запросов можно удовлетворить одним и тем же фрагментом кэшированных данных без необходимости обращения к базе данных. Это снижает количество обращений к базе данных и ускоряет время отклика сервера.
Кэширование сессий и аутентификации. Кэширование может использоваться для улучшения пользовательского опыта и ускорения времени отклика. Кэшированные данные позволяют пользователям легко перемещаться между разделами для которых требуется аутегнтификация, поэтому кеширование аутентификации и деталий сессий позволяет уменьшить количество избыточных операций аутентификации.
Преимущества кэширования в Django
Кэширование становится все более выгодным решением для веб-разработчиков в современных условиях, когда огромное значение играют как данные, так и скорость работы. Вот некоторые из преимуществ кэширования:
Повышение производительности. Кэширование повышает производительность веб-приложений за счет снижения нагрузки на сервер. Когда сервер получает запросы от приложения, кэширование гарантирует, что некоторые запросы будут удовлетворены с использованием ранее кэшированных данных. Это избавляет сервер от необходимости выполнять эти операции заново с нуля. В результате улучшается пользовательский опыт и ускоряется время отклика.
Сокращение времени отклика. Кэширование позволяет сократить время отклика за счет уменьшения количества обращений к базе данных. Кэширование позволяет при необходимости извлекать данные из удобного места. Поскольку некоторые данные требуют серьезных вычислений, на выполнение которых требуется определенное время, получение данных каждый раз из базы данных может быть не лучшим вариантом. Кэширование спасает ситуацию, сохраняя данные и оперативно предоставляя их при необходимости.
Оптимизация ресурсов. Кэширование данных или ресурсов в веб-приложении обеспечивает доступ к ресурсам без выполнения повторяющихся операций.
Настройка проекта Django
Основными задачами этого раздела является создание виртуального окружения и установка необходимых для проекта модулей. Чтобы создать виртуальную среду, введите в терминале команду:
$ python -m venv project
Все модули для проекта будут установлены внутри этой среды. Чтобы начать ее использовать, ее нужно активировать.
В Windows это можно сделать с помощью команды:
$ .\project\Scripts\activate
В macOS или Linux:
$ source project/bin/activate
Прежде чем приступить к реализации кэширования, необходимо настроить проект Django. Поэтому сначала установим Django. Откройте терминал и выполните команду:
$ pip install django
После успешной установки Django создадим приложение Django. Для создания проекта выполните команду:
$ django-admin startproject cachedproject
Перейдите в папку проекта. Здесь мы создадим Django-приложение. Выполните команду:
$ cd cachedproject
А затем выполните следующее:
$ python manage.py startapp cachedapplication
После успешного создания проекта и приложения нужно зарегистрировать приложение в проекте. Откройте файл settings.py
и приведите список INSTALLED_APPS
к следующему виду:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# new application added
'cachedapplication',
]
Примечание: чтобы использовать приложение в проекте Django, оно должно быть зарегистрировано в списке INSTALLED_APPS
.
Чтобы убедиться в том, что фреймворк Django успешно установлен, давайте его протестируем. В терминале выполните команду:
$ python manage.py runserver
Убедитесь, что вы получили результат, показанный на этом скриншоте:
terminal output
Теперь скопируйте URL-адрес и вставьте его в строку браузера. Должна появиться «страница успеха».
Настройка различных параметров кэширования в файле settings.py
Чтобы использовать кэширование, его необходимо настроить в Django-проекте. В этом разделе рассмотрим, как настраиваются различные системы кэширования, доступные в Django.
Кэширование в локальной памяти
Как следует из названия, кэширование в локальной памяти, иногда сокращенно называемое locmem, хранит кэшированные данные в оперативной памяти хостинга.
В качестве дефолтной системы кэширования Django автоматически использует кэширование в локальной памяти, если вы не указали альтернативный механизм кэширования в файле settings.py
. Это потокобезопасный, быстрый и отзывчивый метод кэширования.
Local Memory Cache менее пригодна для использования в продакшен средах, поскольку включает в себя механизм для каждого процесса, который предотвращает любое межпроцессное кэширование и заставляет отдельные процессы поддерживать свои частные экземпляры кэша. Тем не менее, это хороший выбор для разработки.
Чтобы настроить кэширование памяти в своем приложении, добавьте вот этот код в файл settings.py
:
# CACHES dictionary which contains caching configurations.
CACHES = {
# a cache alias or name. In this case, we use "default" as the alias.
"default": {
# Here, we're using the in-memory cache backend.
"BACKEND": "django.core.cache.backends.locmem.LocMemCache",
# LOCATION parameter gives a unique name or identifier to this cache instance.
"LOCATION": "unique-snowflake",
}
}
Файловое кэширование
При файловом кэшировании каждое кэшируемое значение сериализуется и хранится отдельно в файле. Эта система удобна для небольших приложений или в тех случаях, когда кэширование на основе памяти нецелесообразно.
Недостатком является относительно низкая скорость работы по сравнению с кэшированием на основе памяти.
Чтобы настроить файловое кэширование в приложении, добавьте следующий код в файл settings.py
:
# A CACHES dictionary, which contains caching configurations.
CACHES = {
# we use "default" as the alias.
"default": {
# Here, we're using the file-based cache backend.
"BACKEND": "django.core.cache.backends.filebased.FileBasedCache",
# LOCATION parameter to specify the file system path where cached data will be stored.
"LOCATION": "/var/tmp/django_cache",
}
}
Если вы разрабатываете под Windows, убедитесь, что путь к месту расположения начинается с буквы соответствующего диска, как показано ниже:
CACHES = {
"default": {
"BACKEND": "django.core.cache.backends.filebased.FileBasedCache",
"LOCATION": "C:/my/path-to/file",
}
}
Кэширование в базе данных
Помимо хранения кэша в файлах и оперативной памяти машины, Django предоставляет возможность хранить кэш в базе данных.
Это лучше всего работает, если у вас быстрый и хорошо индексируемый сервер баз данных.
Чтобы использовать кэширование базы данных в своем приложении, добавьте следующий код в файл settings.py
:
# CACHES dictionary, which contains caching configurations.
CACHES = {
# we use "default" as the alias.
"default": {
# Here, we're using the database-backed cache backend.
"BACKEND": "django.core.cache.backends.db.DatabaseCache",
# Provide a LOCATION parameter to specify the database table name where cached data will be stored.
"LOCATION": "my_cache_table",
}
}
Перед использованием кэша выполните следующую команду для построения таблицы базы данных, указанной в настройке выше:
python manage.py createcachetable
Приведенная выше команда создает в базе данных таблицу в нужном формате, который ожидает система кэширования БД Django. Имя таблицы берется из LOCATION
. В данном случае имя таблицы будет my_cache_table
.
Кэширование с помощью Memcached
Memcached — это система кэширования in-memory, которую используют веб-разработчики и некоторые компании с целью уменьшить количество обращений к базам данных и повысить производительность сайта.
В отличие от locmem-кэша, Memcached работает как демон, то есть сервер Memcached запускается как фоновый процесс, независимо от непосредственного взаимодействия с пользователем. Поэтому Memcached необходимо установить на машине отдельно. Затем в своем Django-приложении установите и настройте один из клиентов для работы с ним, например pylibmc или pymemcache, на использование Memcached.
Приложение Django можно связать с демоном Memcached, добавив настройки кэша, местоположение, IP-адрес и другие данные, как показано ниже:
# A dictionary named CACHES, which contains caching configurations.
CACHES = {
# "default" is the alias.
"default": {
# Here, we're using the Memcached cache backend.
"BACKEND": "django.core.cache.backends.memcached.PyMemcacheCache",
# LOCATION parameter to specify the Memcached server's IP address and port.
"LOCATION": "127.0.0.1:11211",
}
}
Технология Memcached особенно хорошо подходит для приложений с высокой нагрузкой на чтение или запросы, поскольку она была разработана для быстрого хранения и извлечения данных.
Есть у Memcached недостаток: поскольку данные хранятся в памяти, в случае падения сервера они будут потеряны.
Redis
Redis — это база данных in-memory, которую можно использовать для кэширования. Она кэширует данные, используя хранилище данных Redis in-memory. Redis славится своей быстротой и адаптивностью, что делает его отличным вариантом для распределенных систем и высокопроизводительного кэширования.
Для кэширования данных с помощью Redis в приложении необходим сервер Redis, работающий либо локально, либо на удаленной машине. Чтобы настроить Redis на своей машине, прочитайте руководство по началу работы с Redis.
После настройки сервера Redis необходимо установить клиент Python для Redis. Для установки используйте эту команду:
$ pip install django-redis
Интерфейс redis-py поддерживается Django нативно, или с помощью пакетов django-redis и redis.
Учитывая, что сервер Redis работает на localhost
(127.0.0.1), порт=6379
, для настройки кэширования Redis в приложении добавьте этот код в файл settings.py
:
# A dictionary named CACHES, which contains caching configurations.
CACHES = {
# "default" is the alias.
"default": {
# Here, we're using the Redis cache backend.
"BACKEND": "django.core.cache.backends.redis.RedisCache",
# A LOCATION parameter to specify the Redis server's address and port.
"LOCATION": "redis://127.0.0.1:6379",
}
}
Недостатками Redis являются его сложность и зависимость от внешних сервисов. Установка и настройка Redis может оказаться сложнее, чем с некоторыми другими системами кэширования. Ему требуется второй сервер и обслуживание. Использование Redis создает зависимость от внешнего сервиса. Если у Redis возникнут проблемы или он выйдет из строя, это может повлиять на возможности кэширования в приложении.
Выполнение кэширования в Django с использованием Redis
Итак, достаточно теории. В этом разделе мы изучим, как выполнять кэширование в приложении Django. Мы рассмотрим три формы кэширования:
кэширование представлений (views)
кэширование фрагментов шаблона (template fragments)
кэширование сайта
Но прежде чем мы подробно разберем каждую форму кэширования, давайте сначала должным образом настроим проект. Мы создадим, зарегистрируем и заполним модели, настроим URL-адреса приложения, создадим шаблон, установим и настроим панель отладки Django.
Внутри приложения cachedapplication
откройте файл models.py
и приведите его к следующему виду:
from django.db import models
class Programmer(models.Model):
name = models.CharField(max_length=50)
dob = models.CharField(max_length=20)
language = models.CharField(max_length=20)
quote = models.CharField(max_length=150)
def __str__(self):
return f"{self.name}"
Далее откройте файл admin.py
и вставьте в него этот код:
from django.contrib import admin
from .models import Programmer
admin.site.register(Programmer)
Этот фрагмент кода регистрирует модель Programmer
в панели администратора Django.
Прежде чем заполнять модели, давайте выполним несколько миграций. В терминале выполните команду:
$ python manage.py makemigrations
А также эту:
$ python manage.py migrate
В Django можно наполнять модели двумя способами: через терминал и через админскую панель. Для простоты мы будем использовать админскую панель. Поскольку эта панель предназначена только для суперпользователя, необходимо ее создать. Выполните следующую команду в терминале:
$ python manage.py createsuperuser
Эта команда предложит ввести данные суперпользователя: имя пользователя, e-mail и два пароля.
После успешного создания суперпользователя запустите локальный сервер и в браузере введите URL: http://127.0.0.1:8000/admin/
. На рисунке ниже показана страница, на которую вы попадете.
Чтобы войти в систему, введите учетные данные суперпользователя, а после входа заполните модели данными, как показано на рисунке ниже.
Внутри приложения создайте папку templates
, а в ней — файл list_all.html
. Пока оставьте HTML-файл пустым. Откройте файл views.py
и приведите его к следующему виду:
from django.shortcuts import render
from .models import Programmer
def home(request):
programmers = Programmer.objects.all()
context = {
'programmers': programmers
}
return render(request, 'list_all.html', context)
Теперь давайте зарегистрируем представление (view) home в файле urls.py
проекта. В папке cachedproject
откройте файл urls.py
и вставьте в него этот код:
from django.contrib import admin
from django.urls import path, include
from cachedapplication import views
urlpatterns = [
path('admin/', admin.site.urls),
# the home view from the cachedapplication
path('home/', views.home, name='home'),
]
Теперь откройте файл list_all.html
и вставьте в него следующий код:
Caching
Name
DOB
Language
Quote
{% for programmer in programmers %}
{{programmer.name}}
{{programmer.dob}}
{{programmer.language}}
{{programmer.quote}}
{% endfor %}
Установим Django debug toolbar. Это пакет Python, который помогает разработчикам отслеживать производительность Django-приложений. Он предоставляет подробную информацию о запросах к базе данных, HTTP-запросах, времени отрисовки шаблонов и т.д. Итак, в терминале введите команду:
pip install django-debug-toolbar
Чтобы настроить django-debug-toolbar
, откройте файл settings.py
и измените список INSTALLED_APPS
следующим образом:
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# new application added
'cachedapplication',
# the debug toolbar
'debug_toolbar',
]
Добавьте панель инструментов отладки в список MIDDLEWARE
:
MIDDLEWARE = [
# debug toolbar middleware
'debug_toolbar.middleware.DebugToolbarMiddleware',
]
Сделайте так, чтобы промежуточное ПО панели отладки было сразу после этого:
django.middleware.csrf.CsrfViewMiddleware
Оно также должно быть перед этим:
django.contrib.auth.middleware.AuthenticationMiddleware
Добавьте конфигурации кэша Redis:
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379/1",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
}
}
Также добавьте этот код в файл settings.py
:
INTERNAL_IPS = [
# ...
'127.0.0.1', # Add your development machine's IP address here
]
Наконец, настроим URL-адреса отладочной панели в файле urls.py. Сразу после импорта добавьте эту строку кода:
import debug_toolbar
Внутри списка urlpatterns
добавьте код:
urlpatterns = [
# debug toolbar URLS
path('__debug__/', include(debug_toolbar.urls)),
]
Сделав это, мы можем приступать к работе. Запускаем сервер и вставляем в браузер URL: http://127.0.0.1:8000/home/
. На скирншоте ниже показана страница, которую мы получим.
Каждый раз, когда вы запускаете приложение с использованием этого представления (view), оно будет выполнять SQL-запросы. В данном случае три запроса заняли 2,60 мс. Чтобы не делать каждый раз SQL-запросы к одним и тем же данным, реализуем кэширование представления.
Кэширование представлений
Как следует из названия, кэширование представлений предполагает кэширование результатов работы отдельных представлений (views) Django. В этом разделе мы реализуем кэширование представлений. Для этого внесем несколько изменений в файл view.py
. Откройте его и добавьте этот импорт:
from django.views.decorators.cache import cache_page
Прямо над представлением также добавим декоратор:
@cache_page(60*15)
(60*15)
— это аргумент, передаваемый в @cache_page. Он представляет собой таймаут кэширования в секундах. Home view будет кэшироваться в течение 15 минут.
Теперь посетим это же представление и обновим страницу. Мы получим результат, показанный на скриншоте ниже.
На изображении выше видно, что выполняется 0 SQL-запросов, поскольку данные извлекаются из кэша. Это позволяет снизить нагрузку на сервер при обслуживании пользователей кэшированным содержимым.
Кэширование фрагментов шаблона
Это кэширование определенных фрагментов шаблона в проекте. Если в шаблоне есть части с большими вычислениями, то этот вид кэширования оказывается очень полезным. Для реализации такого кэширования мы используем следующие теги: {% load cache %}
, {% cache %}
и {% endcache %}
. Тег {% cache %}
принимает два аргумента: таймаут кэширования и уникальный ключ кэширования для идентификации конкретного кэшируемого фрагмента.
Теперь попробуем запустить проект до реализации этой техники кэширования. На скриншоте ниже показано, что мы получим.
Общее время составляет 220,26 мс, а три SQL-запроса выполняются за 7,75 мс.
Теперь давайте реализуем технику кэширования. Мы кэшируем часть шаблона В верхней части файла мы загружаем кэш с помощью При повторном запуске проекта мы получим результат, показанный на скирншоте ниже. результаты кэширования: время 68.14 мс, 2 запроса в 2.13 мс На изображении видно, что после внедрения кэширования результаты улучшились. Предполагает кэширование всех страниц сайта. Для его реализации необходимо добавить в файл А также добавьте эти строки: Заключение Понимание кэширования в Django очень важно для веб-разработчиков, стремящихся создавать высокопроизводительные веб-приложения. В этой статье мы рассмотрели преимущества кэширования, настройку кэширования в Django и лучшие практики реализации. Вооружившись этими знаниями, веб-разработчики смогут с уверенностью внедрять кэширование в свои Django-проекты для оптимизации производительности. Еще больше актуальных знаний и инструментов можно освоить на онлайн-курсах OTUS под руководством экспертов в области IT. Каждый день в рамках курсов проходят открытые уроки, на которых можно узнать что-то новое и пообщаться с экспертами. Календарь уроков можно посмотреть по ссылке.templates/list_all.html
и измените его так:
{% load cache %}
{% for programmer in programmers %}
Name
DOB
Language
Quote
{% endfor %}
{{programmer.name}}
{{programmer.dob}}
{{programmer.language}}
{{programmer.quote}}
{% load cache %}
и заключаем div-часть в {% cache 500 programmers %}
и {% endcache %}
.Кэширование сайта
settings.py
следующие настройки middleware: MIDDLEWARE = [
# …
'django.middleware.cache.UpdateCacheMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.cache.FetchFromCacheMiddleware',
# …
]
CACHE_MIDDLEWARE_ALIAS = ' ' # cache alias
CACHE_MIDDLEWARE_SECONDS = 600 # number of seconds each page should be cached.
CACHE_MIDDLEWARE_KEY_PREFIX = '' # name of site if multiple sites are used