Advertisement
  1. Code
  2. Python

Как кэшировать используя Redis в приложениях Django

Scroll to top
Read Time: 7 min

Russian (Pусский) translation by Masha Kolesnikova (you can also view the original English article)

Одним из способов уменьшить нагрузку на сервер является кеширование данных. Это делается путем кэширования данных после их обработки и последующего получения из кэша при следующем запросе. В этом учебнике дается подробное обсуждение Redis, объясняя, как установить Redis и как кэшировать данные в приложениях Python.

Введение в Redis и кэширование

Кэширование относится к сохранению ответа сервера на самом клиенте, так что клиенту не нужно снова и снова запрашивать сервер для одного и того же ресурса. Ответ сервера должен содержать информацию о том, как сделать кеширование, чтобы клиент кэшировал ответ на определенный период времени или вообще никогда не кэшировал ответ сервера.

Кэш, с другой стороны, является аппаратным или программным компонентом, который используется для хранения данных, поэтому будущие запросы на одни и те же данные могут быть отправлены быстрее.

В наше время, когда пользователи ожидают результаты в течение секунды, целесообразно обслуживать запросы, читая данные из кеша, что в конечном счете будет быстрее, чем чтение из более медленного хранилища данных; таким образом, производительность системы зависит от количества запросов, которые могут быть получены из кеша.

Redis - хранилище данных в памяти с открытым исходным, используемое в качестве базы данных, кеша и брокера сообщений. Он работает, сохраняя данные в кеше и предоставляя их при следующем запросе, а не каждый раз запрашивая базу данных.

Установка Redis

Первый шаг - получить Redis и запустить локально на вашем компьютере. Самый простой способ установить Redis через диспетчер пакетов операционной системы:

1
sudo apt-get install redis-server

Вы также можете следовать инструкциям официального сайта Redis.

Загрузите и извлеките Redis 4.0.6 tar следующим образом:

1
$ wget https://download.redis.io/releases/redis-4.0.6.tar.gz 
2
$ tar xzf redis-4.0.6.tar.gz 
3
$ cd redis-4.0.6 $ make

Бинарные файлы, которые теперь компилируются, доступны в каталоге src. Запустите Redis с помощью:

1
$ src/redis-server

Вы можете взаимодействовать с Redis с помощью встроенного клиента:

1
$ src/redis-cli
2
redis set foo bar OK redis
3
get foo "bar"

Чтобы проверить, запущен ли сервер redis, выполните в терминале следующую команду:

1
$ sudo redis-server
2
* Ready to accept connections

Пример API Django

Давайте создадим наш проект Django. Наш проект сможет кэшировать все продукты в магазине, что позволяет легко и быстро извлекать данные при последующих запросах.

Чтобы использовать Redis в нашем приложении, нам нужно сделать следующее:

  1. Проверить, существуют ли результаты для текущего запроса в кеше.
  2. Если результаты есть в кеше, извлеките их.
  3. Если результатов не существует, извлеките их, сохраните их в кеше и затем пересылайте их запрашивающему объекту.

Требования

  • Django
  • django-redis
  • Redis
  • loadtest

Создаем свой проект

Прежде чем приступить к работе, создайте каталог и установите виртуальное окружение. Виртуальное окружение позволит вам устанавливать версии библиотек, требуемые вашим приложением.

1
mkdir myprojects
2
3
cd myprojects

Затем активируйте виртуальное окружение и установите требования к проекту.

1
 source venv/bin/activate
2
 
3
 pip install django==1.9
4
 
5
 pip install django-redis
6
 
7
 pip install djangorestframework

Создание проекта Django

1
django-admin startproject django_cache

Создайте новое приложение под названием store, которое будет обрабатывать управление продуктами в нашем магазине.

1
cd django_cache
2
3
python manage.py startapp store

Добавьте приложение store и rest_framework в список установленных приложений в файле settings.py.

1
# settings.py

2
INSTALLED_APPS = [
3
    'django.contrib.admin',
4
    'django.contrib.auth',
5
    'django.contrib.contenttypes',
6
    'django.contrib.sessions',
7
    'django.contrib.messages',
8
    'django.contrib.staticfiles',
9
    'store', # add here

10
    'rest_framework', # add here too

11
]

Создание моделей

В store/models.py мы начинаем с создания модели продукта для хранения сведений о продукте следующим образом:

1
from __future__ import unicode_literals
2
from django.db import models
3
import datetime
4
5
# Create your models here.

6
7
8
class Product(models.Model):
9
10
    name = models.CharField(max_length=255)
11
    description = models.TextField(null=True, blank=True)
12
    price = models.IntegerField(null=True, blank=True)
13
    date_created = models.DateTimeField(auto_now_add=True, blank=True)
14
    date_modified = models.DateTimeField(auto_now=True, blank=True)
15
16
    def __unicode__(self):
17
        return self.name
18
19
    def to_json(self):
20
        return {
21
            'id': self.id,
22
            'name': self.name,
23
            'desc': self.description,
24
            'price': self.price,
25
            'date_created': self.date_created,
26
            'date_modified': self.date_modified
27
        }

Миграции

Создайте первоначальную миграцию для нашей модели продуктов и выполните синхронизацию базы данных.

1
python manage.py makemigration store
2
3
python manage.py migrate

Создание суперпользователя

Создайте суперпользователя, войдите в панель администратора и заполните базу данных примерами данных, которые мы будем использовать для проведения наших тестов.

1
python manage.py createsuperuser

Настройка Redis в приложениях Python

Чтобы использовать Redis с приложением Django, нам нужно настроить Redis для хранения данных кэша приложения. Добавьте следующее в файл settings.py:

1
CACHES = {
2
    'default': {
3
        'BACKEND': 'django_redis.cache.RedisCache',
4
        'LOCATION': 'redis://127.0.0.1:6379/',
5
        'OPTIONS': {
6
            'CLIENT_CLASS': 'django_redis.client.DefaultClient',
7
        }
8
    }
9
}

Затем мы создадим ендпоинт, который достает все продукты из нашей базы данных. Сначала мы проверим производительность приложения с точки зрения того, сколько времени потребуется для извлечения данных из базы данных без кэширования. Затем мы реализуем другой ендпоинт, который извлекает данные из кеша и сравним производительность.

В файле store/views.py добавьте следующий код, который извлекает все продукты, существующие в базе данных.

1
from django.shortcuts import render
2
from rest_framework.decorators import api_view
3
from rest_framework.response import Response
4
from rest_framework import status
5
6
# Create your views here.

7
8
9
10
@api_view(['GET'])
11
def view_books(request):
12
13
    products = Product.objects.all()
14
    results = [product.to_json() for product in products]
15
    return Response(results, status=status.HTTP_201_CREATED)

Настройка URL-адресов

Создайте файл store/urls.py и добавьте в него следующий код.

1
# store/urls.py

2
from django.conf.urls import url
3
from .views import view_books
4
5
6
urlpatterns = [
7
    url(r'^$', view_books),
8
]

Нам также необходимо импортировать URL-адреса из приложения users в основной файл django_cache/urls.py.

1
# django_cache/urls.py

2
3
from django.conf.urls import url, include
4
from django.contrib import admin
5
6
urlpatterns = [
7
    url(r'^admin/', admin.site.urls),
8
    url(r'^store/', include('store.urls'))
9
]

Давайте проведем тест и посмотрим, как у нас все получилось. Мы будем использовать loadtest. Если вы не знакомы с loadtest, то это инструмент для тестирования производительности.

Установка loadtest как root довольна простая:

1
sudo npm install -g loadtest
1
$ loadtest -n 100 -k  http://localhost:8000/store/
2
3
# result

4
INFO Requests per second: 55
5

Как видно из вышеизложенного, 55 запросов обрабатываются за секунду.

Давайте создадим еще один ендпоинт для извлечения данных после кэширования с помощью Redis. Измените файл users/views.py, чтобы в нем был следующий код:

1
from rest_framework.decorators import api_view
2
from rest_framework import status
3
from rest_framework.response import Response
4
from django.core.cache import cache
5
from django.conf import settings
6
from django.core.cache.backends.base import DEFAULT_TIMEOUT
7
8
CACHE_TTL = getattr(settings, 'CACHE_TTL', DEFAULT_TIMEOUT)
9
from .models import Product
10
11
12
# Create your views here.

13
14
15
@api_view(['GET'])
16
def view_books(request):
17
    # rest of the code

18
19
20
@api_view(['GET'])
21
def view_cached_books(request):
22
    if 'product' in cache:
23
        # get results from cache

24
        products = cache.get('product')
25
        return Response(products, status=status.HTTP_201_CREATED)
26
27
    else:
28
        products = Product.objects.all()
29
        results = [product.to_json() for product in products]
30
        # store data in cache

31
        cache.set(product, results, timeout=CACHE_TTL)
32
        return Response(results, status=status.HTTP_201_CREATED)
33

В приведенном выше коде будет проверяться, присутствует ли нужный продукт в кеше, и если он найден, соответствующие данные будут возвращены в браузер. В случае отсутствия данных в кеше мы сначала извлекаем данные из базы данных, сохраняем их в кеше и затем возвращаем в браузер.

Обновите store/urls.py следующим образом.

1
from django.conf.urls import url
2
from .views import view_books, view_cached_books
3
4
5
urlpatterns = [
6
    url(r'^$', view_books),
7
    url(r'^cache/', view_cached_books),
8
9
]

Давайте проведем тесты.

1
$ loadtest -n 100 -k  http://localhost:8000/store/cache/
2
3
# results

4
INFO Requests per second: 233
5
6

В первый раз, когда вы запросите ендпоинт localhost:8000/store/cache, приложение будет запрашивать данные из базы данных и возвращать их, но последующие вызовы на этот URL будут обходить базу данных и делать запрос в кеш, поскольку данные уже доступны будут доступны в нем ,

Заключение

В этом уроке мы использовали Redis, чтобы придать иллюзию скорости нашему приложению. Мы использовали Redis для хранения результатов запросов, а затем при последующих запросах возвращали эти результаты из кеша.

Существуют и другие инструменты кеширования, такие как Memcached, похожие на Redis. Однако Redis более популярен, чем Memcached, потому что для настройки и работы в приложениях требуется всего пара минут. Redis имеет более сложные механизмы, поскольку он был описан как «хранилище структур данных», что делает его более мощным и гибким. Redis также имеет большее преимущество, потому что вы можете хранить данные в любой форме.

Надеюсь, этот учебник показал вам, как легко добавить кэш-слой в ваше приложение, и, следовательно, повысить его производительность. Кэширование должно быть тем, что нужно учитывать, когда вам нужно сократить время загрузки и затраты на сервер.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.